[CQOI2007]涂色PAINT

[CQOI2007]涂色PAINT

https://ac.nowcoder.com/acm/problem/19909

题意:
给你目标字符串的状态,现可以将连续一段字符串染色,求最小的染色次数
题解:
我们定义dp[i][j]是区间i到区间j最小的涂色次数
区间dp的核心思想实际上是由一个个小区间进行合并成为大区间,所以我们在dp的时候应该从长度最短的下手,也就是长度为1的。
1.长度为1的区间,涂色次数为1.
2.长度区间为2的值:
它可以由两个长度为1的区间和并,但是这个题目比较特殊的一点就是,你图一次可以连续涂一个区间,所以如果s[i]==s[j]那么这个区间只需要涂一次,如果不同,那么就是两个区间次数的相加了。
3.长度为n的值:
仿照区间长度为2的时候,我们可以枚举区间中的某个分割点来进行递推,这就跟Floyd的核心思想差不多了(Floyd其实本质就是动态规划)。
但是这个题的要求,涂一次可以涂一个连续的区间,所以说,如果s[i]==s[j],那么我们就可以直接转移左区间或者右区间,因为涂一次可以图一个连续的区间。
综上所述:
转移方程
1. i==j时:dp[i][j]=1;
2. 当i!=j且s[i]==s[j]时:dp[i][j]=min(dp[i][j-1],dp[i+1][j])
3. 当i!=j且s[i]!=s[j]时:我们就需要枚举断电k ,dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j])

代码:

/*Keep on going Never give up*/
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stdlib.h>
#include <queue>
#include <string>
const int maxn = 100;
const int MaxN = 0x3f3f3f3f;
const int MinN = 0xc0c0c00c;
typedef long long ll;
const ll mod = 1e9+7;
using namespace std;
int dp[maxn][maxn];
char s[maxn];
int main(){
    scanf("%s",s+1);
    memset(dp,MaxN,sizeof dp);
    for(int i=0;i<=strlen(s+1);i++) dp[i][i]=1;
    for(int len=1;len<=strlen(s+1);len++){
        for(int i=1,j=i+len;j<=strlen(s+1);i++,j++){
            if(s[i]==s[j]) dp[i][j]=min(dp[i+1][j],dp[i][j-1]);
            else{
                for(int k=i;k<j;k++){
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
                }
            }
        }
    }
    cout<<dp[1][strlen(s+1)]<<endl;
    return 0;
}
题解 文章被收录于专栏

主要写一些题目的题解

全部评论

相关推荐

不愿透露姓名的神秘牛友
06-10 15:24
高考前一晚在OPPO手机上设置了早上5:30的闹钟,然而闹钟并未按时响起。直到妈妈做好早餐后,在6:27打开手机才发现闹钟未触发,“气得早上饭都没吃”。资本家你赢了
永不遗忘:我来解释一下 :Oppo 手机晚上两点会自动进行系统更新,这个系统更新会重置掉所有设置好的闹钟,而且他也不会告诉你,而且只有 Oppo 会这样,华为苹果小米三星都不会
点赞 评论 收藏
分享
代码飞升:别用口语,后端就写后端,前端就写前端,最后别光后悔
点赞 评论 收藏
分享
04-29 22:35
门头沟学院 Java
牛友说改了名字能收到offer:旧图新发查看图片
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务