• LightOJ


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

    题目大意:有n个地方,每个地方要穿一种衣服,衣服可以嵌套穿,一旦脱下的衣服不能再穿,除非穿同样的一件新的,问在满足题目要求的穿衣顺序下最少需要准备几件衣服

    Sample Input

    2

    4

    1 2 1 2

    7

    1 2 1 1 3 2 1

    Sample Output

    Case 1: 3

    Case 2: 4

    emmmm,区间DP。。。。别问我为什么QAQ,定义状态为$dp[i][j]$表示区间$[i,j]$最少所需要的衣服,很容易知道我们当转移的时候如果两边所需要的衣服一样,那么状态就变成了:$dp[l][r]=dp[l][r-1]$也就是说我可以直接将$l$所需要的衣服穿在最里面,这样就可以省下一件了。接下来就是比较常见的区间转移过程了:$dp[l][r]=min(dp[l][r],dp[l][mid]+dp[mid+1][r])$

    以下是AC代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    const int mac=150;
    const int inf=1e8+10;
    
    int a[mac],dp[mac][mac];
    
    int main()
    {
        int t,Case=0,n;
        scanf ("%d",&t);
        while (t--){
            scanf ("%d",&n);
            for (int i=1; i<=n; i++)
                scanf ("%d",&a[i]);
            for (int i=1; i<=n; i++)
                for (int j=i; j<=n; j++)
                    dp[i][j]=inf;
            for (int i=1; i<=n; i++) dp[i][i]=1;
            for (int len=2; len<=n; len++)
                for (int l=1; l+len-1<=n; l++){
                    int r=l+len-1;
                    if (a[l]==a[r]) dp[l][r]=dp[l][r-1];
                    for (int mid=l; mid<=r; mid++)
                        dp[l][r]=min(dp[l][r],dp[l][mid]+dp[mid+1][r]);
                }
            printf("Case %d: %d
    ",++Case,dp[1][n]);
        }
    
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    组合数取模 Lucas定理
    关于上下界的二分查找
    POJ 1091 跳蚤
    Eular 函数模板
    POJ 数学(3)
    SRM 567 div2
    SRM 570 div2
    最大最小搜索,alpha beta 剪枝
    JavaScript:prototype属性使用方法
    ArcGIS网络分析之Silverlight客户端服务区分析(五)
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13264291.html
Copyright © 2020-2023  润新知