[Swust OJ 1132]-Coin-collecting by robot

本文探讨了如何使用反向动态规划解决在限定路径上的硬币收集问题。通过实例展示了一种从终点到起点的策略,以及如何通过优化空间复杂度来解决此类问题。提供了一个具体代码实现,帮助理解算法的执行流程。
 
 
 
Time limit(ms): 1000    Memory limit(kb): 65535
Several coins are placed in cells of an n×m board. A robot, located in the upper left cell of the board, needs to collect as many of the coins as possible and bring them to the bottom right cell. On each step, the robot can move either one cell to the right or one cell down from its current location. 
Description
The fist line is n,m, which 1< = n,m <= 1000. 
Then, have n row and m col, which has a coin in cell, the cell number is 1, otherwise is 0.
Input
The max number Coin-collecting by robot. 
Output
1
2
3
4
5
6
7
5 6
0 0 0 0 1 0
0 1 0 1 0 0
0 0 0 1 0 1
0 0 1 0 0 1
1 0 0 0 1 0
 
Sample Input
1
2
5
 
Sample Output
Hint
algorithm text book
 
题目大意:就是给出一个方阵nXm,每个格子1代表有硬币,0代表没有,问从左上角,到右下角(每次只能向下和向右移动)最多能收集多少硬币
 
思路其实也挺简单的就是一个从终点到起点的反向dp,每次只能每次只能向下和向右移动(注意dp是反向进行的)
于是得到了一个dp方程dp[i][j] += max(dp[i + 1][j] , dp[i][j + 1] )  注:这里为了降低空间复杂度直接用dp数据存贮的矩阵
 
代码如下
 1 #include <stdio.h>
 2 int rows, dp[1001][1001];
 3 int main()
 4 {
 5     int i, j, n, m;
 6     scanf("%d%d", &n, &m);
 7     for (i = 0; i < n; i++)
 8     for (j = 0; j < m; j++)
 9         scanf("%d", &dp[i][j]);
10     for (i = n - 1; i >= 0; i--)
11     for (j = m - 1; j >= 0; j--)
12         dp[i][j] += dp[i + 1][j] > dp[i][j + 1] ? dp[i + 1][j] : dp[i][j + 1];
13     printf("%d\r\n", dp[0][0]);
14     return 0;
15 }
View Code

 

其实最开始并没有想到dp(还是题做的少,没这个概念),直接两个方位的bfs+优先队列

感觉应该是对的,为啥就是wa 呢?贴出代码,求大神指教

 1 #include <iostream>
 2 #include <queue>
 3 #include <algorithm>
 4 using namespace std;
 5 int map[1001][1001], vis[1001][1001], dir[][2] = { 1, 0, 0, 1 };
 6 int n, m;
 7 struct node{
 8     int x, y, cur;
 9     friend bool operator<(node x, node y){
10         return x.cur < y.cur;
11     }
12 };
13 int bfs(){
14     priority_queue<node>Q;
15     struct node now, next;
16     now.x = now.y = 1, now.cur = map[1][1];
17     vis[1][1] = 1;
18     Q.push(now);
19     while (!Q.empty()){
20         now = Q.top();
21         Q.pop();
22         if (now.x == n&&now.y == m)
23             return now.cur;
24         for (int i = 0; i < 2; i++){
25             next.x = now.x + dir[i][0];
26             next.y = now.y + dir[i][1];
27             if (next.x >= 1 && next.x <= n && next.y >= 1 && next.y <= m &&!vis[next.x][next.y]){
28                 next.cur = now.cur + map[next.x][next.y];
29                 vis[next.x][next.y] = 1;
30                 Q.push(next);
31             }
32         }
33     }
34 }
35 int main(){
36     cin >> n >> m;
37     for (int i = 1; i <= n; i++)
38     for (int j = 1; j <= m; j++)
39         cin >> map[i][j];
40     cout << bfs() << "\r\n";
41     return 0;
42 }
View Code

 

转载于:https://www.cnblogs.com/zyxStar/p/4541030.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值