LightOj 1422(区间dp)

思路

先把所有的答案dp[i][j]初始化为最差的解(因为后面要取min),也就是每件衣服都是新买的衣服(最大的花费)。

对于 d p [ i ] [ j ] dp[i][j] dp[i][j] 如果是由之前买新衣服来的,则 d p [ i ] [ j ] = d p [ i ] [ j − 1 ] + 1 dp[i][j] = dp[i][j - 1] + 1 dp[i][j]=dp[i][j1]+1
然后再考虑在这个区间范围,是否有一天要穿相同的衣服。
对于 d p [ i ] [ j ] dp[i][j] dp[i][j]枚举间断点k,如果衣服的种类 k i n d [ k ] = = k i n d [ j ] kind[k] == kind[j] kind[k]==kind[j],即如果第 k 天衣服和第 i 天的衣服是一样的,那就比较第 j 天穿一件新的与不穿一件新的衣服。
穿一件新的衣服在进入分割的时候就已经算了,所以我们直接看不穿一件新衣服,取小即可。 d p [ i ] [ j ] = d p [ i ] [ k ] + d p [ k + 1 ] [ j − 1 ] dp[i][j] = dp[i][k] + dp[k + 1][j - 1] dp[i][j]=dp[i][k]+dp[k+1][j1]

代码

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn = 1e2 + 10;
int dp[maxn][maxn];
int a[maxn];
int main()
{
    int n, T;
    scanf("%d", &T);
    for(int t = 1; t <= T; t++)
    {
        memset(dp, 0, sizeof(dp));
        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] = j - i + 1;//初始化最大值,假设我每一件都穿新衣服

        for(int len = 1; len <= n; len++)
        {
            for(int i = 1; i + len <= n; i++)
            {
                int j = i + len;
                dp[i][j] = dp[i][j - 1] + 1;
                for(int k = i; k < j; k++)
                    if(a[k] == a[j])
                        dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j - 1]);
            }
        }
        printf("Case %d: %d\n", t, dp[1][n]);
    }
    return 0;
}

参考来源

博客
https://blog.csdn.net/qq_34374664/article/details/54867113

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值