1013: 冒险游戏(risk_game)
时间限制: 2 Sec 内存限制:2048 MB提交: 59 解决: 23
题目描述
河海组织一场冒险游戏,该游戏将场地分为N*M的方格,每个方格内均有一个关卡,要闯过每个关卡,都需要消耗一定数量的体力
游戏的起点为(1,1) 终点为(N,M),每通过一关,可以选择右方或下方的一个关卡,顺利通过终点则挑战成功,但在任何地方体力透支(体力值<0)则挑战失败
如果要通过挑战,在开始挑战时最少需要补充多少体力?
游戏的起点为(1,1) 终点为(N,M),每通过一关,可以选择右方或下方的一个关卡,顺利通过终点则挑战成功,但在任何地方体力透支(体力值<0)则挑战失败
如果要通过挑战,在开始挑战时最少需要补充多少体力?
输入
第一行两个数,分别是n m,(1<= n,m <= 2000)
后面n行,每行m个非负数,表示每个关卡需要消耗的体力 (0<= a[i][j] <= 10000)
后面n行,每行m个非负数,表示每个关卡需要消耗的体力 (0<= a[i][j] <= 10000)
输出
一行,表示最小体力数
样例输入
2 2
1 2
3 4
样例输出
7
提示
共2条可选路径
1->2->4 7
1->3->4 8
来源
思路:
一个二维的动态规划,给出一个矩阵,全是正数,要求从1,1 走到M,N,每次只能向下或向右,输出路径上点数字之和最小。状态转移方程:dp[i][j] = min{dp[i-1][j] , dp[i][j-1]} + a[i][j]。WA了几次,是因为inf开的太小了,之前还一直担心inf如果开的很大会爆掉,但是经过这几次的做题发现inf不会轻易爆掉的,反而有好几次是因为inf开的比较小而造成结果错误。另外数组也要开大一点。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
long long dp[2010][2010];
int a[2010][2010];
int min(int a,int b)
{
return a<b?a:b;
}
int main()
{
//freopen("in.txt","r",stdin);
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
for(int i=2;i<=n;i++)dp[i][0]=1<<30;
for(int i=2;i<=m;i++)dp[0][i]=1<<30;
dp[0][0]=0;
dp[0][1]=0;
dp[1][0]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
dp[i][j]=min(dp[i-1][j],dp[i][j-1])+a[i][j];
}
printf("%lld\n",dp[n][m]);
}
}