解题思路:

  • 根据题目的提示,对于区间[l,r][l,r],令dpl,rdp_{l,r}表示区间中需要的最少涂色次数,若colorl=colorrcolor_l = color_r,则dpl,rdp_{l,r}可以由dpl+1,rdp_{l+1, r}或者dpl,r1dp_{l,r-1}转移过来,不会增加涂色次数,因为r或l可以由l或r直接一笔涂色完成。即最少涂色次数可以是:dpl,r=min(dpl+1,r,dpl,r1), colorl=colorrdp_{l,r} = \min(dp_{l+1,r}, dp_{l, r-1}), \ color_l = color_r
  • 对于区间[l,r]colorlcolorr[l,r], color_l \neq color_r,需要枚举区间中的每一个点有状态转移方程:dpl,r=min(dpl,r,dpl,k+dpk+1,r),k[l,r)dp_{l,r} = \min(dp_{l,r}, dp_{l,k}+dp_{k+1,r}),k \in [l, r)
  • 初始化dpi,i=1,i[0,len)dp_{i,i} = 1, i \in [0,len)
#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin >> s;
    int ln = s.size();
    vector<vector<int>> dp(ln, vector<int>(ln, 0));
    for (int i = 0; i < ln; ++i)
        dp[i][i] = 1;
    for (int len = 2; len <= ln; ++len)
    {
        for (int l = 0; l < ln - 1; ++l)
        {
            int r = l + len - 1;
            if (r >= ln)
                break;
            dp[l][r] = r - l + 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]);
                }
            }
        }
    }
    cout << dp[0][ln - 1] << endl;
    return 0;
}