题意:
对于一段空白的木板,每次可以选取连续的一段涂上任意中颜色,问将木板涂至给定颜色需要的最少次数。

思路:
区间dp。
原问题:将木板全部涂色完成需要的最少次数。
子问题:将木板的连续某一段涂完需要的最少次数。
记:dp[i][j]表示将木板的第i块至第j块涂成指定颜色需要的最少次数。

区间dp考虑先枚举长度;
当块的长度为一时,只要涂一次,即dp[i][i]=1;
当木板长度大于一时:
若端点的两块颜色相同,可认为在涂一端时顺带涂了另一端,所以 dp[i][j]=min(dp[i][j-1],d[i+1][j]);
若端点的两块颜色不相同,则可以在端点间枚举端点,即先涂第i块到第k块,再涂第k+1块到第j块,所以 dp[i][j]=min{dp[i][k]+dp[k+1][j]}(i<k<j);

最后输出第一块到最后一块的次数即可。

代码:

#include <iostream>
#include <queue>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <cmath>
#include <algorithm>
#include <cstdio>
#include <cctype>
#include <functional>
#include <string>
#include <cstring>
#include <sstream>
#include <deque>
#define fir first
#define sec second
using namespace std;

typedef long long ll;
typedef pair<ll,ll> P;
typedef pair<P,int> Q;

const int inf1=2e9+9;
const ll inf2=8e18+9;
const ll mol=1e9+7;
const int maxn=2e5+9;
const ll maxx=1e12+9;

string s;
int dp[555][555];

int main()
{
    cin>>s;
    int n=s.size();
    for(int i=0;i<n;i++) dp[i][i]=1;
    for(int len=2;len<=n;len++)
    {
        for(int i=0,j=i+len-1;j<n;i++,j++)
        {
            if(s[i]==s[j]) dp[i][j]=min(dp[i+1][j],dp[i][j-1]);
            else
            {
                dp[i][j]=dp[i][i]+dp[i+1][j];
                for(int k=i+1;k<j;k++)
                    dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);
            }
        }
    }
    printf("%d\n",dp[0][n-1]);
}