涂色计划P4170
题目描述
假设你有一条长度为 555 的木版,初始时没有涂过任何颜色。你希望把它的 555 个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为 555 的字符串表示这个目标:
RGBGR
。每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成
RRRRR
,第二次涂成RGGGR
,第三次涂成RGBGR
,达到目标。用尽量少的涂色次数达到目标。
输入格式
输入仅一行,包含一个长度为 nnn 的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。
输出格式
仅一行,包含一个数,即最少的涂色次数。
输入输出样例
输入 #1AAAAA输出 #11输入 #2RGBGR输出 #23说明/提示
40%40\%40% 的数据满足 1≤n≤101\le n\le 10 1≤n≤10。
100%100\%100% 的数据满足
#include<bits/stdc++.h> using namespace std; const int N= 105,INF=0x3f3f3f3f; int f[N][N],n; char s[N]; int dfs(int l,int r) { if(l==r) return f[l][r]=1; if(f[l][r]!=-1) return f[l][r]; f[l][r]=INF; if(s[l]==s[r]) for(int i=l;i<=r-1;i++) { f[l][r]=min(f[l][r],dfs(l,i)+dfs(i+1,r)-1); } else { for(int i=l;i<=r-1;i++) { f[l][r]=min(f[l][r],dfs(l,i)+dfs(i+1,r)); } } return f[l][r]; } int main() { while(scanf("%s",s+1)!=EOF) { n=strlen(s+1); memset(f,-1,sizeof(f)); dfs(1,n); printf("%d\n",f[1][n]); } return 0; }
#include<bits/stdc++.h> using namespace std; const int N= 105,INF=0x3f3f3f3f; int f[N][N],n; char s[N]; int main() { while(scanf("%s",s+1)!=EOF) { n=strlen(s+1); memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;i++) f[i][i]=1; for(int len=1;len<=n;len++) { for(int l=1;l+len-1<=n;l++) { int r=l+len-1; for(int k=l;k<=r-1;k++) if(s[l]==s[r]) f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]-1); else f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]); } } printf("%d\n",f[1][n]); } return 0; }