2018-暑假留校训练赛(2)

题目链接:https://vjudge.net/contest/237052#problem/A

Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. Did we not tell you that it was just an online game ? uhhh! now here is the real onsite task for Harry. You are given a magrid S ( a magic grid ) having R rows and C columns. Each cell in this magrid has either a Hungarian horntail dragon that our intrepid hero has to defeat, or a flask of magic potion that his teacher Snape has left for him. A dragon at a cell (i,j) takes away |S[i][j]| strength points from him, and a potion at a cell (i,j) increases Harry's strength by S[i][j]. If his strength drops to 0 or less at any point during his journey, Harry dies, and no magical stone can revive him.
Harry starts from the top-left corner cell (1,1) and the Sorcerer's Stone is in the bottom-right corner cell (R,C). From a cell (i,j), Harry can only move either one cell down or right i.e., to cell (i+1,j) or cell (i,j+1) and he can not move outside the magrid. Harry has used magic before starting his journey to determine which cell contains what, but lacks the basic simple mathematical skill to determine what minimum strength he needs to start with to collect the Sorcerer's Stone. Please help him once again.

Thanks a lot for helping Harry Potter in finding the Sorcerer's Stone of Immortality in October. Did we not tell you that it was just an online game ? uhhh! now here is the real onsite task for Harry. You are given a magrid S ( a magic grid ) having R rows and C columns. Each cell in this magrid has either a Hungarian horntail dragon that our intrepid hero has to defeat, or a flask of magic potion that his teacher Snape has left for him. A dragon at a cell (i,j) takes away |S[i][j]| strength points from him, and a potion at a cell (i,j) increases Harry's strength by S[i][j]. If his strength drops to 0 or less at any point during his journey, Harry dies, and no magical stone can revive him.

Harry starts from the top-left corner cell (1,1) and the Sorcerer's Stone is in the bottom-right corner cell (R,C). From a cell (i,j), Harry can only move either one cell down or right i.e., to cell (i+1,j) or cell (i,j+1) and he can not move outside the magrid. Harry has used magic before starting his journey to determine which cell contains what, but lacks the basic simple mathematical skill to determine what minimum strength he needs to start with to collect the Sorcerer's Stone. Please help him once again.

Input (STDIN):

The first line contains the number of test cases T. T cases follow. Each test case consists of R C in the first line followed by the description of the grid in R lines, each containing C integers. Rows are numbered 1 to R from top to bottom and columns are numbered 1 to C from left to right. Cells with S[i][j] < 0 contain dragons, others contain magic potions.

Output (STDOUT):

Output T lines, one for each case containing the minimum strength Harry should start with from the cell (1,1) to have a positive strength through out his journey to the cell (R,C).

Constraints:

1 ≤ T ≤ 5

2 ≤ R, C ≤ 500

-10^3 ≤ S[i][j] ≤ 10^3

S[1][1] = S[R][C] = 0

Sample Input:

3
2 3
0 1 -3
1 -2 0
2 2
0 1
2 0
3 4
0 -2 -3 1
-1 4 0 -2
1 -2 -3 0

Sample Output:

2
1
2

Explanation:

Case 1 : If Harry starts with strength = 1 at cell (1,1), he cannot maintain a positive strength in any possible path. He needs at least strength = 2 initially.

Case 2 : Note that to start from (1,1) he needs at least strength = 1.

题目大意:给你一副图,问你从图左上点走到右下点,所需要的最小初始分数,因为每走到一点就要加上改点的值,且你要保证在中途每点上你的分数的值至少为1,你的走路方式只能往右走或下走。

个人思路:刚看到直接dfs,加上剪枝,改了六七遍,都是超时,然后意识到不能用dfs,立马想到dp来做,一直是正向思维,一直在想怎么写出状态转移方程,不过一直没写出来,因为如果用正向来做的话,不仅仅要保留该点的当前分数值,还要保留起点到该点所需的分数值,这样就控制不了了,但是逆向思维,从终点往回退,只需要保留该点到终点所需要的分值,而不需要考虑该点还剩多少分值,很简单就能做出来

dp[i][j]表示从该点到终点所需要的分值

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<set>
typedef long long ll;
using namespace std;
#define INF 1e9+7
int a[510][510];
int dp[510][510];//dp[i][j]表示从该点到终点所需要的最少分数
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
                scanf("%d",&a[i][j]);
        }
        dp[n-1][m-1]=1;//每个点最小是1,初始化终点是1
        for(int i=n-1;i>=0;i--)
        {
            for(int j=m-1;j>=0;j--)
            {
                if(i!=n-1&&j==m-1)
                {
                    dp[i][j]=max(1,dp[i+1][j]-a[i][j]);
                }
                else if(i==n-1&&j!=m-1)
                {
                    dp[i][j]=max(1,dp[i][j+1]-a[i][j]);
                }
                else if(i!=n-1&&j!=m-1)
                {
                    dp[i][j]=max(1,min(dp[i+1][j]-a[i][j],dp[i][j+1]-a[i][j]));
                }
            }
        }
        printf("%d\n",dp[0][0]);
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/caijiaming/p/9288101.html