Halloween Costumes(区间DP)

题目链接:https://cn.vjudge.net/contest/318859#problem/B
题意:一个人要去参加派对,不同的派对要穿不同的衣服。现在给出每个派对的要穿的衣服,已知这个人可以多穿衣服或者脱去一定的衣服,但每一件衣服脱去了之后就不能再穿了。求这个人需要穿的最少的衣服。
思路:又是一道让我自闭的区间DP“入门题”,状态方程不是很好想,需要仔细去理解,现在对我来说难点就是怎样找到最小子结构,还是需要多多练习刷题才行。
设dp[i][j]为一个区间i到j需要的最少衣服数,则这个人到第j个派对的时候,有两种决策:
①不用管前面的情况,当前可以直接穿上第j个派对需要的衣服,则此时的状态转移方程为dp[i][j]=min(dp[i][j], dp[i][j-1]+1)
②与第一种决策相反,脱去一定的衣服,如果有在[i,j-1]之间有c[k]=c[j],则可以认为把衣服脱到k派对时的衣服,再去参加j派对,则转移方程为
dp[i][j]=min(dp[i][j], dp[i][k] + dp[k+1][j-1]

#include<iostream>
#include<cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
int c[105];
int dp[105][105];
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;
    cin >> t;
    for(int kase = 1; kase <= t; ++kase)
    {
        int n;
        cin >> n;
        for(int i = 1; i <= n; ++i)
            cin >> c[i];    
        for(int i = 1; i <= n; ++i)
            for(int j = i; j <= n; ++j)
                dp[i][j] = j-i+1;
        cout << "Case " << kase << ": ";
        for(int len = 1; len <= n; ++len){
            for(int i = 1; i+len <= n; ++i){
                dp[i][i+len] = dp[i][i+len-1] + 1;
                for(int k = i; k <= i+len-1; ++k){
                    if(c[i+len] == c[k]) 
                        dp[i][i+len] = min(dp[i][i+len], dp[i][i+len-1]);
                } 
            }
        }
        cout << dp[1][n] << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值