LightOJ 1422 Halloween Costumes 区间dp

题意:给你n天需要穿的衣服的样式,每次可以套着穿衣服,脱掉的衣服就不能再穿了,问至少要带多少条衣服才能参加所有宴会

思路:dp[i][j]代表i-j天最少要带的衣服

从后向前dp 区间从大到小

更新dp[i][j]时有两种情况 考虑第i天穿的衣服

1:第i天穿的衣服在之后不再穿了 那么 dp[i][j]=dp[i+1][j]+1;

2:第i天穿的衣服与i+1到j的某一天共用,那么dp[i][j]=min(dp[i][j],dp[i+1][k-1],dp[k][j]),前提是第i天和第k天需要的礼服样式相同

代码如下(注意dp的初始化和方向)

http://lightoj.com/volume_showproblem.php?problem=1422

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long LL;
int dp[105][105],a[105];
int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
       int n;
       scanf("%d",&n);
       for(int i=1;i<=n;++i)
        scanf("%d",&a[i]);
       memset(dp,0,sizeof(dp));
       for(int i=1;i<=n;++i)
        for(int j=i;j<=n;++j)
           dp[i][j]=j-i+1;
       for(int i=n-1;i>=1;--i)
       {
           for(int j=i+1;j<=n;++j)
           {
               dp[i][j]=dp[i+1][j]+1;
               for(int k=i;k<=j;++k)
                if(a[i]==a[k])
                dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j]);
           }
       }
       printf("Case %d: %d
",++cas,dp[1][n]);
    }
    return 0;
}
View Code

 普通的区间dp写法,上面那种其实也行,主要是我喜欢普通的区间dp写法

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long LL;
int dp[105][105],a[105];
int main()
{
    int T,cas=0;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; ++i)
            scanf("%d",&a[i]);
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=n; ++i)
            for(int j=i; j<=n; ++j)
                dp[i][j]=j-i+1;
        for(int k=1; k<n; ++k)
        {
            for(int i=1; i+k<=n; ++i)
            {
                dp[i][i+k]=dp[i+1][i+k]+1;
                for(int j=i+1; j<=i+k; ++j)
                    if(a[i]==a[j])
                        dp[i][i+k]=min(dp[i][i+k],dp[i+1][j-1]+dp[j][i+k]);
            }
        }
        printf("Case %d: %d
",++cas,dp[1][n]);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/shuguangzw/p/5064827.html