[Jzoj] 1035.【SCOI2009】粉刷匠

送分小仙女□ 提交于 2019-11-26 19:12:07

题目大意

windywindyNN 条木板需要被粉刷。
每条木板被分为MM 个格子。
每个格子要被刷成红色或蓝色。
windywindy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。
每个格子最多只能被粉刷一次。
如果windywindy只能粉刷TT 次,他最多能正确粉刷多少格子?
一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。

题目解析

DPDP
f[i,j,k,0/1]f[i,j,k,0/1]表示前ii个木板,涂色到第ii个木板的第jj个,粉刷了kk次,且第i,ji,j个的格子涂成0/10/1的最大值。
j=1j=1时,f[i,j,k,0]=max(f[i1,m,k1,0],f[i1,m,k1,1])f[i,j,k,0]=max(f[i-1,m,k-1,0],f[i-1,m,k-1,1])f[i,j,k,1]f[i,j,k,1]同理。表示到新的一个木板时,就另外涂色。

j>1j>1时,f[i,j,k,0]=max(f[i,j1,k,0],f[i,j1,k1,1])f[i,j,k,0]=max(f[i,j-1,k,0],f[i,j-1,k-1,1])f[i,j,k,1]f[i,j,k,1],同理。

接着判断当前格子的颜色,若为00,则f[i,j,k,0]++f[i,j,k,0]++,反之同理。

代码

#include<bits/stdc++.h>
using namespace std;
int f[51][51][2501][2]; 
int n,m,t;
string s;
int main()
{
	cin>>n>>m>>t;
	for(int i=1;i<=n;i++)
	{
	  cin>>s;
	  for(int j=1;j<=m;j++)
	   for(int k=1;k<=t;k++)
	   {
	   	 if(j!=1)
	   	  f[i][j][k][0]=max(f[i][j-1][k][0],f[i][j-1][k-1][1]),f[i][j][k][1]=max(f[i][j-1][k][1],f[i][j-1][k-1][0]);
	   	 else
	   	  f[i][j][k][1]=f[i][j][k][0]=max(f[i-1][m][k-1][0],f[i-1][m][k-1][1]);
	   	if(s[j-1]=='0') f[i][j][k][0]++;else f[i][j][k][1]++;
	   }
	}
	cout<<max(f[n][m][t][1],f[n][m][t][0]);
} 
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!