• 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
  • 相关阅读:
    java配置环境变量
    What Beautiful HTML Code Looks Like jessica
    Hive 快速搭建
    Apq本地工具集
    SQL:查询购买了所有指定商品的人
    NodeJs
    留存
    markdown
    微信公众号开发
    viper
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/5064827.html
Copyright © 2020-2023  润新知