UVALIVE 4857 Halloween Costumes (区间DP)

题目链接:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=15381


题意:

有n个party,m种衣服,告诉你了这n个party需要穿的衣服,每次衣服脱了就不能再穿了。

问他最少需要多少套衣服。


分析:

我们想要衣服最少那么肯定要换的次数最少,就是使尽量多的场次穿一样的衣服,那么就类似这个问题了,求一个区间内有多少个括号匹配。

我们这个问题就是求区间内有多少种衣服相同

dp[i][j]表示i到j有多少种衣服相同

最后的衣服数等于n-dp[1][n].

如果第i个party 与第j个party所穿的衣服一样的话,那么dp[i][j]=max{dp[i][k]+dp[k+1][j]}+1;

否则dp[i][j]=max{dp[i][k]+dp[k+!][j]}   (i<=k<j)


代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 110;

int a[maxn];
int dp[maxn][maxn];

int main()
{
    int n,m,t,cas=1;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        memset(dp,0,sizeof(dp));
        for(int len=2;len<=n;len++){
            for(int i=1;i+len<=n+1;i++){
                int j = i+len-1;
                for(int k=i;k<j;k++){
                    if(a[i]==a[j])
                        dp[i][j]=max(dp[i][k]+dp[k+1][j]+1,dp[i][j]);
                    else
                        dp[i][j]=max(dp[i][k]+dp[k+1][j],dp[i][j]);
                }
            }
        }
        printf("Case %d: %d\n",cas++,n-dp[1][n]);
    }
    return 0;
}



你可能感兴趣的:(UVALIVE 4857 Halloween Costumes (区间DP))