• 解题报告:luogu P4170


    题目链接:P4170 [CQOI2007]涂色

    区间 (dp) 好题。

    我们假如已经有这个区间的最小步数:

    [BRG ]

    如果在区间右端添加一个 R 会怎么样呢?

    考虑上一个涂到这个 R 未知的颜色是啥,显然是前面的这些之一或是他自己。

    如果是他自己,那么:

    [dp_{l,r}=dp_{l,r-1}+1 ]

    如果上一个与他不相同的话,那么设位置为 (k)

    [dp_{l,r}=dp_{l,k}+dp_{k+1,r-1}+1 ]

    如果上一个颜色与他相同:

    [dp_{l,r}=dp_{l,k}+dp_{k+1,r-1} ]

    如果是在右面加元素同理。

    (Code:)

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    
    #define inf 1000000000
    
    char s[55];
    int n,dp[55][55];
    
    int main()
    {
    	scanf("%s",s);
    	n=strlen(s);
    	for(int i=n+1;i>=1;i--) s[i]=s[i-1];
    	for(int i=0;i<=n;i++) for(int j=0;j<=n;j++) dp[i][j]=inf;
    	for(int i=0;i<=n;i++) dp[i][i]=1;
    	for(int i=1;i<=n;i++) for(int j=0;j<i;j++) dp[i][j]=0;
    	for(int i=2;i<=n;i++)
    	{
    		for(int l=1;l+i-1<=n;l++)
    		{
    			int r=l+i-1;
    			dp[l][r]=dp[l][r-1]+1;
    			for(int k=r-1;k>=l;k--)
    			{
    				if(s[k]==s[r]) dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r-1]);
    				else dp[l][r]=min(dp[l][r],dp[l][k]+dp[k+1][r-1]+1);
    			}
    			dp[l][r]=min(dp[l][r],dp[l+1][r]+1);
    			for(int k=l+1;k<=r;k++)
    			{
    				if(s[k]==s[l]) dp[l][r]=min(dp[l][r],dp[k][r]+dp[l+1][k-1]);
    				else dp[l][r]=min(dp[l][r],dp[l+1][k-1]+dp[k][r]+1);
    			}
    		}
    	}
    	printf("%d
    ",dp[1][n]);
    	return 0;
    }
    
  • 相关阅读:
    Java 8简明教程
    ASCII码
    正则 取反匹配
    Eclipse 常用快捷键
    MongoDb基本操作
    Mac下eclipse的快捷键
    oracle的字符集设置与乱码
    Java7、Java8 安装卸载问题
    Oracle | PL/SQL Check约束用法详解
    浅谈数据库中的触发器
  • 原文地址:https://www.cnblogs.com/tlx-blog/p/12885487.html
Copyright © 2020-2023  润新知