P1006 传纸条[棋盘DP]
题目来源:洛谷
题目描述
小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。
在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。
还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0−100的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这2条路径上同学的好心程度之和最大。现在,请你帮助小渊和小轩找到这样的2条路径。
输入输出格式
输入格式:
输入文件,第一行有2个用空格隔开的整数m和n,表示班里有m行n列。
接下来的m行是一个m×n的矩阵,矩阵中第i行j列的整数表示坐在第i行j列的学生的好心程度。每行的n个整数之间用空格隔开。
输出格式:
输出文件共一行,包含一个整数,表示来回2条路上参与传递纸条的学生的好心程度之和的最大值。
输入输出样例
- 3 3
- 0 3 9
- 2 8 5
- 5 7 0
- 34
说明
【限制】
30%的数据满足:1≤m,n≤10
100%的数据满足:1≤m,n≤50
NOIP 2008提高组第三题
解析:
非常经典的一道棋盘dp,值得一写。
如果我们分两次dp的话,未免有些麻烦,反正纸条都是在(1,1)~(m,n)之间流动,我们可以假设两张纸条都是从(1,1)流出的,并且每次移动的步数相同。这与原始情况没有什么太大的区别,二者是等价的。
首先,我们需要知道,棋盘dp问题有一个特点:
假设纸条当前走的步数为i,走到的位置为(x,y),我们就有x+y=i+1(假设初始时为步数为1,而不是0),手模一下就出来了,就不给出证明了,反正也就是个归纳法的事儿。
然后我们需要寻找并定义状态和决策,显而易见纸条当前传的步数可以当作阶段,而当前状态就是两张纸条的所在位置,决策就是上一步从哪里走来(下一步走到哪去也是一样的),我们不妨定义dp[i][x1][x2]表示两张纸条在走第i步时,第一张纸条处于x1行,(i-x1+1)列,第二张纸条处于x2行,(i-x2+1)列。
根据题意,我们可以向右、向下走,由于有两个纸条,于是我们有四种可能的决策:
dp[i][x1][x2]=max(dp[i-1][x1][x2],dp[i-1][x1-1][x2],dp[i-1][x1][x2-1],dp[i-1][x1-1][x2-1]);
然后我们要累加两张纸条当前得到的好心程度。
注意题目有一个细节,每个同学只帮一次。所以如果当前状态涉及到同一个同学(纸条传到同一个同学那里),那我们就只能把最优解加一个次,而不是两次:
dp[i][x1][x2]+=a[x1][y1]+a[x2][y2],(x1!=x2);
dp[i][x1][x2]+=a[x1][y1],(x1==x2);
你可能要问为啥只比较行是否相等呢?因为列是从行计算出来的,它们是绝对相等的。。。你可以试一下,加不加这个条件无所谓。
最后答案就在dp[n+m-1][m][m]里(应该能理解吧?)。
参考代码:
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<cmath>
- #include<algorithm>
- #include<string>
- #include<cstdlib>
- #include<queue>
- #include<vector>
- #define INF 0x3f3f3f3f
- #define PI acos(-1.0)
- #define N 51
- #define MOD 2520
- #define E 1e-12
- using namespace std;
- int a[N][N],dp[][][];
- int main()
- {
- int n,m;
- scanf("%d%d",&m,&n);
- for(int i=;i<=m;i++)
- for(int j=;j<=n;j++) scanf("%d",&a[i][j]);
- dp[][][]=a[][];
- for(int i=;i<=n+m-;i++){
- for(int x1=;x1<=min(m,i);x1++)
- for(int x2=;x2<=min(m,i);x2++){
- int y1=i+-x1,y2=i+-x2;
- dp[i][x1][x2]=max(max(dp[i-][x1][x2],dp[i-][x1-][x2]),max(dp[i-][x1][x2-],dp[i-][x1-][x2-]));
- if(x1==x2&&y1==y2) dp[i][x1][x2]+=a[x1][y1];
- else dp[i][x1][x2]+=a[x1][y1]+a[x2][y2];
- }
- }
- cout<<dp[n+m-][m][m]<<endl;
- return ;
- }
P1006 传纸条[棋盘DP]的更多相关文章
- [Luogu P1006]传纸条 (网格DP)
题面 传送门:https://www.luogu.org/problemnew/show/P1006 Solution 挺显然但需要一定理解的网络(应该是那么叫吧)DP 首先有一个显然但重要的结论要发 ...
- 洛谷P1006 传纸条【dp】
题目:https://www.luogu.org/problemnew/show/P1006 题意: 给定一个m*n的矩阵,从(1,1)向下或向右走到(m,n)之后向上或向左走回(1,1),要求路径中 ...
- 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏
P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...
- P1006 传纸条(二维、三维dp)
P1006 传纸条 输入输出样例 输入 #1 复制 3 3 0 3 9 2 8 5 5 7 0 输出 #1 复制 34 说明/提示 [限制] 对于 30% 的数据,1≤m,n≤10: 对于 100% ...
- 【洛谷】【动态规划(多维)】P1006 传纸条
[题目描述:] 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸 ...
- 洛谷 P1006 传纸条 题解
P1006 传纸条 题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法 ...
- P1006 传纸条 (方格取数dp)
题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个mm行nn列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运 ...
- 洛谷 P1006 传纸条 多维DP
传纸条详解: 蒟蒻最近接到了练习DP的通知,于是跑来试炼场看看:发现有点难(毕竟是蒟蒻吗)便去翻了翻题解,可怎么都看不懂.为什么呢?蒟蒻发现题解里都非常详细的讲了转移方程,讲了降维优化,但这题新颖之处 ...
- P1006 传纸条 多维DP
题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个mm行nn列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运 ...
随机推荐
- 微服务之Polly熔断策略
NET Core 微服务之Polly熔断策略 紧接着上一篇说,咱们继续介绍Polly这个类库 熔断策略(Circuit-breaker) 如果调用某个目标服务出现过多超时.异常等情况,可以采取一定时间 ...
- XMemcached的基本使用
XMemcached是memcached的一个java客户端,基于java nio,支持memcached的所有协议.本文简要介绍XMemcached的基本使用. 一.添加依赖 <depende ...
- cocos creator 判断滑动方向
定义变量 public firstX = null; public firsty = null; 点击 获取坐标 this.viewNode.on(cc.Node.EventType.TOUCH_ST ...
- java--带参方法 递归阶乘
package com.test.day01; // public class TestParam { public void f1(int n){ n =0; } public static voi ...
- 开始使用 git(配置+常用命令)
▶ 注意 页面显示问题: -- 是两个短横线 - 是一个横短线 由于显示问题导致两个短横线之间没有空格,看起来像是一条横线,实则是两条短横线 ▶ git 常用命令 ◆ git add ● git ad ...
- GBDT笔记
GBDT笔记 GBDT是Boosting算法的一种,谈起提升算法我们熟悉的是Adaboost,它和AdaBoost算法不同: 区别如下: AdaBoost算法是利用前一轮的弱学习器的误差来更新样本权重 ...
- SAS学习笔记4 基本运算语句(lag、retain、_n_函数)
lag:返回的是上一次lag函数运行时的实参,即lag(argument)=上一次lag函数执行时的argument retain:对变量进行值的初始化和保留到下一个迭代步 _n_:data步的自动变 ...
- oracle 、mysql 取昨天 前天 本周 数据
查询今天数据: SELECT COUNT(1) FROM T_CALL_RECORDS WHERE TO_CHAR(T_RKSJ,'YYYY-MM-DD')=TO_CHAR(SYSDATE,'YYYY ...
- MogileFS安装
MogileFS是一款开源的.高性能的.分布式的文件系统,用于组建分布式文件集群.用来存取海量文件,而不用关心具体的文件存放位置.存储容量大小,以及文件损坏和丢失等问题 MogileFS有三大部分:存 ...
- Sharding-Jdbc 插件应用
Sharding-Jdbc介绍 Sharding-Jdbc在3.0后改名为Shardingsphere它由Sharding-JDBC.Sharding-Proxy和Sharding-Sidecar(计 ...