zoukankan      html  css  js  c++  java
  • BZOJ1260 [CQOI2007]涂色paint 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ1260


    题意概括

      假设你有一条长度为5的木版,初始时没有涂过任何颜色。你希望把它的5个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为5的字符串表示这个目标:RGBGR。 每次你可以把一段连续的木版涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木版涂成RRRRR,第二次涂成RGGGR,第三次涂成RGBGR,达到目标。 用尽量少的涂色次数达到目标。

      n<=50


    题解

      我们考虑区间型动归。

      如果s[L] = s[R] ,那么显然有dp[L][R] = min(dp[L][R] , dp[L + 1][R] , dp[L][R - 1])。

      如果s[L] = s[L + 1],那么有dp[L][R] = min(dp[L][R] , dp[L + 1][R]);

      如果s[R] = s[R - 1],那么有dp[L][R] = min(dp[L][R] , dp[L][R - 1]);

      剩余的情况,就是基础的区间合并:dp[L][R]=min(dp[L][R] , dp[L][k] +dp[k+1][R] |  L <= k Λ k<R);

      所以n3复杂度。

      这题有30秒时限,貌似开大了。

      记忆化dfs也可以做的。

      初始所有的dp[i][i] = 1;


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    using namespace std;
    const int N=50+5;
    int n,dp[N][N];
    char s[N];
    int main(){
    	scanf("%s",s+1);
    	n=strlen(s+1);
    	memset(dp,63,sizeof dp);
    	for (int i=1;i<=n;i++)
    		dp[i][i]=1;
    	for (int i=1;i<n;i++)
    		for (int j=1;j+i<=n;j++){
    			int L=j,R=j+i;
    			if (s[L]==s[R])
    				dp[L][R]=min(dp[L+1][R],dp[L][R-1]);
    			if (s[L]==s[L+1])
    				dp[L][R]=min(dp[L][R],dp[L+1][R]);
    			if (s[R]==s[R-1])
    				dp[L][R]=min(dp[L][R],dp[L][R-1]);
    			for (int k=L;k<R;k++)
    				dp[L][R]=min(dp[L][R],dp[L][k]+dp[k+1][R]);
    		}
    	printf("%d",dp[1][n]);
    	return 0;
    }
    

      

  • 相关阅读:
    86. Partition List
    2. Add Two Numbers
    55. Jump Game
    70. Climbing Stairs
    53. Maximum Subarray
    64. Minimum Path Sum
    122. Best Time to Buy and Sell Stock II
    以场景为中心的产品设计方法
    那些产品经理犯过最大的错
    Axure教程:如何使用动态面板?动态面板功能详解
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1260.html
Copyright © 2011-2022 走看看