zoukankan      html  css  js  c++  java
  • 区间dp F

    F - Halloween Costumes 区间dp

    题目大意:

    一个人去参加晚会,不同的晚会要穿不同的衣服,他一次性可以穿几件衣服,但是衣服一旦脱下来就变成旧衣服了,他就不会再穿了,问他参加n个晚会,至少要穿几件衣服。

    题解:

    这个题目可以转化成涂色问题,每一次可以连续涂若干长度的颜色,问最少涂多少次颜色,使得这个序列变成我们想要的颜色。

    (dp[i][j]) 表示从 (i)(j) 最少涂 (dp[i][j]) 次颜色。

    这个转移方程怎么写呢?可以以左端点作为判断的依据。

    对于一个区间 ([l,r]) 假设最先从左端点开始涂颜色,如果这个区间还有和左端点的颜色是一样的,那么则说明这个点就是最开始已经涂过了,所以以这个点为分节符,从这个点的两边转移过来。

    (dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]))

    #include <bits/stdc++.h>
    #define id first
    #define val second
    #define inf 0x3f3f3f3f
    #define inf64 0x3f3f3f3f3f3f3f3f
    using namespace std;
    const int maxn=110;
    typedef long long ll;
    int dp[maxn][maxn],a[maxn];
    
    int main(){
        int t;
        scanf("%d",&t);
        for(int cas=1;cas<=t;cas++){
            int n;
            scanf("%d",&n);
            memset(dp,0,sizeof(dp));
            for(int i=1;i<=n;i++) scanf("%d",&a[i]),dp[i][i]=1;
            for(int len=2;len<=n;len++){
                for(int i=1;i+len-1<=n;i++){
                    int j=i+len-1;
                    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][j],dp[i][k-1]+dp[k+1][j]);
                    }
                }
            }
            printf("Case %d: %d
    ",cas,dp[1][n]);
        }
        return 0;
    }
    
  • 相关阅读:
    jekins接通gitee的webhook做自动部署 vue、react、java、springBoot
    vue可复用性 & 组合
    vite使用短链接
    Ubuntu12.04(X86_64)上安装Mesa8.0.4
    回调函数
    c#隐式转换
    OpenGL ES2 的OffScreen实现
    Catch exception from other thread
    C# []、List、Array、ArrayList 区别及应用
    redhat update
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/13262916.html
Copyright © 2011-2022 走看看