把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

Alien 的粉刷

题目描述
Alien 们也要造房子,刷一面墙的时候,Alien 喜欢将这面墙从左往右分成很多个部分,每个部分用一种颜色来粉刷,为了便于表示,用’A’到’Z’表示 26 种颜色。粉刷的规则是每次用一种颜色粉刷连续一段任意长度的部分,后刷的覆盖先刷的。 现在 Alien 们给出了一个墙壁的粉刷序列,为了节省人力,需要你帮他们用最少的次数粉刷完毕。
输入
第 1 行一个整数 N。
第 2 行是一个长度为 N 的字符串 S,表示粉刷序列(由大写英文字母组成)。
输出
输出共一行一个数 Ret,表示最少次数。
样例输入 Copy
5
RGBGR
样例输出 Copy
3
提示
【样例解释】第一次 RRRRR,第二次 RGGGR,第三次 RGBGR。
【数据规模】
对于 30%的数据: N≤10;对于 100%的数据:N≤50;

分析题目思路是区间DP。那么就简单了。
DP首先要初始化,此处已知的是当长度为1时,染色次数就、肯定是1
然后是状态转移方程的分析。假如一段区间是首尾颜色相同,则新增长度不产生影响f[i][j]可以直接从f[i][j-1]或f[i+1][j]转移过来。
如若不同就将大区间转换为小区间,化未知为已知。这与FLOYD找中间点的思想相同。方程为f[i][j]=min(f[i][j],f[i][k]+f[k+1][j])
注意这是区间DP要从小区间即长度短的向大区间更新而非按点的顺序从左到右更新

#include "bits/stdc++.h"
using namespace std;
int n;
string s="";
int dp[55][55];
int main()
{
scanf("%d\n",&n);
char c=getchar();s+=c;int l=1;
for(int i=1;i<n;i++){c=getchar();if(c!=s[l-1])s+=c,l++;	}
memset(dp,0x7f,sizeof(dp));
for(int i=0;i<l;i++)dp[i][i]=1;
for(int k=1;k<l;k++)
 for(int j=0,i=j+k;i<l;j++,i++)
 {
 dp[j][i]=dp[j][i-1]+1;
 if(s[i]==s[j])dp[j][i]--;
 else{
 for(int k=j;k<i;k++)
 dp[j][i]=min(dp[j][i],dp[j][k]+dp[k+1][i]);	
 }	
 
 }
  
  printf("%d",dp[0][l-1]);
}
posted @ 2021-07-05 15:47  BLUE_ROBIN  阅读(69)  评论(0)    收藏  举报
Live2D
浏览器标题切换
浏览器标题切换end