P4170 [CQOI2007]涂色
考察:区间dp
思路:
f[i][j]为涂色[i,j]区间的最少次数,按s[i]与s[j]的关系划分集合,如果s[i]!=s[j],我们枚举断点,f[i][j] = f[i][k]+f[k+1][j].如果s[i]==s[j],答案不是f[i+1][j-1]+1,这个方程不能处理全都相等的情况,应该考虑去掉一边即只涂f[i+1,j]或者f[i,j-1](涂了i处,j可以当作一起被涂)
注意s[i]==s[j]不是f[i][j] = f[i+1][j-1],而是s[i]或s[j]有一端不用涂了.
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 const int N = 55; 7 char s[N]; 8 int f[N][N]; 9 int main() 10 { 11 scanf("%s",s+1); 12 int lens = strlen(s+1); 13 for(int i=1;i<=lens;i++) f[i][i] = 1; 14 for(int len=2;len<=lens;len++) 15 for(int i=1;i+len-1<=lens;i++) 16 { 17 int j = i+len -1; f[i][j] = 0x3f3f3f3f; 18 if(s[i]==s[j]) f[i][j] = min(f[i+1][j],f[i][j-1]); 19 else 20 for(int k=i;k<j;k++) 21 f[i][j] = min(f[i][j],f[i][k]+f[k+1][j]); 22 } 23 printf("%d\n",f[1][lens]); 24 return 0; 25 }