CodeForces 812 B.Sagheer, the Hausmeister(dp)

题意

给你一个n层楼每层m个房间+2个楼梯道,从第一层的左楼梯口开始过一个+1min,求关闭所有灯的最短时间.

题解

dp记录每层楼的左右开灯房间,维护楼梯口的时间;

dp[i][m+1] = min(dp[i][m+1]+2*(m+1-l), k+m+1);

dp[i][0] = min(dp[i][0]+2*r, dp[i][m+1]+m+1);

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

const int maxn = 20, maxm = 105;
int dp[maxn][maxm+2];
char mapp[maxn][maxm+2]; 

int main(){
	int n, m;
	while(~scanf("%d %d", &n, &m)){
		int x = -1, y = -1, ok = 0;
		for(int i = 0; i < n; i++){
			for(int j = 0; j < m+2; j++){
				scanf("%1d", &mapp[i][j]);
				if(mapp[i][j] == 1 && !ok){
					x = i;
					y = j;
					ok = 1;
				}
			}
		}
		if(x == -1 && y == -1){
			printf("0\n");
		}
		else{
			int l, r;
			memset(dp, INF, sizeof(dp));
			dp[n-1][0] = 0;
			for(int i = n-1; i >= 0; i--){
				l = 0;
				r = 0;
				dp[i][0] = min(dp[i][0], dp[i+1][0]+1);
				dp[i][m+1] = min(dp[i][m+1], dp[i+1][m+1]+1);
				for(int j = 1; j <= m; j++){
					if(mapp[i][j] == 1){
						if(l == 0){
							l = j;
						}
						r = j;
					}
				}
				int k = dp[i][0];
				if(r){
					dp[i][0] = min(dp[i][0]+2*r, dp[i][m+1]+m+1);
				}
				if(l){
					dp[i][m+1] = min(dp[i][m+1]+2*(m+1-l), k+m+1);
				}
			}
			l = 0;
			r = 0;
			for(int i = 0;i <= m+1; i++){
				if(mapp[x][i] == 1){
					if(l == 0){
						l = i;
					}
					r = i;
				}
			}
			int ans = min(dp[x+1][0]+r+1, dp[x+1][m+1]+m+2-l);
			if(x == n-1){
				ans = r;
			}
			printf("%d\n", ans);
		}
	}
}

 

阅读更多

没有更多推荐了,返回首页