Labyrinth(Dp)2014年百度之星 资格赛
来源:互联网 发布:java编写口令红包 编辑:程序博客网 时间:2024/05/01 02:37
Labyrinth
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 519 Accepted Submission(s): 174
Problem Description
度度熊是一只喜欢探险的熊,一次偶然落进了一个m*n矩阵的迷宫,该迷宫只能从矩阵左上角第一个方格开始走,只有走到右上角的第一个格子才算走出迷宫,每一次只能走一格,且只能向上向下向右走以前没有走过的格子,每一个格子中都有一些金币(或正或负,有可能遇到强盗拦路抢劫, 度度熊身上金币可以为负,需要给强盗写欠条 ),度度熊刚开始时身上金币数为0,问度度熊走出迷宫时候身上最多有多少金币?
输入的第一行是一个整数T(T < 200),表示共有T组数据。 每组数据的第一行输入两个正整数m,n(m<=100,n<=100)。接下来的m行,每行n个整数,分别代表相应格子中能得到金币的数量,每个整数都大于等于-100且小于等于100。
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。 每组测试数据输出一行,输出一个整数,代表根据最优的打法,你走到右上角时可以获得的最大金币数目。
23 41 -1 1 02 -2 4 23 5 1 -902 21 11 1
Case #1:18Case #2:4
------------------------------------------------------------------------------------------------
伤不起,同学告诉我是搜索,我用dfs+dp做了4个小时,答案正确,但一直超时,各种剪枝都试了,也无法ac。
还是对dfs的时间复杂度掌握不牢。
dfs代码如下:
#include<stdio.h>long map[107][107],n,m;int play[3][2]={1,0,0,1,-1,0};struct{ long ans,step; }f[107][107];void dfs(int x,int y){ int i,dx,dy; for(i=0;i<3;i++) { dx=x+play[i][0]; dy=y+play[i][1]; if(dx>0 && dy>0 && dx<=m && dy<=n && f[x][y].ans+map[dx][dy]>f[dx][dy].ans && f[dx][dy].step>=f[x][y].step) { f[dx][dy].ans=f[x][y].ans+map[dx][dy]; f[dx][dy].step=f[x][y].step+1; dfs(dx,dy); } }}main(){ int t; while(scanf("%d",&t)!=EOF) { int hi=1; while(t--) { int i,j,a,b; scanf("%d %d",&m,&n); for(i=1;i<=m;i++) for(j=1;j<=n;j++) {scanf("%d",&map[i][j]);f[i][j].ans=-101;f[i][j].step=9999999;} f[1][1].ans=map[1][1]; f[1][1].step=0; dfs(1,1); printf("Case #%d:\n",hi++); printf("%ld\n",f[1][n].ans); } }}
冷静一下,其实100的迷宫不算大,也没有复杂的元素干扰,是不是考虑贪心?
尝试贪心模拟测试数据,发现可以用dp。每一格的金钱数,必然从3个状态转移而来。
举例:
1 -1 1 0
2 -2 4 2
3 5 1 -90
dp[i][j]代表了地图上坐标为i,j的最多金钱数,那么dp矩阵的第一列必然是136
因为第一列只能自上而下的移动。如果只考虑向右移动,第二列可能是0 1 11 对于这一列,有可能还存在往上或者往下移动的可能,那么我就把所有可能全列举出来,并取最大值。注意防止回头走重复的路陷入死循环,程序里我用了一个变量tmp来防止走回来。
题目先输入m再输入n着实烦,我还是改回来了。ac代码:
#include<stdio.h>int map[107][107],n,m,dp[107][107];int max(int a,int b){ if(a>b)return a; else return b;}void DP(int c){ for(int i=1;i<=n;i++)//自上而下 { int tmp=dp[i][c-1]+map[i][c];// tmp是用来记录从左边来的值 dp[i][c]=max(dp[i][c],tmp); for(int j=i+1;j<=n;j++) { tmp=tmp+map[j][c]; dp[j][c]=max(dp[j][c],tmp); } } for(int i=n;i>=1;i--)//自下而上 { int tmp=dp[i][c-1]+map[i][c]; dp[i][c]=max(dp[i][c],tmp); for(int j=i-1;j>=1;j--) { tmp=tmp+map[j][c]; dp[j][c]=max(dp[j][c],tmp); } }}main(){ int t; while(scanf("%d",&t)!=EOF) { int hi=1; while(t--) { int i,j,a,b; scanf("%d %d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=m;j++) {scanf("%d",&map[i][j]);dp[i][j]=-999999;} dp[1][1]=map[1][1]; //初始化第一列 for(i=2;i<=n;i++) dp[i][1]=dp[i-1][1]+map[i][1]; for(i=2;i<=m;i++) DP(i); printf("Case #%d:\n",hi++); printf("%d\n",dp[1][m]); } }}
- Labyrinth(Dp)2014年百度之星 资格赛
- 2014年百度之星程序设计大赛 - 资格赛 1004 Labyrinth(Dp)
- 2014年百度之星程序设计大赛 - 资格赛 1004 Labyrinth(Dp)
- 2014百度之星资格赛——1004 Labyrinth(dp)
- 2014 百度之星 资格赛 Labyrinth
- 2014年百度之星资格赛第四题Labyrinth
- 2014年百度之星程序设计大赛 - 资格赛 Labyrinth
- 2014百度之星资格赛解题报告:Labyrinth
- 2014百度之星资格赛——Labyrinth
- 2014百度之星资格赛1004 度度熊走迷宫 Labyrinth
- 百度之星资格赛 1004 Labyrinth
- 2014年百度之星程序设计大赛 - 资格赛 第四题 Labyrinth
- 2014年百度之星程序设计大赛 - 资格赛 第四题 Labyrinth
- ACM-百度之星资格赛之Labyrinth——hdu4826
- 百度之星资格赛 hdu 4826 Labyrinth 动态规划
- 2014百度之星第四题Labyrinth(DP)
- 2015年百度之星资格赛 A dp
- 2014年百度之星资格赛(解题报告)
- android源码下载
- Windows8.1无法验证安装密钥请检查你的安装介质
- 在“解决方案管理器”中添加引用时找不到System.Web.Dll
- C#读取Excel文件并用datagridview显示
- Html中DIV层叠与悬浮
- Labyrinth(Dp)2014年百度之星 资格赛
- UltraEdit编辑HTML中文乱码 -解决方案
- 用Spotlight实时监控WindowsServer2008
- 没意思
- python学习
- Hdu-1565 方格取数(1) (状态压缩dp入门题
- Qt中QEvent的过滤和分发
- 数据库设计问题
- 安装mysql时的error 0错误