pyoj61 双线DP

传纸条(一)

时间限制:2000 ms  |  内存限制:65535 KB

难度:5

描述

小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。

在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。

还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0-1000的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度之和最大。现在,请你帮助小渊和小轩找到这样的两条路径。

输入
第一行输入N(0<N<100)表示待测数据组数。
每组测试数据输入的第一行有2个用空格隔开的整数m和n,表示班里有m行n列(2<=m,n<=50)。 
接下来的m行是一个m*n的矩阵,矩阵中第i行j列的整数表示坐在第i行j列的学生的好心程度(不大于1000)。每行的n个整数之间用空格隔开。
输出
每组测试数据输出共一行,包含一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。 
样例输入
1
3 3
0 3 9
2 8 5
5 7 0
样例输出
34妈蛋,看zzuli那个不会过来的要同时考虑两个人的走动情况同时DP,假设两个人坐标为(i,j).(p.q)直观DP方程:

dp[i][j][p][q]=max(dp[i-1][j][p-1][q],dp[i-1][j][p][q-1],dp[i][j-1][p-1][q],dp[i][j-1][p][q-1])+e[i][j]+e[p][q];

四维必爆无疑,考虑压缩为三维,不难发现类似于在0的个数那道题的发现,在只能往右和下走的情况的下,只能走n+m-2步才能到达

又同时从(1,1)出发,每次都走一步的话,不难得到:i+j==p+q==k,则(k-2)表示当前走了几步

所以我们只要考虑出k和两个坐标的一个维就可以知道另一维的值

所以考虑DP方程:dp[k][x1][x2]=max{dp[k-1][x1][x2],dp[k-1][x1-1][x2],dp[k-1][x1][x2-1],dp[k-1][x1-1][x2-1]}+e[x1][k+2-x1]+e[x2][k+2-x2];

x1,x2分别表示两个点的横坐标,根据k求出纵坐标

代码:

#include<bits/stdc++.h>
using namespace std;
#define Max(a,b,c,d) max(max(a,b),max(c,d))
#define ql(a) memset(a,0,sizeof(a))
#define CIN(a) scanf("%d",&a)
int dp[105][61][61];
int e[61][61];
int main()
{
int x1,y1,x2,y2;
int n,m,i,j,k,t;
//cin>>t;
CIN(t);
while(t--){ql(e),ql(dp);
cin>>n>>m;
for(i=1;i<=n;++i)
for(j=1;j<=m;++j) CIN(e[i][j]);
for(k=1;k<n+m-2;++k)
for(x1=1;x1<=n;++x1)
for(x2=x1+1;x2<=n;++x2)     //红色部分的优化意义:打印出结果不难发现结果成对角线对称,所以不必重复计算
if(x1==x2||k+2-x1<0||k+2-x2<0||k+2-x1>m||k+2-x2>m) continue;
else{
dp[k][x1][x2]=Max(dp[k-1][x1][x2],dp[k-1][x1][x2-1],dp[k-1][x1-1][x2],dp[k-1][x1-1][x2-1])
+e[x1][k+2-x1]+e[x2][k+2-x2];
}
for(k=1;k<n+m-2;k++){
for(i=1;i<=n;++i){
for(j=1;j<=n;++j)
cout<<dp[k][i][j]<<" ";
cout<<endl;
}
cout<<endl;
}
printf("%d\n",max(dp[k-1][n-1][n],dp[k-1][n][n-1]));   //其实不必比较,二者是等价的
}
return 0;
}

之所以会产生对角线成对称结果的原因:
md表达能力太差,举个栗子,假设两条线路L1,L2,

当L1走到(x1,k+2-x1),L2走到(x2,k+2-x2)获得的值与L1走到(x2,k+2-x2),L2走到(x1,k+2-x1)的值实际上是一样的!

想象一下L1,L2走过的一对最佳路线对调之后L1->L2,L2->L1这样不又出现一种结果吗!但是显然这两种结果的值肯定是一样的,所以根据这个去重!

时间: 2024-10-01 07:04:18

pyoj61 双线DP的相关文章

探寻宝藏 --- 双线DP

双线DP , 在郑轻的时候 做过 这种双线DP  ,  这是多维DP 应该是比较简单的  但是那个 时间复杂度的优化 始终看不懂 .  先附上代码吧 , 等看懂了再来 , 补充一下 解释  . #include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<v

nyoj 61——传纸条(一)——————【双线dp】

传纸条(一) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是,他们可以通过传纸条来进行交流.纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n).从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者

nyoj 712 探 寻 宝 藏(双线dp 第六届河南省程序设计大赛)

探 寻 宝 藏 时间限制:1000 ms  |  内存限制:65535 KB 难度:5 描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物就藏在右下角,迷宫的进出口在左上角.当然,迷宫中的通路不是平坦的,到处都是陷阱.Dr.Kong决定让他的机器人卡多去探险. 但机器人卡多从左上角走到右下角时,只会向下走或者向右走.从右下角往回走到左上角时,只会向上走或者向左走,而且卡多不走回头路.(即:一个点最多经过一次).当

双线dp ——牧场物语

牧场物语 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice FZU 2234 Description 小茗同学正在玩牧场物语.该游戏的地图可看成一个边长为n的正方形. 小茗同学突然心血来潮要去砍树,然而,斧头在小茗的右下方. 小茗是个讲究效率的人,所以他会以最短路程走到右下角,然后再返回到左上角.并且在路上都会捡到/踩到一些物品,比如说花朵,钱和大

51nod 1503 多线程dp

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1503 1503 猪和回文 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有n行,m列组成.我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m.处于第r行第c列的格子用(r,c)表示. 刚开始的时候猪站在(1,1),

zzuli 1875多线DP

1875: 蛤玮的财宝 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 530  Solved: 116 SubmitStatusWeb Board Description 蛤玮和他的妹子出海游玩,不小心遭遇了海难,他们醒来之后发现自己到了一座金银岛.岛主非常好心的告诉他们在岛的另一边有船可以送他们回家. 这座岛可以看成n*m的矩阵,蛤玮他们在位置(1,1),而船在位置(n,m).蛤玮发现金银岛遍地都是金子,每个格子里有价值a[i,j]的金子,他和妹

二模 (5) day2

第一题: 有 N 个人顺时针围在一圆桌上开会,他们对身高很敏感. 因此决定想使得任意相邻的两人的身高差距最大值最小. 如果答案不唯一,输出字典序最小的排列,指的是身高的排列.N<=50 解题过程: 1.最大值最小的问题直接想到二分答案..然后就变成判断环的问题,但是想不到什么好的算法,就直接爆搜了..事实证明全部超时.. 2.正解:首先有一个贪心原则:即最高的和最矮的人肯定不会排到一起,然后他们之间的人必定是递增或者递减的(最矮的递增到最高的,然后最高的递减到最矮的),可用交换的方法证明.那么先

NYOJ 61 传纸条(一)

双线DP #include<iostream> #include<algorithm> #include<ctype.h> #include<string> #include<string.h> #include<vector> #include<queue> using namespace std; int dp[110][55][55]; //压缩空间 dp[x1+y1][x1][x2]; //已知x1+y1 .x1和

POJ 2057 The Lost House 经典树形DP+贪心

题意:链接 方法:树形DP+贪心 解析:这是一道好题. 好首先要明确这题求的是什么? 名义上是期望值,而实际上就是找一条路径.什么路径呢?从根节点走遍所有的叶子节点所花费步数最短的路径. 明确了题意后该怎么做呢? 首先看我们需要什么? 目前有个根节点,我们需要知道从他向一个分支走,失败步数是多少,成功步数是多少? 那么怎么维护我们需要的东西呢? 首先我们先给他们起个名:suc,fai; 其次再给一个节点的叶子节点的个数起个名:son 起名完事之后我们就要更新了. 先谈叶子节点,显然叶子节点的su