题目描述

小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排坐成一个 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. GPT3:人工智能时代的新型语言模型

    目录 GPT-3:人工智能时代的新型语言模型 随着人工智能技术的不断发展,自然语言处理领域也迎来了新的里程碑.GPT-3 是当前最具代表性的语言模型之一,它具有如下特点: GPT-3 是一种全新的语言 ...

  2. Python 逻辑表达式的妙用

    今天偶然看到有这样一段代码,感到很惊讶: super().__init__(package_name or (robot_name + "_moveit_config")) 语义非 ...

  3. 通信原理知识点总结(XDU网信通原)

    因为感觉第2章和第7章内容特别乱,当时老师讲的时候好像也没有按照一个正确的顺序来讲,所以我就把这两部分的内容按照结构顺序整理了一下,这样更便于理解和记忆 第2章 无线信道传输特性 显示不全点链接看完整 ...

  4. Git无法push提示报错443

    更新 设置代理不能完美解决问题,需要检查本地的SSH配置是否正确,以及正确配置SSH密钥关联github账户 配置SSH参考链接: <GitHub如何配置SSH Key> https:// ...

  5. Word书签替换,加盖电子印章及转换PDF(Java实用版)

    一.前言 在项目中有需要对word进行操作的,可以看看哈,本次使用比较强大的spire组件来对word进行操作,免费版支持三页哦,对于不止三页的word文件,可以购买收费版,官网:https://ww ...

  6. KVM VM 添加 usb 设备

    制作xml文件 参考链接:https://libvirt.org/formatdomain.html#usb-pci-scsi-devices <hostdev mode='subsystem' ...

  7. 安装.NET Framework4.5以上版本受阻怎么办?

    安装和卸载 .NET Framework 受阻疑难解答 - .NET Framework | Microsoft Learn Windows RT 8.1.Windows 8.1 和 Windows ...

  8. 【游戏开发笔记】编程篇_C#面向对象{上}

    @ 目录 1.变量和表达式 1.1注释 1.2C#控制台程序基本结构 1.3变量(从存储长度来看) 1.4变量的命名 1.5字面值 1.6运算符 2流程控制 2.1分支 2.2循环 3变量知识拓展 3 ...

  9. Kitex微服务开发实践(ETCD服务注册)

    服务注册通常用于分布式系统或微服务架构中,是一种用于管理和发现这些分布式服务的机制.它的目标是让服务能够动态地找到其他服务,并能够与其进行通信,而无需显式地配置其位置信息 本文简单讲述使用etcd进行 ...

  10. async、await其实是generator和promise的语法糖

    async 关键字用于声明异步函数,await 用于在async函数中将异步代码变为同步,阻塞代码的执行 对于promise和generator不熟悉的朋友可以移步看看这些文章 Promise的理解与 ...