codeforces 812B Sagheer, the Hausmeister dp

参考某大佬的思路:dp[I][0/1]表示已经灭掉第I层的灯,并且在第I层的左/右端
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 20;
const int maxm = 110;
int L[maxm],R[maxm];
int dp[maxn][2];
int main()
{
	int n,m;
	char s[maxm];
//	freopen("in.txt","r",stdin);
	while(cin>>n>>m)
	{
		int mx=1<<30;
		for(int i=1;i<=n;i++)
		{
			L[i]=1e5;R[i]=-1;
			cin>>s;
			for(int j=0;j<m+2;j++)
			{
				if(s[j]=='1')
				{
					L[i]=min(L[i],j);
					R[i]=max(R[i],j);
					mx=min(mx,i);
				}
			}
			if(L[i]==1e5)
			L[i]=0,R[i]=m+1;
		}
		int ans=0;
		for(int i=n;i>=mx;i--)
		{
			if(L[i]==0)//i层为空 
			{
				if(i==n)
				{
					dp[i][0]=0,dp[i][1]=m+1;
				}
				else
				{
					dp[i][0]=dp[i+1][0]+1;
					dp[i][1]=dp[i+1][1]+1;
				}
				continue;
			}
			if(i==mx)
			{
				ans=min(dp[i+1][0]+1+R[i],dp[i+1][1]+1+(m+1)-L[i]);
				continue;
			}
			if(i==n)
			{
				dp[i][0]=R[i]*2;
				dp[i][1]=m+1;
				continue;
			}
			dp[i][0]=min(dp[i+1][0]+2*R[i]+1,dp[i+1][1]+m+2);//灭掉 当前层灯
			dp[i][1]=min(dp[i+1][0]+m+2,dp[i+1][1]+2*(m+1-L[i])+1);
		}
		if(mx==n)
		{
			ans=R[n];
		}
		cout<<ans<<endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值