2014百度之星资格赛 1004:Labyrinth(DP)

Labyrinth


Time Limit: 2000/1000 MS
(Java/Others)    Memory Limit: 32768/32768 K
(Java/Others)
Total Submission(s): 1507    Accepted
Submission(s): 520

Problem Description

度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格,且只能向上向下向右走以前没有走过的格子,每一个格子中都有一些金币(或正或负,有可能遇到强盗拦路抢劫,度度熊身上金币可以为负,需要给强盗写欠条),度度熊刚开始时身上金币数为0,问度度熊走出迷宫时候身上最多有多少金币?

Input

输入的第一行是一个整数T(T <
200),表示共有T组数据。
每组数据的第一行输入两个正整数m,n(m<=100,n<=100)。接下来的m行,每行n个整数,分别代表相应格子中能得到金币的数量,每个整数都大于等于-100且小于等于100。

Output

对于每组数据,首先需要输出单独一行”Case
#?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
每组测试数据输出一行,输出一个整数,代表根据最优的打法,你走到右上角时可以获得的最大金币数目。

Sample Input

2

3 4

1 -1 1 0

2 -2 4 2

3 5 1 -90

2 2

1 1

1 1

Sample Output

Case #1:

18

Case #2:

4


  DP题

  一开始用DFS做的,果断超时。看讨论版才发现需要用DP,当时就蔫了,后来还是查了网上的题解,才明白怎么用DP解这道题,对DP的理解更深了。下面是思路:

  思路:这道题的思路是一列列的确定每一个格子的最大金币数。先确定第一列的最大金币数,因为只能向下走,所以很好求。之后每一列每格的最大金币数可以由前一列求得。

  例如要求dp[i][j](dp[][]的含义是走到这个位置的最大金币数),则从前一列有3种走法到这个格子:

  1、它的左边一个格子,即a[i][j-1],直接向右走一个格子;

  2、a[i][j-1]上面的所有格子,可以先向右走一个格,然后向下一直走到a[i][j]的位置;

  3、a[i][j-1]下面的所有格子,可以先向右走一个格,然后向上一直走到a[i][j]的位置。

  遍历上述所有路径的过程中需要记录一个最大值,最后这个值就是dp[i][j]的值。

  由此可知,确定该位置的每一种路径,需要遍历m次。而你需要确定每一列的每一个格子的dp[][]值,所以这个算法的时间复杂度为O(n*m*m)

  代码

赛后再贴 ^_^

  先贴上超时的DFS代码


 1 #include <iostream>
2 #include <stdio.h>
3 #include <string.h>
4 using namespace std;
5 int Max;
6 int a[110][110];
7 bool isv[110][110];
8 int dx[3] = {1,-1,0};
9 int dy[3] = {0,0,1};
10 int m,n;
11 bool judge(int x,int y)
12 {
13 if(x<1 || x>m || y<1 || y>n)
14 return true;
15 if(isv[x][y])
16 return true;
17 return false;
18 }
19 void dfs(int x,int y,int money)
20 {
21 if(x==1 && y==n){
22 if(money>Max)
23 Max=money;
24 }
25 int i;
26 for(i=0;i<3;i++){
27 int nx = x+dx[i];
28 int ny = y+dy[i];
29 if(judge(nx,ny))
30 continue;
31 //可以走
32 isv[nx][ny] = true;
33 dfs(nx,ny,money+a[nx][ny]);
34 isv[nx][ny] = false;
35 }
36 }
37 int main()
38 {
39 int i,j,Case,T;
40 scanf("%d",&T);
41 for(Case=1;Case<=T;Case++){
42 scanf("%d%d",&m,&n);
43 for(i=1;i<=m;i++)
44 for(j=1;j<=n;j++)
45 scanf("%d",&a[i][j]);
46 printf("Case #%d:\n",Case);
47 Max=0;
48 memset(isv,0,sizeof(isv));
49 isv[1][1] = true;
50 dfs(1,1,a[1][1]);
51 printf("%d\n",Max);
52 }
53 return 0;
54 }

Freecode : www.cnblogs.com/yym2013

时间: 2024-08-08 17:50:08

2014百度之星资格赛 1004:Labyrinth(DP)的相关文章

2014 百度之星 题解 1004 Labyrinth

Problem Description 度度熊是一仅仅喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫仅仅能从矩阵左上角第一个方格開始走,仅仅有走到右上角的第一个格子才算走出迷宫,每一次仅仅能走一格,且仅仅能向上向下向右走曾经没有走过的格子,每个格子中都有一些金币(或正或负,有可能遇到强盗拦路抢劫,度度熊身上金币能够为负,须要给强盗写欠条),度度熊刚開始时身上金币数为0,问度度熊走出迷宫时候身上最多有多少金币? Input 输入的第一行是一个整数T(T < 200),表示共同拥有T组数据

2014百度之星资格赛——Labyrinth

2014百度之星资格赛--Labyrinth Problem Description 度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格,且只能向上向下向右走以前没有走过的格子,每一个格子中都有一些金币(或正或负,有可能遇到强盗拦路抢劫,度度熊身上金币可以为负,需要给强盗写欠条),度度熊刚开始时身上金币数为0,问度度熊走出迷宫时候身上最多有多少金币? Input 输入的第一行是一个整数T(

2014百度之星资格赛题解

比赛链接:点击打开链接 ,,杭电把比赛关了代码都找不到了.. 无责任民科还是mark一下好了.. HDU 4823 Energy Conversion 把式子变换一下发现是一个等比数列,高速幂就可以. #include<stdio.h> #include<iostream> #include<string.h> #include<math.h> using namespace std; #define ll __int64 #define inf 10000

2014百度之星资格赛第四题

Labyrinth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2911    Accepted Submission(s): 1007 Problem Description 度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一

[2014百度之星资格赛]

第一题: Energy Conversion Problem Description 魔法师百小度也有遇到难题的时候-- 现在,百小度正在一个古老的石门面前,石门上有一段古老的魔法文字,读懂这种魔法文字需要耗费大量的能量和大量的脑力. 过了许久,百小度终于读懂魔法文字的含义:石门里面有一个石盘,魔法师需要通过魔法将这个石盘旋转X度,以使上面的刻纹与天相对应,才能打开石门. 但是,旋转石盘需要N点能量值,而为了解读密文,百小度的能量值只剩M点了!破坏石门是不可能的,因为那将需要更多的能量.不过,幸

2014百度之星资格赛——Disk Schedule

2014百度之星资格赛--Disk Schedule Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景. 磁盘有许多轨道,每个轨道有许多扇区,用于存储数据.当我们想在特定扇区来读取数据时,磁头需要跳转到特定的轨道.具体扇区进行读取操作.为了简单,我们假设磁头可以在某个轨道顺时针或逆时针匀速旋转,旋转一周的时间是360个单位时间.磁头也可以随意移动到某个轨道进行

2014百度之星资格赛—— Xor Sum(01字典树)

Xor Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others) Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起

2014百度之星资格赛第一题

Energy Conversion Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 11867    Accepted Submission(s): 2861 Problem Description 魔法师百小度也有遇到难题的时候-- 现在,百小度正在一个古老的石门面前,石门上有一段古老的魔法文字,读懂这种魔法文字需要耗费大量的能量和大

2014百度之星资格赛第二题

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2560    Accepted Submission(s): 366 Problem Description 有很多从磁盘读取数据的需求,包括顺序读取.随机读取.为了提高效率,需要人为安排磁盘读取.然而,在现实中,这种做法很复杂.我们考虑一个相对简单的场景.