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

题目链接:Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister

题意:

有n层楼,每层有m个房间,每层的两边是楼梯。

现在有一个人站在左下角,这个人必须将这一层的灯关闭后才能去另外一层。

每移动一次需要1分钟,问关闭所有灯需要多少时间。

题解:

考虑DP[i][j]表示当前已经关闭了第i层全部的灯,j=0时表示在这一层的最左边,j=1时表示在这一层的最右边。

然后推上去就行了。最后讨论一下特殊情况。

 1 #include<bits/stdc++.h>
 2 #define F(i,a,b) for(int i=(a);i<=(b);++i)
 3 using namespace std;
 4
 5 int n,m,l[16],r[16],dp[15][2];
 6 char s[200];
 7
 8 void up(int &a,int b){if(a>b)a=b;}
 9
10 int main()
11 {
12     scanf("%d%d",&n,&m);m+=2;
13     F(i,1,n)
14     {
15         l[i]=m,r[i]=1;
16         scanf("%s",s+1);
17         F(j,1,m)if(s[j]==‘1‘){l[i]=j;break;}
18         for(int j=m;j;j--)if(s[j]==‘1‘){r[i]=j;break;}
19     }
20     F(i,1,n)F(j,0,1)dp[i][j]=INT_MAX;
21     dp[n][1]=m-1,dp[n][0]=2*(r[n]-1);
22     int cnt=1,ans=INT_MAX;
23     F(i,1,n){if(l[i]==m)cnt=i+1;else break;}
24     for(int i=n-1;i>=cnt;i--)
25     {
26         if(i==cnt)
27         {
28             up(ans,dp[i+1][0]+r[i]);
29             up(ans,dp[i+1][1]+m-l[i]+1);
30         }
31         else
32         {
33             up(dp[i][0],dp[i+1][0]+2*r[i]-1);
34             up(dp[i][0],dp[i+1][1]+m);
35             up(dp[i][1],dp[i+1][0]+m);
36             up(dp[i][1],dp[i+1][1]+2*(m-l[i]+1)-1);
37         }
38     }
39     if(cnt>=n||n==1)ans=r[n]-1;//注意特殊情况
40     printf("%d\n",ans);
41     return 0;
42 }

时间: 2024-10-12 20:04:45

Codeforces Round #417 (Div. 2) B. Sagheer, the Hausmeister(DP)的相关文章

Codeforces Round #417 (Div. 2) A. Sagheer and Crossroads 模拟 枚举

Codeforces Round #417 (Div. 2) A. Sagheer and Crossroads 模拟  枚举 题意 一个红绿灯 按逆时针方向一次给出各个路口的左转,直行,右转,以及行人车道让你判断,汽车是否有可能撞到行人 注意 当前车道的左转有可能撞到别的车道的行人的 题解 一大堆特判 1 #include <cstdio> 2 #include <cmath> 3 #include <cstdlib> 4 #include <cstring&g

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序

Codeforces Round #417 (Div. 2) C. Sagheer and Nubian Market 二分答案 +排序 题意 有 a[ i ] 个数 要求选最多的数 使其和不超过 S ,且在此情况下,和最小选最多数情况下 和最小 且 每个数有加成 如果选了 k个数 那么加成后 就是 a[ i ] + k*i ; 题解 二分mid 表示选了个数 加成一下,将加成以后结果排序一下 , 若前 mid数 和大于 s 则此方案不可行 PS 要用 long long ..... 还有 co

Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree(树上Nim)

题目链接:Codeforces Round #417 (Div. 2) E. Sagheer and Apple Tree 题意: 给你一棵树,每个节点有a[i]个苹果,有两个人要在这个树上玩游戏. 两个人轮流操作,谁不能操作谁就输了. 这个树有一个特性:叶子到根的距离的奇偶性相同. 每次操作可以选一个节点i,和一个数x,x小于当前节点i的苹果数. 对于节点i,如果是叶子节点,就将这x个苹果吃掉. 如果是非叶子节点,就将这x个苹果移向节点i的任意儿子节点. 现在第二个操作的人要交换两个节点的苹果

(博弈\sg) Codeforces Round #417 (Div. 2) E Sagheer and Apple Tree

Sagheer is playing a game with his best friend Soliman. He brought a tree with n nodes numbered from 1 to n and rooted at node 1. The i-th node has ai apples. This tree has a special property: the lengths of all paths from the root to any leaf have t

Codeforces Round #417 (Div. 2)-A. Sagheer and Crossroad

[题意概述] 在一个十字路口 ,给定红绿灯的情况, 按逆时针方向一次给出各个路口的左转,直行,右转,以及行人车道,判断汽车是否有可能撞到行人 [题目分析] 需要在逻辑上清晰,只需要把所有情况列出来即可 [AC] 1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int main() { 5 int light[10][10]; 6 7 8 for(int i = 1; i <= 4; i++) 9 for(int j = 1; j

Codeforces Round #360 (Div. 2) D 数学推导 E dp

Codeforces Round #360 (Div. 2) A  == B  水,但记一下: 第 n 个长度为偶数的回文数是  n+reverse(n). C    dfs 01染色,水 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i

Codeforces Round #417 (Div. 2)——ABCE

题目链接 题面有点长需耐心读题. A.一个人行道上的人被撞有4种情况 1.所在车道有车驶出 2.右边车道有左转车 3.左边车道有右转车 4.对面车道有直行车 #include <bits/stdc++.h> #define rep(i, j, k) for(int i = j;i <= k;i ++) #define rev(i, j, k) for(int i = j;i >= k;i --) using namespace std; typedef long long ll;

Codeforces Round #245 (Div. 1) B. Working out (简单DP)

题目链接:http://codeforces.com/problemset/problem/429/B 给你一个矩阵,一个人从(1, 1) ->(n, m),只能向下或者向右: 一个人从(n, 1) ->(1, m),只能向上或者向右.必须有一个相遇点, 相遇点的值不能被取到, 问两个人能得到的最大路径和是多少? dp[i][j]:表示从一个点出发的最大值:先预处理从(1,1) (1,m) (n,1) (n,m)四个点出发的4个dp最大值.然后枚举所有的点,但是这个点不能在边缘,考虑枚举点不够

Codeforces Round #168 (Div. 1) B. Zero Tree 树形dp

题目链接: http://codeforces.com/problemset/problem/274/B 题意: 给出一棵树,每个点有权值,每次操作可以对一个联通子集中的点全部加1,或者全部减1,且每次操作必须包含点1,问最少通过多少次操作可以让整棵树每个点的权值变为0. 思路: http://blog.csdn.net/qq_24451605/article/details/48622953 定义状态up[u],down[u]代表点u被加操作的次数和点u被减操作的次数 因为必须包含点1,所以我