练习题 Jumping Froggy

完整英文题意:

Froggy lives in a beautiful pond where there are N lotuses numbered from 1 to N in order. When looking down at the pond, it seems like the lotuses are floating at certain (x, y) on the 2-dimensional plane. Froggy wants to jump from the 1st lotus to the Nth lotus. But, he can only jump in a very specific way. He has to meet one of the following conditions to jump from the lotus at (x1, y1) to the lotus at (x2, y2).            x1 < x2 and y1 = y2            x1 = x2 and y1 < y2 A certain number of flies are resting on each lotus. Froggy can regain his strength by eating all the files. Each fly is equal to 1 unit of energy. He consumes K energy to jump from one lotus to another.

Currently, he is at the 1st lotus and wants to go to the Nth lotus. The amount of energy that he has saved should be maximized when arriving at the Nth lotus. Also, the amount of energy shouldn’t go less than 0. At first, he has 0 amount of energy. He will eat flies on the 1st lotus to gain strength and jump to other lotuses. Let’s write a program to help Froggy finding a path to jump.

[Input]

The first line contains T, the number of test cases. For each test case, the first line has two space-separated integers N,K(2≤N≤300,000,1≤K≤1,000). The ith line of the subsequent N lines gives information of the ith lotus as three integers x,y,f(0≤x,y≤100,000,0≤f≤1,000). This represents that there is a lotus at (x, y) with f flies. No two or more lotuses are in the same location. All inputs are guaranteed that there exists a path to jump from the 1st lotus to the Nth lotus.

[Output]

For each test case, on a single line, print “#T”(test case number) and the max value of final energy after arriving at the Nth lotus.

Input Example
1 // T : Number of test case
6 5 // N, K
1 1 5 // x, y, f of 1st lotus
2 3 5
3 2 30
1 2 4
2 1 5
3 3 5

Output Example
#1 5 // Max energy upon arrival

Explanation)
Froggy can jump in the following conditions.
   x1 < x2 and y1 = y2
   x1 = x2 and y1 < y2
He starts at (1, 1), the 1st lotus.
Eat 5 flies at (1, 1) -> Total energy: 5
(1, 1) > (2, 1) Jump -> Total energy: 0 (Consumed energy by K=5)
Eat 5 flies at (2, 1) -> Total energy: 5
(2, 1) > (2, 3) Jump -> Total energy: 0 (Consumed energy by K=5)
Eat 5 flies at (2, 3) -> Total energy: 5
(2, 3) > (3, 3) Jump -> Total energy: 0 (Consumed energy by K=5)
Eat 5 flies at (3, 3) -> Total energy: 5
Arrive.

sample_input下载链接 : https://files.cnblogs.com/files/proscientist/jumping_froggy_input.zip

 

题解:

较难的动态规划题目,dp数组为某一行,某一列的初始能量

遍历时的特征是先遍历行列较小值,所以后面出现的点所找的行列初始值必为之前跳到这一行/列的值

 

  1 /* H59 Jumping Froggy
  2 题意:青蛙跳荷叶,荷叶上有飞虫可以补充f点能量,每跳一次消耗固定能量K。
  3 限制条件是 x1 < x2 and y1 = y2
  4            x1 = x2 and y1 < y2
  5 按顺序输入N个荷叶的信息,求解从1st荷叶跳到nth荷叶上最大剩余能量
  6 */
  7 #include <stdio.h>
  8 #define MAX 100005
  9 #define max(a,b) ((a)>(b)?(a):(b))
 10 int T, N, K, ans, pos, poe;
 11 int ex[MAX], ey[MAX];
 12  
 13 struct Node{
 14     int x, y, f;
 15     bool operator > (const Node b)const{
 16         return this->x + this->y > b.x + b.y;
 17     }
 18     bool operator <= (const Node b)const{
 19         return this->x + this->y <= b.x + b.y;
 20     }
 21     bool operator == (const Node b)const{
 22         if (this->x != b.x)return false;
 23         if (this->y != b.y)return false;
 24         return true;
 25     }
 26 }node[300005], fnode, lnode;
 27  
 28 void quickSort(int first, int last){
 29     int i, j, pivot;
 30     Node temp;
 31     if (first < last){
 32         pivot = first;
 33         i = first;
 34         j = last;
 35         while (i < j){
 36             while (node[i] <= node[pivot] && i < last)++i;
 37             while (node[j] > node[pivot])--j;
 38             if (i < j){
 39                 temp = node[i];
 40                 node[i] = node[j];
 41                 node[j] = temp;
 42             }
 43         }
 44         temp = node[pivot];
 45         node[pivot] = node[j];
 46         node[j] = temp;
 47         quickSort(first, j - 1);
 48         quickSort(j + 1, last);
 49     }
 50 }
 51 /* 用dfs写的代码,注意剪枝条件
 52 void dfs(int x, int y, int val){//val表示上个点的结余
 53     Node * node;
 54     for (int i = x + 1; i <= enx; ++i){
 55         if (m.isNode(i, y)){
 56             node = m.getNode(i, y);
 57             if (val >= K && node->dp < (val - K + node->f)){
 58                 node->dp = val - K + node->f;
 59                 dfs(i, y, node->dp);
 60             }
 61             else break;
 62         }
 63     }
 64     //另一方向同理
 65 }*/
 66 int main(void){
 67     scanf("%d", &T);
 68     for (int tc = 1; tc <= T; ++tc){
 69         for (int i = 0; i < MAX; ++i)
 70             ex[i] = ey[i] = 0;
 71         scanf("%d%d", &N, &K);
 72         for (int i = 0; i < N; ++i)
 73             scanf("%d%d%d", &node[i].x, &node[i].y, &node[i].f);
 74         fnode = node[0], lnode = node[N - 1];
 75  
 76         quickSort(0, N - 1);
 77  
 78         for (pos = 0; pos < N; ++pos)
 79         if (node[pos] == fnode)break;
 80         for (poe = pos; poe < N; ++poe)
 81         if (node[poe] == lnode)break;
 82  
 83         ey[fnode.y] = ex[fnode.x] = fnode.f;
 84  
 85         int x, y, upt;
 86         for (int i = pos + 1; i < poe; ++i){
 87             x = node[i].x, y = node[i].y, upt = -1;
 88             if (ex[x] >= K)
 89                 upt = ex[x] + node[i].f - K;
 90             if (ey[y] >= K)
 91                 upt = max(upt, ey[y] + node[i].f - K);
 92             ex[x] = max(ex[x], upt);
 93             ey[y] = max(ey[y], upt);
 94         }      
 95  
 96         ans = max(ex[lnode.x], ey[lnode.y]) + lnode.f - K;
 97         printf("#%d %d\n", tc, ans);
 98     }
 99     return 0;
100 }

 

posted @ 2017-12-28 16:40  proscientist  阅读(248)  评论(0编辑  收藏  举报