您的位置:首页 > 产品设计 > UI/UE

UESTC 2016 Summer Training #2 Div.2(未完待续)

2016-07-13 11:25 369 查看
题目来源:SPOJ AMR11、UVALive 5983-5992

A

题意:给出一个n*m的图,从左上角出发,去右下角,只能向下或者向右走,每个格子有权值,问如何安排你在左上角时的权值,使得到达右下角时权值大于1。

做法:一开始想到的就是简单的直接DP,却发现有些问题,因为在过程中可能会出现不合法的情况,会影响到最后的情况,可是却不容易想清楚最后是因为什么导致答案错误。

因此最后的做法大致有两种:

1)用二分枚举答案,然后正向DP,找到符合条件的最小的答案。

2)逆向DP,假设最后走到终点是体力为1,在逆推的过程中,记住一旦出现小于1的体力值,就要将其改为1,最后得到的DP矩阵中最小的数一定只能是1

下面代码是第二种做法。第一种做法网上也很多,可以自行去找。

#include <bits/stdc++.h>

#define INF 0x3f3f3f3f
#define eps 1e-6
typedef long long LL;
const double pi = acos(-1.0);
const long long mod = 1e9 + 7;
using namespace std;

int R,C,T;
int S[505][505];
int dp[505][505];

int main()
{
scanf("%d",&T);
while(T--)
{
memset(S,0,sizeof(S));
scanf("%d %d",&R,&C);
for(int i = 1;i <= R;i++)
for(int j = 1;j <= C;j++)
scanf("%d",&S[i][j]);

memset(dp,0,sizeof(dp));
dp[R][C] = 1;
for(int i = R - 1;i > 0;i--)
dp[i][C] = max(dp[i + 1][C] - S[i][C],1);
for(int j = C - 1;j > 0;j--)
dp[R][j] = max(dp[R][j + 1] - S[R][j],1);
for(int i = R - 1;i > 0;i--)
for(int j = C - 1;j > 0;j--)
dp[i][j] = max(min(dp[i + 1][j],dp[i][j + 1]) - S[i][j],1);
printf("%d\n",dp[1][1]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: