zoukankan      html  css  js  c++  java
  • 题解 lg4158 [SCOI2009]粉刷匠

    题意

    给 N 条每条被划分成 M 个格子的木板每个格子刷颜色,每一次刷只能刷一条木板连续的一段,且每一个格子最多只能粉刷一次,一共只能刷 T 次,问能够正确的刷多少格子.

    思路

    有一个很显然的性质,就是一条木板要是要涂就一定会涂满但bakaのfpjo显然没有注意到这一点

    且还有 每一个格子最多只能粉刷一次

    然后就很好来写dp转移了

    (g(i,j,k))(i) 条木板的前(j)个格子涂上(k)次的最大正确粉刷格子数,(pre(i,j))表示第(i)条木板的前(j)个格子中蓝色的数量明显有

    [g(i,j,k)=max_{0leq l leq j}(g(i,l,k-1)+max(pre(j)-pre(l),i-l-(pre(j)-pre(l)))) ]

    然后考虑(f(i,k))表示前(i)条木板涂(k)次的最大答案

    [f(i,k)=max_{0leq j leq k}(f(i-1,k-j)+g(i,m,j)) ]

    代码

    #include<bits/stdc++.h>
    using namespace std;
    int const MAXN=60,MAXT=2600;
    int n,m,T,ans=0;
    int pre[MAXN][MAXN],g[MAXN][MAXN][MAXT],f[MAXN][MAXT];
    char str[MAXN];
    int main(){
    	scanf("%d%d%d",&n,&m,&T);
    	for(int i=1;i<=n;i++){
    		scanf("%s",str+1);
    		for(int j=1;j<=m;j++){
    			pre[i][j]=(str[j]=='1')+pre[i][j-1];
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int k=1;k<=min(T,m);k++){
    			for(int j=1;j<=m;j++){
    				for(int l=0;l<=j;l++){
    					g[i][j][k]=max(g[i][j][k] , g[i][l][k-1]+max( pre[i][j]-pre[i][l],(j-l)-(pre[i][j]-pre[i][l]) ) );
    				}
    			}
    		}
    	}
    	for(int k=1;k<=T;k++){
    		for(int j=0;j<=min(k,m);j++){
    			for(int i=1;i<=n;i++){
    				f[i][k]=max(f[i][k],f[i-1][k-j]+g[i][m][j]);
    				ans=max(ans,f[i][k]);
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    android常用组件
    android button点击效果
    service+activity
    收藏
    c++
    工厂模式
    lr常遇到一些问题
    lr介绍
    ((1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(6) NOT NULL)' at line 1"))
    mysqlclient 1.4.0 or newer is required; you have 0.10.0
  • 原文地址:https://www.cnblogs.com/fpjo/p/14009106.html
Copyright © 2011-2022 走看看