题意

现在给你一块长度为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;
}