涂色计划P4170

题目描述

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

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

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

输入格式

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

输出格式

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

输入输出样例

输入 #1
AAAAA
输出 #1
1
输入 #2
RGBGR
输出 #2
3

说明/提示

40%40\%40% 的数据满足 1≤n≤101\le n\le 10 1n10。

100%100\%100% 的数据满足

 

#include<bits/stdc++.h>
using namespace std;
const int N= 105,INF=0x3f3f3f3f;
int f[N][N],n;
char s[N];
int dfs(int l,int r)
{
    if(l==r) return f[l][r]=1;
    if(f[l][r]!=-1) return f[l][r];
    f[l][r]=INF;
    if(s[l]==s[r])
        for(int i=l;i<=r-1;i++)
        {
            f[l][r]=min(f[l][r],dfs(l,i)+dfs(i+1,r)-1);
        }
    else
    {
        for(int i=l;i<=r-1;i++)
        {
            f[l][r]=min(f[l][r],dfs(l,i)+dfs(i+1,r));
        }
    }
    return f[l][r];
}
int main()
{
    while(scanf("%s",s+1)!=EOF)
    {
        n=strlen(s+1);
        memset(f,-1,sizeof(f));
        dfs(1,n);
        printf("%d\n",f[1][n]);
    }
    return 0;
}

 

#include<bits/stdc++.h>
using namespace std;
const int N= 105,INF=0x3f3f3f3f;
int f[N][N],n;
char s[N];

int main()
{
    while(scanf("%s",s+1)!=EOF)
    {
        n=strlen(s+1);
        memset(f,0x3f,sizeof(f));
        for(int i=1;i<=n;i++)
            f[i][i]=1;
        for(int len=1;len<=n;len++)
        {
            
            for(int l=1;l+len-1<=n;l++)
            {
                int r=l+len-1;
                for(int k=l;k<=r-1;k++)
                    if(s[l]==s[r]) f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]-1);
                    else f[l][r]=min(f[l][r],f[l][k]+f[k+1][r]);
            }
        }
        printf("%d\n",f[1][n]);
    }
    return 0;
}

 

 

 
posted @ 2021-03-13 18:09  conprour  阅读(80)  评论(0编辑  收藏  举报