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;
        
    }
  • 相关阅读:
    算法的学习 — 冒泡排序
    自定义UICollectionLayout布局 —— UIKit之学习UICollectionView记录一《瀑布流》
    HDU 1541 Stars (线段树||树状数组)
    HDU 1617 Phone List (排序||字典树)
    CSU 1312 CX and girls (最短路)
    CSU 1320 Scoop water (卡特兰数)
    POJ 1838 Banana (并查集)
    POJ 1837 Balance (DP)
    POJ 1088 滑雪 (记忆化搜索)
    TYVJ 1261 可达总数 (BFS)
  • 原文地址:https://www.cnblogs.com/lizitong/p/10020767.html
Copyright © 2011-2022 走看看