• light oj 1422


    题意:告诉有n场晚会中需要穿的衣服,衣服是可以套在其他衣服外面的,
    也就是说如果顺序为 1 2 1,那么可以将2套在1外面,第三场晚会需要穿1的时候把2脱掉即可,这样就只需要穿两次衣服。
    题目是再告诉了顺序之后需要求出在某种序列下最少需要穿多少次衣服。

    思路:区间DP,对于区间【i,j】,如果a[i]在[i+1,j]中未出现,dp[i][j] = dp[i+1][j]+1,否则a[i]应考虑是否被重复利用,若重复利用那么并不需要再一次穿上a[i],所以dp[i][j] = min(dp[i][j],dp[i][k-1],dp[k+1][j])。

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <iostream>
    #include <queue>
    #include <algorithm>
    #define MAXSIZE 1005
    #define LL long long
    #define INF 0x3f3f3f
    #define mod 10056
    
    using namespace std;
    
    int dp[MAXSIZE][MAXSIZE],a[MAXSIZE];
    
    int Solve(int n)
    {
        for(int i=0;i<MAXSIZE;i++)
        {
            for(int j=i;j<MAXSIZE;j++)
            {
                dp[i][j] = j-i+1;
            }
        }
    
        for(int i=n;i>=1;i--)
        {
            for(int j=i+1;j<=n;j++)
            {
                dp[i][j] = dp[i+1][j] + 1;
                for(int k=i+1;k<=j;k++)
                {
                    if(a[k] == a[i])
                    {
                        dp[i][j] = min(dp[i][k-1]+dp[k+1][j],dp[i][j]);
                    }
                }
            }
        }
        return dp[1][n];
    }
    
    int main()
    {
        int T,n,cns=1;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);
            int ans = Solve(n);
            printf("Case %d: %d
    ",cns++,ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    主键索引和非主键索引解析
    DNS劫持、污染的原理
    B-树,B+树与B*树的优缺点比较
    CollectionUtils工具类
    maven换源
    哪些字段可以加索引?
    callable和runnable的区别
    类加载器实例化时的顺序
    28BYJ-48步进电机
    《计算机网络》读书笔记之应用层
  • 原文地址:https://www.cnblogs.com/alan-W/p/7642721.html
Copyright © 2020-2023  润新知