zoukankan      html  css  js  c++  java
  • Light OJ 1422 Halloween Costumes

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1422

    很简单的区间DP的入门题。一开始这题想了很久就是想不出来。直到做了后面几道区间DP回过来终于想明白了。

    区间DP可以使用记忆化搜索和直接DP的方法写。

    这题的状态转移方程:

    dp[i][j]=min(1+dp[i+1][j],dp[i+1][k-1]+dp[k][j])   (    a[i]==a[k]   i<k<=j   )

    注意初始化。

    /*
     * Light OJ 1422 - Halloween Costumes
     * http://lightoj.com/volume_showproblem.php?problem=1422
     *  区间DP的思想。
     *  比如要求解i到j,dp[i][j].
     *  就是考虑i的衣服,一种是i的衣服只有在i使用,那么就是dp[i+1][j]+1件
     *  然后再i+1~j中枚举k,如果a[i]==a[k].那么dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j])
     *  注意因为i的衣服是可以使用多次的,所以不需要加1,是dp[k][j]
     *  思想很妙
     */
    
    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #include <string.h>
    using namespace std;
    const int MAXN=110;
    int a[MAXN];
    int dp[MAXN][MAXN];
    
    int main()
    {
        int T;
        int n;
        scanf("%d",&T);
        int iCase=0;
        while(T--)
        {
            iCase++;
            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--)//注意DP的顺序
                for(int j=i+1;j<=n;j++)
                {
                    dp[i][j]=dp[i+1][j]+1;//这个表示第i个的衣服在后面没有利用了
                    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\n",iCase,dp[1][n]);
        }
        return 0;
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    node之body-parser的使用
    node解决跨域问题
    node之post提交上传
    HDU 6397(容斥原理)
    HDU 3374(最小最大表示法+KMP)
    HDU 6396(优先队列+思维)
    HDU 6395(矩阵快速幂)
    HDU 6370(并查集)
    HDU 6356(线段树)
    HDU 6354(计算几何)
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3051392.html
Copyright © 2011-2022 走看看