线性dp P1004 【方格取数】题解

代码比较简单的一题,重在思路(除非写假了)

传送门icon-default.png?t=N7T8https://www.luogu.com.cn/problem/P1004

我的最初思路是两次二维dp,即贪心的取,用pre记录前一个位置,只有80pts,要是是在蓝桥拿分就可以跑路了(bushi)

代码如下

// Problem: 
//     P1004 [NOIP2000 提高组] 方格取数
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1004
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
#include<cstring>
using namespace std;
const int N=10;
int ans=0;
int f[N][N];
int pre[N][N];//记录前一个位置
int val[N][N];int main(){int n;cin>>n;int a,b,c;while(cin>>a>>b>>c){if(a==0&&b==0&&c==0){break;}val[a][b]=c;}for(int i=1;i<=n;++i){for(int j=1;j<=n;++j){f[i][j]=max(f[i-1][j],f[i][j-1])+val[i][j];if(f[i-1][j]>=f[i][j-1]){pre[i][j]=1;//1从上一行来}else{pre[i][j]=2;//2从左边来}}}for(int i=1;i<=n;++i) pre[1][i]=2;for(int i=1;i<=n;++i) pre[i][1]=1;ans+=f[n][n];memset(f,0,sizeof f);int line=n;int rank=n;// for(int i=1;i<=n;++i){// for(int j=1;j<=n;++j){// cout<<val[i][j]<<' ';// }// cout<<endl;// }// cout<<endl;// for(int i=1;i<=n;++i){// for(int j=1;j<=n;++j){// cout<<pre[i][j]<<' ';// }// cout<<endl;// }val[rank][line]=0;while(rank>1||line>1){if(pre[rank][line]==1){rank-=1;}else{line-=1;}val[rank][line]=0;}for(int i=1;i<=n;++i){for(int j=1;j<=n;++j){f[i][j]=max(f[i-1][j],f[i][j-1])+val[i][j];}}// cout<<ans<<endl;ans+=f[n][n];cout<<ans<<endl;return 0;
}

这样子代码的问题在于,这道题两次要同时最优,并不能直接贪心

(或许是可以做的,但是要考虑的复杂情况比较多,本蒟蒻决定跳过)

7
1 3 2
1 4 3
2 3 3
3 3 3
5 5 4
6 5 4
7 3 2
7 5 4
0 0 0

例如这组数据,用上面的代码跑一下就会发现,不使用贪心(每次都取最大)的方法能获得更多的价值,于是,我们可以考虑使用一个四维dp来同时维护两次操作

// Problem: 
//     P1004 [NOIP2000 提高组] 方格取数
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1004
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
#include<cstring>
using namespace std;
const int N=10;
int ans=0;
int f[N][N][N][N];
int val[N][N];int main(){int n;cin>>n;int a,b,c;while(cin>>a>>b>>c){if(a==0&&b==0&&c==0){break;}val[a][b]=c;}for(int i=1;i<=n;++i){for(int j=1;j<=n;++j){for(int k=1;k<=n;++k){for(int l=1;l<=n;++l){f[i][j][k][l]=max(max(f[i-1][j][k-1][l],f[i-1][j][k][l-1]),max(f[i][j-1][k-1][l],f[i][j-1][k][l-1]))+val[i][j]+val[k][l];if(i==k&&j==l) f[i][j][k][l]-=val[i][j];}}}}cout<<f[n][n][n][n]<<endl;return 0;
}

这里的四维也比较好理解,其实就是枚举了两种路线分别经过每一个点的状态,并且放在一起考虑(相等要减掉val[i][j])

另外:写二维的时候还没有明显的感觉,后面发现这不就是深搜变种嘛,洛谷有一题很像

本题数据是N<=9

但是我们有更好的三维优化   三维思路出处

思路:用k来表示x坐标和y坐标的和,然后通过y算出x坐标,创造一个f[k][y1​][y2​]来跑dp

和前面思路大致相同,有转移公式(思路,不是原代码)

f[k][i][j]=max(f[k−1][i][j],f[k−1][i−1][j],f[k−1][i][j−1],f[k−1][i−1][j−1])
+[(i==j)?map[k−i+1][i]:map[k−i+1][i]+map[k−j+1][j]]

其实这个方程不难理解,可以类似于用bfs的扩散来协助理解。枚举的k实际上就是步数,i,j就是枚举该不输的每个点。在这个dp公式中,如果i不动,k-1,那么其实就是行数-1,否则就是列数-1,巧妙的表现了两种情况。

感觉是很熟悉的优化,但是我想不到

代码如下:

// Problem: 
//     P1004 [NOIP2000 提高组] 方格取数
//   
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1004
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)#include<iostream>
#include<cstring>
using namespace std;
const int N=20;//数组最好开大一点,不然会越界(但是洛谷能过就是了)
int ans=0;
int f[N][N][N];
int val[N][N];int main(){int n;cin>>n;int a,b,c;while(cin>>a>>b>>c){if(a==0&&b==0&&c==0){break;}val[a][b]=c;}for(int k=2;k<=n*2;++k){//从2开始,不能从3,因为要考虑(1,1)的情况for(int i=1;i<=min(k-1,n);++i){//k-1  是因为要考虑横坐标至少有1for(int j=1;j<=min(k-1,n);++j){f[k][i][j]=max(max(f[k-1][i-1][j-1],f[k-1][i][j-1]),max(f[k-1][i-1][j],f[k-1][i][j]))+val[k-j][j]+val[k-i][i];if(i==j) f[k][i][j]-=val[k-i][i];//重复就减掉}}}cout<<f[n*2][n][n]<<endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/720841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用reduce递归获取有多层嵌套的数组中的children

常见的多层嵌套的数组&#xff0c;如下 const items [{id: 1,name: "item1",children: [{id: 11,name: "item11",children: [{id: 111, name: "item111"},{id: 112, name: "item112"}]},{id: 12,name: "item12",children:…

MySQL--优化(SQL语句执行慢,如何分析)

MySQL–优化&#xff08;SQL语句执行慢&#xff0c;如何分析&#xff09; 定位慢查询SQL执行计划索引 存储引擎索引底层数据结构聚簇和非聚簇索引索引创建原则索引失效场景 SQL优化经验 一、如何分析 聚合查询&#xff1a; 对于涉及大量数据的聚合操作&#xff0c;如果可能的…

【c++】STL--List的实现

目录 一. List的数据结构 二. List实现的基本框架 1. list的结点结构类 2. List的迭代器类 正向迭代器 反向迭代器 3. List操作接口的实现 1. 默认成员函数 构造函数 和 析构函数 拷贝构造函数 和 赋值运算符重载 2. 修改相关函数接口 insert 和 erase …

thinkphp实现对两个字段或or条件搜索

thinkphp实现对两个字段或or条件搜索 $mD(Adstext);$data[adstext_title]array(like,"%{$keyword}%");$data[id]array(like,"%{$keyword}%");$data[_logic] or; //条件或$arr$m->where($data)->relation(true)->select(); // du…

R语言简介、环境与基础语法及注释

R语言简介、环境与基础语法及注释 一、R语言1.R语言简介2.R语言官网3.R语言中国的镜像网站4.R语言下载5.R语言的历史 二、R语言环境1.Windows安装1.1 去 R 语言下载的镜像站点的列表下载1.2 选择版本进行下载1.3 点击运行1.4 一路默认&#xff0c;安装完毕&#xff01; 2.Linux…

【AI视野·今日Robot 机器人论文速览 第八十期】Fri, 1 Mar 2024

AI视野今日CS.Robotics 机器人学论文速览 Fri, 1 Mar 2024 Totally 32 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers Humanoid Locomotion as Next Token Prediction Authors Ilija Radosavovic, Bike Zhang, Baifeng Shi, Jathushan Rajasegaran…

CCF会议期刊(计算机网络)

中国计算机学会推荐国际学术会议 序号会议简称会议全称分类类型专业领域1SIGCOMMACM International Conference on Applications, Technologies, Architectures, and Protocols for Computer CommunicationA会议计算机网络2MobiComACM International Conference on Mobile Com…

【笔记】MTK与高通平台emergency APN配置差异

协议规定 根据3GPP协议&#xff0c;emergency APN配置需要注意。 3GPPspec TS24.301 6.5.1.2 UE requested PDN connectivity procedure initiation In order to request a PDN connection for emergency bearer services, the UE shall not include an APN in the PDN CONNE…

❤ 前端实现发邮件

❤ 前端实现发邮件 1、Nodejs使用nodemailer发邮件 一、开启发送者邮箱的SMTP服务 QQ邮箱开启SMTP服务教程 163邮箱开启SMTP服务教程 二、安装nodemailer模块 在node项目目录下&#xff0c;使用cmd运行下面命令 npm install nodemailer --savenodemailer官网 https://nod…

ShardingSphere-SQL 解析 Issue 处理流程

ShardingSphere-SQL 解析 Issue 处理流程 这是之前给社区写的 SQL 解析 Issue 的处理流程&#xff0c;可以帮助社区用户快速参与到 ShardingSphere-SQL 解析任务当中。 ShardingSphere SQL 解析 issue 列表 Issue 背景说明 当前 Issue 使用自定义的爬虫脚本从对应的数据库官…

MySQL-----视图

一 视图 ▶ 介绍 视图view是一个虚拟表&#xff0c;非真实存在&#xff0c;其本质是根据SQL语句获取动态的数据集&#xff0c;并为其命名&#xff0c;用户使用时只需使用视图名称即可获取结果集&#xff0c;并可以将其当作表来使用。 数据库中存放了视图的定义&…

Java程序员修炼之道 之 Logging

1. 一个最基本的例子 使用Logging框架写Log基本上就三个步骤 引入loggerg类和logger工厂类 声明logger 记录日志 下面看一个例子 //1. 引入slf4j接口的Logger和LoggerFactory import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class UserService { //…

轻量级Redis慢查询监控脚本

Redis是一款非常强大的内存数据库&#xff0c;可以用于缓存、事务、队列等多种场景。但是在使用Redis的过程中&#xff0c;可能会遇到慢查询的问题。为了提高Redis的性能和响应速度&#xff0c;我们需要了解和处理慢查询。本文将围绕分享Redis慢查询脚本这一主题&#xff0c;讲…

ts快速上手笔记02

第二章&#xff1a;面向对象 面向对象是程序中一个非常重要的思想&#xff0c;它被很多同学理解成了一个比较难&#xff0c;比较深奥的问题&#xff0c;其实不然。面向对象很简单&#xff0c;简而言之就是程序之中所有的操作都需要通过对象来完成。 举例来说&#xff1a; 操作…

C#封装常用的Redis工具类

1.请先安装CSRedisCore 接口&#xff1a; namespace Tools.Redis {public interface IRedisTool{bool SetLongValue(string key, string value);bool SetValue(string key, string value, int outSecond);bool SetValue(string key, string value);bool Exists(string key);b…

揭开ChatGPT的智能对话奥秘——深度剖析其工作原理与关键技术

导语 让我们携手走进一个极具革新性的科技前沿领域&#xff0c;一同揭示能够与人类实现自然流畅对话的ChatGPT背后的运作机制。它犹如一个拥有无尽智慧的对话伙伴&#xff0c;跨越知识边界&#xff0c;回应各种疑问&#xff0c;并能创作出精辟的文章和诗篇。那么&#xff0c;C…

TDengine Schemaless常见问题的原因及故障排除

Tips&#xff1a;使用版本&#xff1a;3.0.2.6 &#xff08;一&#xff09;TDengine ERROR (80003002): Invalid data format 格式化问题&#xff1b;如缺少必要的组成格式&#xff08;时间戳、超级表等&#xff09;&#xff0c;或有字符串未作修饰符修饰&#xff0c;类似的还…

js和css阻塞问题

面试常见问题 css 加载会不会阻塞 js 的加载&#xff1f;&#xff08;不会&#xff09;css 加载会不会阻塞 js 的执行&#xff1f;&#xff08;会&#xff09;css 加载会不会阻塞 DOM 的解析&#xff1f;&#xff08;不会&#xff09;css 加载会不会阻塞 DOM 的渲染&#xff1…

解析Excel数据如虎添翼:Excel数据监听器助你快速解析数据,轻松驾驭业务需求,一键解析,风云再起,数据处理从未如此简单,事半功倍

以下代码是一个Excel数据监听器&#xff0c;用于监听和处理Excel数据的读取事件。它实现了AnalysisEventListener接口&#xff0c;并重写了其中的方法。以下是代码中的主要部分&#xff1a; invokeHead方法&#xff1a;在解析Excel表格的表头时触发的回调方法。通过比较模板表…

企业数字人虚拟形象定制解决方案

随着数字化浪潮的推进&#xff0c;虚拟形象在各个领域都展现出了强大的潜力&#xff0c;美摄科技作为业界领先的数字人虚拟形象定制解决方案提供商&#xff0c;致力于为企业打造独一无二的虚拟形象&#xff0c;助力企业在数字世界中塑造独特的品牌形象。 一、解决方案概览 美…