首页 > 代码库 > 动规之区间动规小结

动规之区间动规小结

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

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

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


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;
}