UVALive 5983 MAGRID

题意:在一个n*m的网格上,从(0,0)走到(n-1,m-1),每次只能向右或者向下走一格。一个人最初有一个生命值x,走到每一个格生命值会变为x + s[i][j],(s[i][j]可为负,0,正),若生命值小于等于0,则人死亡。告诉网格上所有s[i][j],求x的最小值使得该人能够或者走到(n-1,m-1)。|s[i][j]| < 1000,n,m < 500。

解法:这道题不能直接dp,否则会错。必须要先二分x的值,然后再dp。dp[i][j]记录的是走到(i,j)格所能有的最大生命值,但是要注意,d[i][j]只能在d[i][j-1]或d[i-1][j]中有一个为正时才能转移过来。

   if (d[i-1][j] > 0) d[i][j] = max(d[i][j], d[i-1][j] + s[i][j]), if (d[i][j-1] > 0) d[i][j] = max(d[i][j], d[i][j-1] + s[i][j])。初始化时将所有d[i][j]赋值为-1。

tag:二分,dp

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-12-03 20:25
 4  * File Name: DP-LA-5983.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 
10 using namespace std;
11 
12 #define CLR(x) memset(x, 0, sizeof(x))
13 #define CLR1(x) memset(x, -1, sizeof(x))
14 
15 int n, m;
16 int d[505][505];
17 int s[505][505];
18 
19 void init()
20 {
21     scanf ("%d%d", &n, &m);
22     for (int i = 0; i < n; ++ i)
23         for (int j = 0; j < m; ++ j)
24             scanf ("%d", &s[i][j]);
25 }
26 
27 bool dp(int x)
28 {
29     CLR1 (d);
30     d[0][0] = x + s[0][0];
31     for (int i = 1; i < n; ++ i)
32         if (d[i-1][0] > 0)
33             d[i][0] = d[i-1][0] + s[i][0];
34     for (int i = 0; i < m; ++ i)
35         if (d[0][i-1] > 0)
36             d[0][i] = d[0][i-1] + s[0][i];
37 
38     for (int i = 1; i < n; ++ i)
39         for (int j = 1; j < m; ++ j){
40             if (d[i][j-1] > 0)
41                 d[i][j] = max(d[i][j], d[i][j-1] + s[i][j]);
42             if (d[i-1][j] > 0)
43                 d[i][j] = max(d[i][j], d[i-1][j] + s[i][j]);
44         }
45     if (d[n-1][m-1] <= 0) return 0;
46     return 1;
47 }
48 
49 int bin_search()
50 {
51     int l = 1, r = 1e7;
52     while (l <= r){
53         int mid = (l + r) >> 1;
54         if (!dp(mid)) l = mid + 1;
55         else r = mid - 1;
56     }
57     return l;
58 }
59 
60 int main()
61 {
62     int T;
63     scanf ("%d", &T);
64     while (T--){
65         init();
66         int ans = bin_search();
67         printf ("%d\n", ans);
68     }
69     return 0;
70 }
View Code

 

posted @ 2013-12-03 20:51  Plumrain  阅读(174)  评论(0编辑  收藏  举报