您的位置:首页 > 其它

Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister

2017-06-03 14:47 429 查看
传送门

B. Sagheer, the Hausmeister

time limit per test
1 second

memory limit per test
256 megabytes

input
standard input

output
standard output

Some people leave the lights at their workplaces on when they leave that is a waste of resources. As a hausmeister of DHBW, Sagheer waits till all students and professors leave the university building, then goes and turns all the lights off.

The building consists of n floors with stairs at the left and the right sides. Each floor has m rooms
on the same line with a corridor that connects the left and right stairs passing by all the rooms. In other words, the building can be represented as a rectangle with n rows
and m + 2 columns, where the first and the last columns represent the stairs, and the m columns
in the middle represent rooms.

Sagheer is standing at the ground floor at the left stairs. He wants to turn all the lights off in such a way that he will not go upstairs until all lights in the floor he is standing at are off. Of course, Sagheer must visit a room to turn the light there
off. It takes one minute for Sagheer to go to the next floor using stairs or to move from the current room/stairs to a neighboring room/stairs on the same floor. It takes no time for him to switch the light off in the room he is currently standing in. Help
Sagheer find the minimum total time to turn off all the lights.

Note that Sagheer does not have to go back to his starting position, and he does not have to visit rooms where the light is already switched off.

Input

The first line contains two integers n and m (1 ≤ n ≤ 15 and 1 ≤ m ≤ 100)
— the number of floors and the number of rooms in each floor, respectively.

The next n lines contains the building description. Each line contains a binary string of length m + 2 representing
a floor (the left stairs, then m rooms, then the right stairs) where 0 indicates
that the light is off and 1 indicates that the light is on. The floors are listed from top to bottom, so that the last line represents the
ground floor.

The first and last characters of each string represent the left and the right stairs, respectively, so they are always 0.

Output

Print a single integer — the minimum total time needed to turn off all the lights.

Examples

input
2 2
0010
0100


output
5


input
3 4
001000
000010
000010


output
12


input
4 3
01110
01110
01110
01110


output
18


Note

In the first example, Sagheer will go to room 1 in the ground floor, then he will go to room 2 in
the second floor using the left or right stairs.

In the second example, he will go to the fourth room in the ground floor, use right stairs, go to the fourth room in the second floor, use right stairs again, then go to the second room in the last floor.

In the third example, he will walk through the whole corridor alternating between the left and right stairs at each floor.

题意:

从左下角开始走 1和m+2是走廊。 中间是房间 如果中间的房间有1的话就代表是开了灯的就要过去关灯。 另外只有走廊能上楼。所以代表只有两边可以上楼。

问最少花费多少时间关完所有的灯,移动一格算一次时间。 (如果已经关完了所有的灯就算结束) 可以dfs也可以dp。因为问的是最少时间嘛。 这种最值问题dp稳的。

#include <bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//using namespace __gnu_pbds;
using namespace std;

#define pi acos(-1)
#define endl '\n'
#define me(x) memset(x,0,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define close() ios::sync_with_stdio(0);
#define rand() srand(time(0));
typedef long long LL;
typedef pair<int, int> pii;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,1,0,0,-1,-1,1,1};
const int dy[]={0,0,1,-1,1,-1,1,-1};
const int maxn=1e3+5;
const int maxx=1e5+100;
const double EPS=1e-9;
const int MOD=1000000007;
#define mod(x) ((x)%MOD);
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
//typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree;
/*lch[root] = build(L1,p-1,L2+1,L2+cnt);
rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*/
/*lch[root] = build(L1,p-1,L2,L2+cnt-1);
rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/
long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}

inline int Scan()
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')flag=1;
else if(ch>='0' && ch<='9')res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-'0';
return flag ? -res : res;
}

int n, m;
char ch[20][120];
int l[20], r[20],visit[20],dp[20][2];

int main()
{
while (~scanf("%d%d", &n, &m))
{
memset(visit, 0, sizeof visit);
memset(r,0,sizeof r);
memset(l,0,sizeof l);
for (int i = n; i >= 1; i--)
{
scanf("%s", ch[i] + 1);
for (int j = 2; j <= m + 1; j++)
if (ch[i][j] == '1') { l[i] = j;visit[i] = 1;break; }//找最左边灯所在的位置
for (int j = m + 1; j >= 2; j--)
if (ch[i][j] == '1') { r[i] = j; break; }//找最右边灯所在的位置
}
int x=n;
while(!visit[x--]&&x>=1) n--;//看一下最远的灯在哪 如果刚开始就不用关灯就不用进行下面的步骤了
if(n==1) {printf("%d\n",r[1]?r[1]-1:0);continue;}
memset(dp,INF,sizeof dp);
dp[1][0]=r[1]?(r[1]-1)*2:0,dp[1][1]=m+1;
for(int i=2;i<n;i++)
{
if(!visit[i])
{
dp[i][0]=dp[i-1][0]+1;
dp[i][1]=dp[i-1][1]+1;
continue;
}
dp[i][0]=min(dp[i-1][0]+2*(r[i]-1)+1,dp[i][0]);//dp[i][0]代表从左边楼梯上的楼 //dp[i][1]代表从右边楼梯上的楼
dp[i][0]=min(dp[i-1][1]+m+1+1,dp[i][0]);//从左边楼梯上的楼无非有两种情况,1是从最右边上的楼然后往左走。
dp[i][1]=min(dp[i-1][1]+2*(m+2-l[i])+1,dp[i][1]);//2是从左边上的楼。 去关了最右边的灯又回到最左边 步数就*2
dp[i][1]=min(dp[i-1][0]+m+1+1,dp[i][1]);//右边同理
}
int ans=min(dp[n-1][0]+r
,dp[n-1][1]+1+m+2-l
);
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: