题意
现在给你一块长度为5的木板,给他涂色,一共有五种颜色,每一次涂色是可以选择涂连续的一段,即我可以涂一格,也可以涂两个连在一起的,也可以涂三格连续在一起的,现在给出目标状态,问要涂的最少次数。解析
首先我们先分析一下样例是什么意思,样例1:AAAAA,很明显,就是选择颜色A,然后涂一次从最左边涂到最右边这就是最少的次数,然后是样例二,RGBGR,三次是怎么涂的也不难理解,首先是是涂一次全部涂成R从最左边涂到最右边,即RRRRR,然后选择颜色G从第二个涂到第四个,即RGGGR,最后再涂中间这个,涂成B,就有了RGBGR。
我们可以选择使用区间dp,区间的左端点和右端点的颜色相同的话我们就可以直接给他涂上
如果不相同,那么我们就要枚举分割点k,在到
,和
到
分别涂好然后累加再求一次最小的min就可以了。
所以我们可以得到递推方程,当左端点等于右端点时,即有
左端点不等于右端点时,
最后的即
就是最后的答案
还有一个点我也是很无语,题目说的是长度为5的木板,输入描述里又变成了长度为n,这个地方卡了我好久。。。。无语是真的
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=100;
int dp[MAXN][MAXN];
string s;
int main(void){
cin>>s;
int len=s.size();
s='#'+s;
for(int i=0;i<MAXN;++i)
for(int j=0;j<MAXN;++j)
dp[i][j]=0xfff;
for(int i=1;i<=len;++i)
dp[i][i]=1;
for(int i=2;i<=len;++i){
for(int l=1;l+i-1<=len;++l){
int r=l+i-1;
if(s[l]==s[r])
dp[l][r]=min(dp[l+1][r],dp[l][r-1]);
else
for(int k=l;k<r;++k)
dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r]);
}
}
printf("%d\n",dp[1][len]);
return 0;
}

京公网安备 11010502036488号