探寻宝藏(双向DP)
题目描述
传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物。某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物就藏在右下角,迷宫的进出口在左上角。当然,迷宫中的通路不是平坦的,到处都是陷阱。Dr.Kong决定让他的机器人卡多去探险。
但机器人卡多从左上角走到右下角时,只会向下走或者向右走。从右下角往回走到左上角时,只会向上走或者向左走,而且卡多不走回头路。(即:一个点最多经过一次)。当然卡多顺手也拿走沿路的每个宝物。
Dr.Kong希望他的机器人卡多尽量多地带出宝物。请你编写程序,帮助Dr.Kong计算一下,卡多最多能带出多少宝物。
输入
接下来对每组测试数据:
第1行: M N
第2~M+1行: Ai1 Ai2 ……AiN (i=1,…..,m)
【约束条件】
2≤k≤5 1≤M, N≤50 0≤Aij≤100 (i=1,….,M; j=1,…,N)
所有数据都是整数。 数据之间有一个空格。
输出
样例输入
2
2 3
0 10 10
10 10 80
3 3
0 3 9
2 8 5
5 7 100
样例输出
120
134
来源
题解(1): http://www.l-ch.net/26112.html
这道题和以往我们做的dp不同之处就在于 是一去一回
加入只有去 我们可以 用动态规划方程 dp[i][j]=max(dp[i-1][j],dp[i][j-1])+map[i][j].
而这道题去了又回来 我们可以理解为两个人同时从左上角去 不过不走相同的路
如果两个人不走相同的路 那么这两个人必须不在相同的列或者行 又因为 两个人走的步数完全相同
所以我们可以通过一个人走的步数得到另外一个人走的步数
我们可以通过一个四维的数组来保存
于是这个时候的动态规划方程
dp[i][j][k][l]=max(max(dp[i-1][j][k-1][l],dp[i-1][j][k][l-1]),max(dp[i][j-1][k-1][l],dp[i][j-1][k][l-1]))+map[i][j]+map[k][l];#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
#define for0(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define ll long long
#define MOD 1000000007
#define inf 0x3f3f3f3f ll dp[][][];
ll mp[][]; int k,n,m,p,q; int main()
{
int l;
scanf("%d",&k);
while(k--){
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
for(int j=; j<=m; j++)
scanf("%lld",&mp[i][j]);
memset(dp,,sizeof(dp));
dp[][][]=mp[][];
for(int l=; l<n+m; l++)
for(int i=; i<=n ;i++)
for(int j=; j<=n; j++){
p=l-i;
q=l-j;
if(p< || q<) break;
if(p>m || q>m) continue;
if(p==q) continue;
dp[l][i][j]=max(max(dp[l-][i-][j],dp[l-][i-][j-]),max(dp[l-][i][j-],dp[l-][i][j]));
//dp[k][i][j]=max(max(dp[k-1][i-1][j],dp[k-1][i-1][j-1]),max(dp[k-1][i][j-1],dp[k-1][i][j]));
dp[l][i][j]+=mp[i][p]+mp[j][q];
//dp[k][i][j]+=map[i][p]+map[j][q];
}
dp[n+m][n][n]=max(max(dp[m+n-][n-][n],dp[m+n-][n-][n-]),max(dp[n+m-][n][n-],dp[n+m-][n][n]));
printf("%lld\n",dp[n+m][n][n]+mp[n][m]);
} }
探寻宝藏(双向DP)的更多相关文章
- 探寻宝藏 --- 双线DP
双线DP , 在郑轻的时候 做过 这种双线DP , 这是多维DP 应该是比较简单的 但是那个 时间复杂度的优化 始终看不懂 . 先附上代码吧 , 等看懂了再来 , 补充一下 解释 . #in ...
- 「BZOJ1924」「SDOI2010」 所驼门王的宝藏 tarjan + dp(DAG 最长路)
「BZOJ1924」[SDOI2010] 所驼门王的宝藏 tarjan + dp(DAG 最长路) -------------------------------------------------- ...
- nyoj 探寻宝藏
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处 ...
- [NOIP2017]宝藏 子集DP
题面:[NOIP2017]宝藏 题面: 首先我们观察到,如果直接DP,因为每次转移的代价受上一个状态到底选了哪些边的影响,因此无法直接转移. 所以我们考虑分层DP,即每次强制现在加入的点的距离为k(可 ...
- NYOJ-712 探寻宝藏(第六届河南省程序设计大赛)
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫 ...
- [CodeVs3196]黄金宝藏(DP/极大极小搜索)
题目大意:给出n(≤500)个数,两个人轮流取数,每次可以从数列左边或者右边取一个数,直到所有的数被取完,两个人都以最优策略取数,求最后两人所得分数. 显然这种类型的博弈题,第一眼就是极大极小搜索+记 ...
- nyoj 61-传纸条(一)(双向dp)
61-传纸条(一) 内存限制:64MB 时间限制:2000ms Special Judge: No accepted:8 submit:37 题目描述: 小渊和小轩是好朋友也是同班同学,他们在一起总有 ...
- POJ 1836 Alignment (双向DP)
Alignment Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10804 Accepted: 3464 Descri ...
- ny712 探寻宝藏 ny61 传纸条(1)
探 寻 宝 藏 时间限制:1000 ms | 内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处 ...
随机推荐
- fork与vfork详解
一.fork函数 要创建一个进程,最基本的系统调用是fork,系统调用fork用于派生一个进程,函数原型如下: pid_t fork(void) 若成功,父进程中返回子进程ID,子进程中返回0,若出 ...
- Gradle学习系列之一——Gradle快速入门(转)
这是一个关于Gradle的学习系列,其中包含以下文章: Gradle快速入门 创建Task的多种方法 读懂Gradle语法 增量式构建 自定义Property 使用java Plugin 依赖管理 构 ...
- wamp无法登录phpmyadmin问题
文章来源:PHP座谈会 地址:http://bbs.phpthinking.com/forum.php? mod=viewthread&tid=163 第一步.用navicat确认一下,自己的 ...
- iOS缓存类的设计
使用执行速度缓存的程序可以大大提高程序,设计一个简单的缓存类并不需要太复杂的逻辑. 只需要一个简单的3接口. 存款对象 以一个对象 删除对象 阅读对象 watermark/2/text/aHR0cDo ...
- Xamarin.Android 入门实例(2)之实现WCF 寄宿于IIS 的Web服务提供
1.WCF 契约 ICalculator.cs using System.ServiceModel; namespace Contracts { [ServiceContract] public in ...
- 程序猿学英语—In July the English learning summary
七月的英语学习更加曲折,七月初.查看更多,周六和周日可以保证每天两小时的英语教室学习.周一到周 五一般是上完晚自习九点多来机房学习英语,学习一个小时十点多再回宿舍. 考完试,回家待了五天,不好意思的说 ...
- Linux(Centos)中tcpdump参数用法详解(转)
在linux下进行编程开发的人尤其是网络编程的人会经常需要分析数据包,那么一定会用到tcpdump,下面就是关于tcpdump的使用方法说明(1). tcpdump的选项 -a 将网络地址 ...
- C#如何获得 WINDOWS
版本号
using System; using System.Runtime.InteropServices; namespace GetWindowsVersion { [ StructLayout( La ...
- Android - 数据存储 -存储文件
Android使用的文件系统和其他平台的基本磁盘的文件系统很相似.这里将要介绍如何使用File API在Android文件系统中读写文件. File对象适合按顺序读写大量的数据.例如,适合图片文件或者 ...
- OpenCV——Delaunay三角 [转载]
从这个博客转载 http://blog.csdn.net/raby_gyl/article/details/17409717 请其它同学转载时注明原始文章的出处! Delaunay三角剖分是1934年 ...