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 }

 

posted @ 2021-02-11 13:23  acmloser  阅读(86)  评论(0编辑  收藏  举报