动规之区间动规小结

来源:互联网 发布:java http post json 编辑:程序博客网 时间:2024/04/28 22:46

区间动规主要有两种方法:

一、是先想出递归式,然后将之转化为滚动数组。

二、或者从小区间贪到大区间。


POJ  1159  点击打开链接

AC代码如下:

#include<iostream>#include<cstring>#include<algorithm>using namespace std;char a[5005];short dp[5005][5005];int min(int a,int b){    return a<b?a:b;}int main(){    int n;    int ans;    int i,j;    while(cin>>n)    {        memset(dp,0,sizeof dp);        cin>>a+1;        //cout<<a+1;        for(i=1;i<=n;i++)        {            dp[i][i]=0;        }        int len;        for(len=2;len<=n;len++)        {            for(i=1;i<=n-len+1;i++)            {                j=i+len-1;                if(a[i]==a[j])                    dp[i][j]=dp[i+1][j-1];                else                {                    dp[i][j]=min(dp[i][j-1],dp[i+1][j])+1;                }            }        }        cout<<dp[1][n]<<endl;    }    return 0;}



POJ  2955   点击打开链接


AC代码如下:

#include<iostream>#include<cstring>#include<algorithm>using namespace std;int dp[105][105];char str[1005];int main(){    int i,j,o,t;    while(cin>>str,str[0]!='e')    {        int l=strlen (str);        for(i=0;i<l;i++)            for(j=0;j<l;j++)            dp[i][j]=0;        for(o=2;o<=l;o++)        {            for(i=0;i<l-o+1;i++)            {                j=i+o-1;                for(t=i;t<j;t++)                {                    dp[i][j]=max(dp[i][j],dp[i][t]+dp[t+1][j]);                    if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))                        dp[i][j]=max(dp[i][j],dp[i+1][j-1]+2);                }            }        }        cout<<dp[0][l-1]<<endl;    }    return 0;}



POJ  1141  点击打开链接



AC代码如下:

#include<iostream>#include<cstring>using namespace std;int dp[205][205];int dd[205][205];char str[1005];int l,minn;int i,j,t,x;void PRINTF(int s,int e){    if(s>e)    return ;    else    {        if(s==e)        {            if(str[s]=='('||str[s]==')')                cout<<"()";            else cout<<"[]";        }        else{                if(dd[s][e]>=0)                {                    PRINTF(s,dd[s][e]);                    PRINTF(dd[s][e]+1,e);                }                else                {                    cout<<str[s];                    PRINTF(s+1,e-1);                    cout<<str[e];                }        }    }}void DP(){    for(i=0;i<l;i++)        dp[i][i]=1;    memset(dd,0,sizeof dd);    dd[0][0]=-1;    for(x=2;x<=l;x++)    {        for(i=0;i<l-x+1;i++)        {            j=i+x-1;            dd[i][j]=i;            minn=dp[i][i]+dp[i+1][j];            for(t=i+1;t<j;t++)            {                if(dp[i][t]+dp[t+1][j]<minn)                {                    minn=dp[i][t]+dp[t+1][j];                    dd[i][j]=t;                }            }            dp[i][j]=minn;            if((str[i]=='('&&str[j]==')')||(str[i]=='['&&str[j]==']'))                if(minn>dp[i+1][j-1])                {                    dp[i][j]=dp[i+1][j-1];                    dd[i][j]=-1;                }        }    }    //cout<<dp[0][l-1]<<endl;}int main(){    cin>>str;    l=strlen (str);    DP();    PRINTF(0,l-1);    cout<<endl;    return 0;}


0 0