[Jzoj] 1035.【SCOI2009】粉刷匠

探讨了在有限次数下,如何通过动态规划算法求解将木板格子正确粉刷为红蓝两色的问题。文章详细介绍了状态转移方程,并提供了一段C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

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

题目解析

DPDPDP
f[i,j,k,0/1]f[i,j,k,0/1]f[i,j,k,0/1]表示前iii个木板,涂色到第iii个木板的第jjj个,粉刷了kkk次,且第i,ji,ji,j个的格子涂成0/10/10/1的最大值。
j=1j=1j=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,0]=max(f[i-1,m,k-1,0],f[i-1,m,k-1,1])f[i,j,k,0]=max(f[i1,m,k1,0],f[i1,m,k1,1])f[i,j,k,1]f[i,j,k,1]f[i,j,k,1]同理。表示到新的一个木板时,就另外涂色。

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

接着判断当前格子的颜色,若为000,则f[i,j,k,0]++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]);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值