BZOJ1260: [CQOI2007]涂色paint 区间DP

    xiaoxiao2022-06-22  31

    1260: [CQOI2007]涂色paint

    Time Limit: 30 Sec   Memory Limit: 64 MB Submit: 1144   Solved: 696 [Submit][Status][Discuss]

    Description

    假设你有一条长度为5的木版,初始时没有涂过任何颜色。你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为5的字符串表示这个目标:RGBGR。 每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成RRRRR,第二次涂成RGGGR,第三次涂成RGBGR,达到目标。 用尽量少的涂色次数达到目标。

    Input

    输入仅一行,包含一个长度为n的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。

    Output

    仅一行,包含一个数,即最少的涂色次数。

    Sample Input

    Sample Output

    【样例输入1】 AAAAA 【样例输入1】 RGBGR 【样例输出1】 1 【样例输出1】 3

    HINT

    40%的数据满足:1<=n<=10 100%的数据满足:1<=n<=50

    题解:

    区间DP的裸题,f[i][j]表示从i位置到j位置染成满足条件的颜色最少需要几次。 当s[i]==s[j]时,f[i][j]=min(f[i+1][j],f[i][j-1]) 当s[i]!=s[j]时,f[i][j]=min(f[i][k],f[k+1][j]) (i<=k<=j) #include<cstdio> #include<iostream> #include<cstring> #define inf 707185547 using namespace std; const int N=55; int n,f[N][N]; char s[N]; int main() { scanf("%s",s+1); n=strlen(s+1); for(int i=1;i<=n;i++) f[i][i]=1; for(int l=1;l<=n-1;l++) for(int i=1;i<=n-l;i++) { int j=i+l; f[i][j]=inf; if(s[i]==s[j]) f[i][j]=min(f[i][j-1],f[i+1][j]); else for(int k=i;k<=j;k++) f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]); } printf("%d\n",f[1][n]); }
    转载请注明原文地址: https://ju.6miu.com/read-1122767.html

    最新回复(0)