#dp#洛谷 4158 [SCOI2009]粉刷匠

题目


分析

首先每条木板可以分开处理,再合并起来求最大值
下面讲一下单独处理每条木板的情况
\(dp[k][m]\)表示前\(m\)个格子粉刷了\(k\)次最多正确粉刷的格子数
那么

\[dp[k][m]=\max\{dp[k-1][m']+(m-m'-(s[m]-s[m']))\} \]


代码

#include <cstdio>
#include <cstring>
#define rr register
using namespace std;
const int N=51;
int n,m,T,ans,s[N],dp[N*N],f[N][N];
inline signed min(int a,int b){return a<b?a:b;}
inline signed max(int a,int b){return a>b?a:b;}
signed main(){
	scanf("%d%d%d",&n,&m,&T);
	for (rr int i=1;i<=n;++i){
		memset(f,0,sizeof(f));
	    for (rr int j=1;j<=m;++j){
		    rr char c=getchar();
		    while (c!=48&&c!=49) c=getchar();
	        s[j]=s[j-1]+(c^48);
		}
		for (rr int j=1;j<=m;++j)
		    for (rr int k=j;k<=m;++k)
		        for (rr int p=j-1;p<k;++p)
		            f[j][k]=max(f[j][k],f[j-1][p]+max(s[k]-s[p],k-p-s[k]+s[p]));
		for (rr int j=T;j>=1;--j)
		for (rr int k=min(j,m);~k;--k)
		    dp[j]=max(dp[j],dp[j-k]+f[k][m]);
	}
	for (rr int i=1;i<=T;++i) ans=max(ans,dp[i]);
	return !printf("%d",ans);
} 
posted @ 2020-10-15 16:48  lemondinosaur  阅读(81)  评论(0)    收藏  举报