zoukankan      html  css  js  c++  java
  • [CQOI2007]涂色paint(BZOJ 1260)题解

    题目描述

    假设你有一条长度为5的木版,初始时没有涂过任何颜色。你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为5的字符串表示这个目标:RGBGR。

    每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成RRRRR,第二次涂成RGGGR,第三次涂成RGBGR,达到目标。

    用尽量少的涂色次数达到目标。

    输入输出格式

    输入格式:

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

    输出格式:

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


    非常明显的一道区间DP

    关于区间DP转https://www.cnblogs.com/lizitong/p/10014809.html

    我们要将一个区间涂成给出的颜色。

    这道题的难点在于其与我们的思维相逆。

    我们主观上的涂色全部都是先涂底层,然后在逐渐在上面覆盖,而这道题的状态转移方程却不同。

    首先状态,dp[i][j]表示[i]到[j]的最少次数。

    注意清初值,由于是求最小,初值清成正无穷,每个单独的颜色都需要涂,所以清成1。

    当我们枚举长度的时候,如果[i][j]颜色相同,岂不是我在涂[i][j-1]或者[i+1][j]顺带一笔就可以带过去?

    这就是我所说的与我们印象相逆的地方。假设我们现实中一笔带过去,中间的颜色全部会变色,但是我们这里是一个逆向的过程,中间的颜色是建立在已经涂过的颜色基础上的。

    仔细想想。

    那如果[i][j]颜色不一样呢?

    那我们就需要把这段区间分成两段涂,枚举k在区间[i][j]中,把区间分成两段,然后将次数相加。

    上代码。欢迎大家在评论区留言讨论。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<string>
    using namespace std;
    char c[55];
    int dp[55][55];
    int main()
    {
        scanf("%s",c+1);
        int l = strlen(c+1);
        memset(dp,0x3f,sizeof(dp));    
        for(int i = 1;i<=l;i++)
        {
            dp[i][i] = 1;
        }
        for(int len = 2;len<=l;len++)
        {
            for(int i = 1;i+len-1<=l;i++)
            {
                int j = i+len-1;
                if(c[i]==c[j])
                {
                    dp[i][j] = min(dp[i+1][j],dp[i][j-1]);
                }else
                {
                    for(int k = i;k<j;k++)
                    {
                        dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]);
                    }
                }    
            }
        }
        printf("%d",dp[1][l]);
        return 0;
        
    }
  • 相关阅读:
    .net core 3.1 使用Redis缓存
    JavaSE 高级 第11节 缓冲输入输出字节流
    JavaSE 高级 第10节 字节数组输出流ByteArrayOutputStream
    JavaSE 高级 第09节 字节数组输入流ByteArrayInputStream
    JavaSE 高级 第08节 文件输出流FileOutputStream
    JavaSE 高级 第07节 文件输入流FileInputStream
    JavaSE 高级 第06节 初识I、O流
    JavaSE 高级 第05节 日期类与格式化
    JavaSE 高级 第04节 StringBuffer类
    JavaSE 高级 第03节 Math类与猜数字游戏
  • 原文地址:https://www.cnblogs.com/lizitong/p/10020767.html
Copyright © 2011-2022 走看看