HHUOJ 1013
1013: 冒险游戏
时间限制: 2 Sec 内存限制: 256 MB提交: 197 解决: 33
[提交][状态][讨论版][命题人:admin]
题目描述
河海组织一场冒险游戏,该游戏将场地分为N*M的方格,每个方格内均有一个关卡,要闯过每个关卡,都需要消耗一定数量的体力
游戏的起点为(1,1) 终点为(N,M),每通过一关,可以选择右方或下方的一个关卡,顺利通过终点则挑战成功,但在任何地方体力透支(体力值<0)则挑战失败
如果要通过挑战,在开始挑战时最少需要补充多少体力?
游戏的起点为(1,1) 终点为(N,M),每通过一关,可以选择右方或下方的一个关卡,顺利通过终点则挑战成功,但在任何地方体力透支(体力值<0)则挑战失败
如果要通过挑战,在开始挑战时最少需要补充多少体力?
输入
第一行两个数,分别是n m,(1<= n,m <= 3000)
后面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
动态规划。
翻了一大堆博客并向聚聚们寻求帮助后,终于找到了根源所在,dp[maxn][maxn](也可以用f[maxn][maxn]表示,这不是重点)数组的初始化。
首先要明白,dp[i][j]是表示搜索到位置(i,j)时的解,而通过比较(取max或min)就可以得出搜索到最后的最优解,在循环中,要保证每一次的结果都被覆盖,就必须使dp[i][j]是一个“不可能”的值,一般来说,根据不同决策,求最小取0,求最大值取inf。
下面是AC代码:
1 #include <iostream> 2 #include <algorithm> 3 #include <cstring> 4 #include <cstdio> 5 6 using namespace std; 7 8 const int inf = 1 << 30; 9 const int maxn = 3005; 10 int a[maxn][maxn]; 11 int dp[maxn][maxn]; 12 13 int main(void) 14 { 15 int n, m; 16 cin >> n >> m; 17 for (int t1 = 1; t1 <= n; ++t1) 18 { 19 for (int t2 = 1; t2 <= m; ++t2) 20 scanf("%d",&a[t1][t2]); 21 } 22 for (int i = 1; i <= n; i++) 23 dp[i][0] = inf; 24 for (int i = 1; i <= m; i++) 25 dp[0][i] = inf; 26 dp[0][0] = inf; 27 for (int i = 1; i <= n; ++i) 28 { 29 for (int j = 1; j <= m; ++j) 30 { 31 if (i == 1 && j == 1) 32 dp[i][j] = a[i][j]; 33 else 34 dp[i][j] = min(dp[i - 1][j] + a[i][j], dp[i][j - 1] + a[i][j]); 35 } 36 } 37 printf("%d\n", dp[n][m]); 38 return 0; 39 }