杭电1078(记忆搜索)

一道记忆搜索题,记忆搜索题就是搜索的形式+DP的思想!

题目:

FatMouse has stored some cheese in a city. The city
can be considered as a square grid of dimension n: each grid location is
labelled (p,q) where 0 <= p < n and 0 <= q < n. At each grid
location Fatmouse has hid between 0 and 100 blocks of cheese in a hole. Now he‘s
going to enjoy his favorite food.

FatMouse begins by standing at location
(0,0). He eats up the cheese where he stands and then runs either horizontally
or vertically to another location. The problem is that there is a super Cat
named Top Killer sitting near his hole, so each time he can run at most k
locations to get into the hole before being caught by Top Killer. What is worse
-- after eating up the cheese at one location, FatMouse gets fatter. So in
order to gain enough energy for his next run, he has to run to a location which
have more blocks of cheese than those that were at the current
hole.

Given n, k, and the number of blocks of cheese at each grid
location, compute the maximum amount of cheese FatMouse can eat before being
unable to move.

Input

There are several test cases. Each test case consists
of

a line containing two integers between 1 and 100: n and k
n
lines, each with n numbers: the first line contains the number of blocks of
cheese at locations (0,0) (0,1) ... (0,n-1); the next line contains the number
of blocks of cheese at locations (1,0), (1,1), ... (1,n-1), and so on.
The
input ends with a pair of -1‘s.

Output

For each test case output in a line the single
integer giving the number of blocks of cheese collected.

Sample Input

3 1

1 2 5

10 11 6

12 12 7

-1 -1

Sample Output

37

思想:

一道记忆搜索题,记忆搜索题就是搜索的形式+DP的思想!

代码:

  超时代码:

  

 1 #include<stdio.h>
2 #include<string.h>
3 //#include<stdlib.h>
4 /*#include<iostream>
5 #include<algorithm>
6 using namespace std;*/
7
8 int getmax(int x, int y){
9 return x > y ? x : y;
10 }
11
12 typedef struct{
13 int x;
14 int y;
15 }List;
16 List list[10001];
17
18 int dir[4][2]={0, -1, -1, 0, 0, 1, 1, 0};
19
20
21 int main(){
22 int n, k, block[101][101], i, j, ii, jj, dp[101][101], max, lastmax, startx, starty, start, num;
23 while(scanf("%d %d", &n, &k) && (n != -1 || k != -1)){
24 max = -1;
25 for(i = 0; i < n; i ++){
26 for(j = 0; j < n; j ++){
27 scanf("%d", &block[i][j]);
28 max = getmax(max, block[i][j]);
29 }
30 }
31 memset(dp, -1, sizeof(dp));
32 dp[0][0] = block[0][0];
33 start = dp[0][0];
34 startx = 0;
35 starty = 0;
36 num = 0;
37 lastmax = dp[0][0];
38 do{
39 for(i = 0; i < 4; i ++){
40 if(block[startx][starty] == max){
41 break;
42 }
43 for(j = 1; j <= k; j ++){
44 ii = startx + dir[i][0] * j;
45 jj = starty + dir[i][1] * j;
46 if(ii < 0 || jj < 0 || ii >= n || jj >= n || block[ii][jj] <= block[startx][starty]){
47 continue;
48 }
49 dp[ii][jj] = getmax(dp[ii][jj], start + block[ii][jj]);
50 lastmax = getmax(dp[ii][jj], lastmax);
51 list[num].x = ii;
52 list[num ++].y = jj;
53 }
54 }
55 if(num == 0){
56 num --;
57 continue;
58 }
59 startx = list[-- num].x;
60 starty = list[num].y;
61 start = dp[startx][starty];
62 }while(num != -1);
63 printf("%d\n", lastmax);
64 }
65 return 0;
66 }

奋进(超时代码)

望大神指点,个人觉得跟下面的正确代码时间复杂度差不多啊!

  正确代码:

  

 1 #include<stdio.h>
2 #include<string.h>
3
4 int map[105][105];
5 int value[105][105];
6 int dir[4][2]={0,1,0,-1,1,0,-1,0};
7 int n,k;
8
9 int dfs(int sx,int sy)
10 {
11 int i,j,x,y,max=0,temp;
12 if(value[sx][sy]!=-1) //该点已经计算过,直接返回值
13 return value[sx][sy];
14 for(i=0;i<4;i++) //2个循环控制该点所能走的地方
15 for(j=1;j<=k;j++)
16 {
17 x=sx+dir[i][0]*j;
18 y=sy+dir[i][1]*j;
19 if(x<0||x>=n||y<0||y>=n||map[x][y]<=map[sx][sy]) //剪枝
20 continue;
21 temp=dfs(x,y);
22 if(temp>max) //max保存由该点所能到达之处能吃到的最大奶酪数
23
24 max=temp;
25 }
26 value[sx][sy]=map[sx][sy]+max; //得到由该点出发所能吃到的最大奶酪数,保存在value里
27 return value[sx][sy];
28 }
29
30 int main()
31 {
32 int i,j;
33 while(scanf("%d%d",&n,&k)!=EOF)
34 {
35 if(n==-1&&k==-1)
36 break;
37 memset(value,-1,sizeof(value)); //初始化数组(不能为0)
38 for(i=0;i<n;i++)
39 for(j=0;j<n;j++)
40 scanf("%d",&map[i][j]);
41 printf("%d\n",dfs(0,0));
42 }
43 return 0;
44 }

网上大神代码

总结:

尽量不要用do....while();

杭电1078(记忆搜索),布布扣,bubuko.com

时间: 2024-10-06 13:53:35

杭电1078(记忆搜索)的相关文章

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY

【转】对于杭电OJ题目的分类

[好像博客园不能直接转载,所以我复制过来了..] 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDI

杭电dp题集,附链接

Robberies 点击打开链接 背包;第一次做的时候把概率当做背包(放大100000倍化为整数):在此范围内最多能抢多少钱  最脑残的是把总的概率以为是抢N家银行的概率之和- 把状态转移方程写成了f[j]=max{f[j],f[j-q[i].v]+q[i].money}(f[j]表示在概率j之下能抢的大洋); 正确的方程是:f[j]=max(f[j],f[j-q[i].money]*q[i].v)  其中,f[j]表示抢j块大洋的最大的逃脱概率,条件是f[j-q[i].money]可达,也就是

杭电 HDU 1164 Eddy&#39;s research I

Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7117    Accepted Submission(s): 4268 Problem Description Eddy's interest is very extensive, recently  he is interested in prime

hdu 1016 Prime Ring Problem DFS解法 纪念我在杭电的第一百题

Prime Ring Problem Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 29577    Accepted Submission(s): 13188 Problem Description A ring is compose of n circles as shown in diagram. Put natural num

一个人的旅行 HDU杭电2066【dijkstra算法】

http://acm.hdu.edu.cn/showproblem.php?pid=2066 Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景--草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女--眼看寒假就快到了,这么一大段时间,可不

杭电1162--Eddy&#39;s picture(Prim()算法)

Eddy's picture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8070    Accepted Submission(s): 4084 Problem Description Eddy begins to like painting pictures recently ,he is sure of himself to b

杭电1276--士兵队列训练问题

士兵队列训练问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4605    Accepted Submission(s): 2148 Problem Description 某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行

杭电1272 并查集找环+判断连通

杭电1272 并查集找环+判断连通 E - E Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1272 Description 上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B