• 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
    ", ans);
    68     }
    69     return 0;
    70 }
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    2008年Web2.0峰会:发展是绝对的硬道理
    盖茨"接班人":微软产品为何总是挨批
    如何使用命令方式检测mx记录是否生效
    IBM公布未来5年将改变人类生活的五大科技
    谷歌李开复:我的传奇人生源于十句箴言
    VCL已死,RAD已死(3)
    VCL已死,RAD已死(2)
    主要程序设计语言范型综论与概要
    谷歌正式放弃与雅虎的广告合作计划
    模仿google分页代码
  • 原文地址:https://www.cnblogs.com/plumrain/p/LA_5983.html
Copyright © 2020-2023  润新知