luoguP4170 [CQOI2007]涂色

区间DP连手题.

\(dp[st][ed]\)表示将区间\([st,ed]\)染成合法的最小方案数.

分两种情况讨论.

\(s[st]=s[ed]\)时,\(dp[st][ed]=\min(dp[st+1][ed],dp[st][ed-1])\)

\(s[st]!=s[ed]\)时,\(dp[st][ed]=\min(dp[st][ed],dp[st][i]+dp[i+1][ed])(i\in[st,ed])\)

初始化即将\(dp[i][i]\)置为1.

千万不要被它的数据范围迷惑!!

#pragma GCC optimize(3)
#include
#define il inline
#define rg register
#define gi read
using namespace std;
const int O = 1010;
template
il TT read() {
    TT o = 0,fl = 1; char ch = getchar();
    while (!isdigit(ch) && ch != '-') ch = getchar();
    if (ch == '-') fl = -1, ch = getchar();
    while (isdigit(ch)) o = o * 10 + ch - '0', ch = getchar();
    return fl * o;
}
char s[52];
int n, dp[52][52];
int main() {
    scanf("%s", s + 1); n = strlen(s + 1);
    for (int i = 1; i <= n; ++i) dp[i][i] = 1;
    for (int len = 1; len < n; ++len)
        for (int st = 1; st + len <= n; ++st) {
            int ed = st + len;
            dp[st][ed] = min(dp[st + 1][ed], dp[st][ed - 1]);
            if (s[st] != s[ed]) {
                ++dp[st][ed];
                for (int i = st + 1; i < ed; ++i)
                    dp[st][ed] = min(dp[st][ed], dp[st][i] + dp[i + 1][ed]);
            }
        }
    printf("%d\n", dp[1][n]);
    return 0;
}

你可能感兴趣的:(luoguP4170 [CQOI2007]涂色)