P4170 [CQOI2007]涂色(思维好题)

P4170 [CQOI2007]涂色 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

设DP[i][j]为完成(i-j)区间的最少涂鸦次数。

考虑dp[i][j]的转移:
重点:如果s[i]==s[j],dp[i][j]=min(dp[i][j-1],dp[i+1][j]),因为颜色一样,只需要首次涂色的时候多图一个。

那为什么不是dp[i][j]=dp[i-1][j+1]+1呢?举例:RRWRR dp[1][5]!=dp[2][4]+1。

其他正常区间dp转移即可.

初始化:dp[i][i]=1.

 

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
const int N=110;
//const int M=;
const int inf=0x3f3f3f3f;     
//const ll INF=0x3ffffffffffff;
int T,n,dp[N][N];
char s[N];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
    scanf("%s",s+1);
    n=strlen(s+1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) dp[i][j]=inf;
    for(int i=1;i<=n;i++) dp[i][i]=1;
    for(int len=2;len<=n;len++)
        for(int i=1;i+len-1<=n;i++)
        {
            int j=i+len-1;
            if(s[i]==s[j]) dp[i][j]=min(dp[i][j-1],dp[i+1][j]);
            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][n]);
    return 0;
}

 

 

posted @ 2023-03-05 19:30  QAQ啥也不会  阅读(12)  评论(0编辑  收藏  举报