题目描述

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

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

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

输入格式

第一行有两个用空格隔开的整数 mm 和 nn,表示班里有 mm 行 nn 列。

接下来的 mm 行是一个 m×nm×n 的矩阵,矩阵中第 ii 行 jj 列的整数表示坐在第 ii 行 jj 列的学生的好心程度。每行的 nn 个整数之间用空格隔开。

输出格式

输出文件共一行一个整数,表示来回两条路上参与传递纸条的学生的好心程度之和的最大值。

题面是直接复制 的,有点炸,但是没关系(反正不会有人到位这里来看题面

我觉得这题的难点在于同时要找到两条路径,并且不能交叉,这个在dp里面是比较难进行限制和定义的
还有就是这种dp类型对我可能是第一次,比较陌生。
这个最简单的状态设计我都是看别人的。。。
设f[i][j][k][l]表示一条路径走到了[i][j],另一条走到了[k][l]时,最大的好感度之和
转移比较明显,就从前面的点转移过来就好了,但是转移的时候要保证不会走到两个重合的点,这样就保证了两个路径不相交。

时间复杂的O(n^4),n最大50,可以接受。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read() {
char c=getchar();int a=0,b=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
int f[51][51][51][51],n,m,a[51][51];
int main()
{
n=read();m=read();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
a[i][j]=read();
}
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<=m;j++)
{
for(int k=0;k<=n;k++)
{
for(int h=0;h<=m;h++)
{
if(i==0||j==0||k==0||h==0)
f[i][j][k][h]=-1145141919;
else
f[i][j][k][h]=0;
}
}
}
}
f[1][1][1][1]=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
for(int k=1;k<=n;k++)
{
for(int h=1;h<=m;h++)
{
if((i==k&&j==h))
continue;
f[i][j][k][h]=max(f[i][j][k][h],f[i-1][j][k-1][h]+a[i][j]+a[k][h]);
f[i][j][k][h]=max(f[i][j][k][h],f[i-1][j][k][h-1]+a[i][j]+a[k][h]);
f[i][j][k][h]=max(f[i][j][k][h],f[i][j-1][k-1][h]+a[i][j]+a[k][h]);
f[i][j][k][h]=max(f[i][j][k][h],f[i][j-1][k][h-1]+a[i][j]+a[k][h]);
}
}
}
}
cout<<max(f[n-1][m][n-1][m],max(f[n-1][m][n][m-1],max(f[n][m-1][n-1][m],f[n][m-1][n][m-1])))<<endl;
return 0;
}

很奇怪,如果我尝试把结果直接转移到f[n][m][n][m]上然后输出,就会错,目前认为是我上面转移边界判断写错了
懒得找了

可以发现,其实这个4维数组里面是大部分用不上的,意思就是,我们浪费了非常多的空间和时间复杂度给了不可能的情况,因为我们每一次都是两边走一步
所以很容易可以发现,类似f[1][1][n][m]这样的状态是不可能也不存在也无意义的,但是它们的存在占用了大量转移的时间和空间
可以考虑优化考虑这一类无意义转移的特征
我们的转移都是一次性走两步的,很明显,这样的情况才是我们真正要的。
我们一次走一步,其实走的总步数就是曼哈顿距离,很明显,两条路的走的步数是一样的。
所以当两边同时走的时候,需要我们转移的地方很明显是没有那么多的,只有步数一样的两个点的状态,我们的转移才是有意义的,否则这个计算其实是没有任何作用的。
所以,我们可以增加一个状态,步数i,另外两个状态就是两个路径的竖直位置。
因为我们每次总是向下和向右走,所以通过步数和竖直位置可以直接计算出来它的水平距离。
这样那些多余的计算和空间就被优化掉了。

代码我懒得写了,主要是这个思考的方法
首先,这个优化依旧是从这个问题的特质出发的,我们发现了两边的步数i是一样的
(应该是我一开始就看的是别人的题解的原因,我感觉如果让我来设计状态,我不会这么暴力)
所以没有其次了(因为我感觉没必要)

然后就是这个问题的一个转化
我们把回传的问题转化为了从上往下的第二条路径。
这个是十分重要的,如果是先找到第一条,再去找第二条,时间复杂度会直接爆炸,而且不可做。
所以这个特性其实非常重要和有用的,因为正着麻烦,那就反着来,正难则反
而且利用这个,其实也是把不可相交这个要求的处理给简化, 一举两得,十分巧妙。。。

这应该就算是一道好题吧,比较的灵活

如果我比赛的时候遇到这个,我肯定是写不出来的

要怎么才能写出来呢?

1.发现这个特征,就是从下往上和从上往下是没有区别的

2.转化问题,把问题转化为找两个一起往下的路径(这个我想不到)

后面就比较简单了,我觉得这种转化其实也是dp的一个难点
只能靠积累了吧。。。
多积累,应该会在一定程度质变的。

加油

传纸条 luoguP1006的更多相关文章

  1. luoguP1006 传纸条

    题目描述 Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个 m" role="presentation& ...

  2. tyvj1011 传纸条

    背景 NOIP2008复赛提高组第三题 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端, ...

  3. NOIP2008 传纸条

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...

  4. NOIP2008传纸条[DP]

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...

  5. NOIP2008 T3 传纸条 解题报告——S.B.S.

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...

  6. [NOIP2008] 提高组 洛谷P1006 传纸条

    题目描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸运的是 ...

  7. TYVJ 1011 NOIP 2008&&NOIP 2000 传纸条&&方格取数 Label:多线程dp

    做题记录:2016-08-15 15:47:07 背景 NOIP2008复赛提高组第三题 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行 ...

  8. nyoj 61 传纸条

    点击打开链接 传纸条(一) 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做 ...

  9. P1011 传纸条//dp优化改进状态表示

    P1011 传纸条 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 NOIP2008复赛提高组第三题 描述 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不 ...

  10. Wikioi 1169 传纸条

    这道题是我人生第一道双线动规题,因此我觉得还是很有必要记录下来. 刚接触到这道题的时候我第一反应是单线的动规,可是下一秒我就觉得这样做可能会有问题,因为从左上角(以下简称A)到右下角(以下简称B)通过 ...

随机推荐

  1. Linux系统运维之Web服务器Nginx安装

    一.介绍 Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like 协议下发行.本文先整理web服务器内容. 二.环境及软件版本 操作 ...

  2. Matlab学习1

    Matlab 数据类型 数字 字符和字符串 矩阵 元胞数组 结构体 清空环境变量及命令 cls % 清除Command Windows中的所有命令 clear all % 清除Workspace*中的 ...

  3. SQL ERVER 表转化为C#实体(SQL 代码)

    本文推出SqlServer表转化为实体的sql代码 在VS中有可以自带生成实体类的快捷操作,但是生成的代码比较杂乱,很多东西都是不需要的,一个一个去敲又很浪费时间,关键太无聊了 在闲暇之余写一份代码供 ...

  4. 基于ChatGPT上线《你说我猜》小游戏

    摘要 AIGC.GPT.休闲小游戏三者可以怎么结合? AIGC.GPT与小游戏的结合为游戏体验带来了新的可能性.AIGC(Artificial Intelligence Game Content)作为 ...

  5. MAUI Blazor 显示本地图片的新思路

    前言 好久没写文章了,水一篇 关于MAUI Blazor 显示本地图片这个问题,有大佬发过了. 就是 token 大佬的那篇 Blazor Hybrid (Blazor混合开发)更好的读取本地图片 主 ...

  6. 数据库是要拿来用的,不是用来PK先进性的

    周五参加了WAIC后又和一家上海本地的数据库厂商交流了一下午.等我要买高铁票回南京的时候已经买不到票了.好不容易刷到一张到苏州北的高铁票,我就上了车.上车后突然想起还不如就回苏州老家住一晚算了.到家后 ...

  7. Git练习网址

    爲了方便学习git指令,让新手们更容易地理解,所以推荐一些git练习和博文网址 推荐的网址如下 网址一:Learn Git Branching! https://learngitbranching.j ...

  8. QTextEdit的使用

    import sys from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit,QVBoxLayout, QPushButton cla ...

  9. 建设数字工厂:MRP物料需求计划的逻辑原理与配置方法

    本文分享自华为云社区<数字工厂深入浅出系列(七): MRP物料需求计划的逻辑原理与配置方法>,作者:云起MAE. MRP是生产制造企业"管好"物料的核心工具方法,基本思 ...

  10. Oracle内存管理方式介绍(转载)

    "Oracle内存管理可分为两大类,自动内存管理和手动内存管理.其中手动内存管理又可分为自动共享内存管理,手动共享内存管理,自动PGA内存管理以及手动PGA内存管理.本文会简单的介绍不同的内 ...