• 杂题 CQOI2007paint


      这道题对于区间进行涂色,就往区间dp上想。

      区间dp肯定是从小区间合并到大区间,所以状态就写出来了。即dp[ i ][ j ]代表从 i 到 j 的区间中的最小方案数。

      同时,在每一次取 i 和 j 的时候,我们在 i 到 j 中枚举 k ,借此来枚举所有的区间分割情况。

      所以dp方程即为dp[ i ][ j ] = min ( dp[ i ][ j ] , dp[ i ][ k ] + dp[ k + 1][ j ]);

      同时我们要考虑尽量的删减涂色的次数。而当一段区间两端颜色相同时,我们不需要分别涂两端,而是先涂一笔,再在两端区间内涂色即可。所以如果当第 i 个颜色和第 j 个颜色相同时,我们将dp[ i ][ j ] - -;

      代码如下:

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<algorithm>
     4 #include<cstring>
     5 using namespace std;
     6 int n,dp[1005][1005];
     7 char c[1005];
     8 int main()
     9 {
    10     scanf("%s",c);
    11     n = strlen(c);
    12     for(int i=0; i<n; i++)
    13     for(int j=0; j<n; j++)
    14     dp[i][j] = 100000005;
    15     for(int i=0; i<n; i++) dp[i][i] = 1;
    16     for(int i=1; i<n; i++)
    17     {
    18         for(int j=0; j<n; j++)
    19         {
    20             for(int k=j; k<i+j; k++)
    21             {
    22                 dp[j][i+j] = min(dp[j][k]+dp[k+1][i+j],dp[j][j+i]);
    23             }
    24             if(c[j] == c[i+j]) dp[j][i+j]--;
    25         //    printf("%d %d %d
    ",j,i+j,dp[j][j+i]);
    26         }
    27     }
    28     printf("%d",dp[0][n-1]);
    29     return 0;
    30 }

     

  • 相关阅读:
    1112评论
    1029 C语言文法
    0909编译原理理解和解释
    复利计算4.0-单元测试
    命令解析程序的编写
    《构建之法》1、2、3章思考与感想
    复利计算4.0
    实验三的分析与总结
    复利计算(更新)
    单、复利计算程序
  • 原文地址:https://www.cnblogs.com/qmcp/p/9537650.html
Copyright © 2020-2023  润新知