P1070道路游戏题解
日常吐槽
作为hin久hin久以前考试考到过的一道题窝一直咕咕咕到现在才想起来去做因为讲解都忘干净了然后自己重新考虑发现被卡了3天
题面



看到题目发现这题的dp状态似乎有点不是很明确?
我们来理一理题目的限制以及我们要干什么。
每条路上出现的金币数量受时间和地点的限制。所以我们至少要用到一个二维的东西。
题目中说当机器人消失的时候需要在任意一个工厂购买机器人。我们先以可能TLE的思路进行dp。设\(dp[i][j]\)表示在\(i\)时刻到达工厂\(j\)的最大值。我们要枚举从哪个点走到了\(j\)点,同时因为购买地点的选取是任意的,所以要加上\(max\{ f[i-k][j]\),那么\(dp[i][j]=max\{max\{ f[i-k][j] \},gold(d,j,i-k,i)-cst[d]\}\),其中\(gold(d,j,i-k,i)\)表示在\(i-k\)时刻一直到\(i\)时刻,从\(d\)点走到\(j\)点路上的所有金币。但这个肯定是会\(T\)的,我们发现地点这一维是最耗复杂度的(它整整占用了两层\(for\)),于是果断删掉。
于是我们设\(dp[i]\)表示\(i\)时刻的最大收益,但是去掉地点这一维了,上面的\(gold\)就必须预处理。
设\(sum[i][j]\)表示在时刻\(i\),从0时刻的第1个工厂走到了第\(j\)个工厂的能捡到的金币,即不扣除买机器人的钱(在哪里买机器人是\(dp\)中要干的事,这里只是预处理)。在这里设\(money[i][j]\)表示时刻\(j\),第\(i\)条路上出现的金币数量。那么\(sum[i][j]=sum[i-1][jian(j,1)]+money[jian(j,1)][i]\)。其中\(jian(i,j)\)表示\(j\)工厂往前走\(i\)步到达的工厂。
辣么转移方程也就呼之欲出了。\(dp[i]=max\{ dp[i-j]+sum[i][k]-sum[i-j][jian(k,j)]-cst[jian(k,j)]\}\),\(cst[i]\)表示在第\(i\)个工厂购买机器人花的钱。
代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<ctime>
#include<cstdlib>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef __int128 i128;
const int inf=2147483647;
inline int read()
{
char ch=getchar();
int x=0;
bool f=0;
while(ch<'0'||ch>'9')
{
if(ch=='-') f=1;
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return f?-x:x;
}
int n,m,p,mon[1009][1009],cst[1009];
int dp[1009],sum[1009][1009];
inline int jian(int i,int k)
{
int qwq=(i-k+n)%n;
return qwq?qwq:n;
}
int main()
{
freopen("1.in","r",stdin);
n=read();m=read();p=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
mon[i][j]=read();//money在这里简写为mon
for(int i=1;i<=n;i++)
cst[i]=read();
for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
sum[i][j]=sum[i-1][jian(j,1)]+mon[jian(j,1)][i];//,printf("sum[%d][%d]=%d\n",i,j,sum[i][j]);
memset(dp,-0x3f,sizeof(dp));
dp[0]=0;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=p;j++)//枚举步数
{
for(int k=1;k<=n;k++)//枚举地点
if(i-j>=0)
dp[i]=max(dp[i],dp[i-j]+sum[i][k]-sum[i-j][jian(k,j)]-cst[jian(k,j)]);
}
}
printf("%d",dp[m]);
}
我们发现上面的方程需要枚举地点,它是个三维的,会\(TLE\)(当然因为现在机子跑的快是可以卡过的),我们要想办法优化。
时间肯定是不能省略的,那剩下的就是步数和地点。我们肯定要把一维优化掉。思考哪个看起来更好搞一些。地图是个环,看起来很麻烦的亚子,所以我们把步数优化掉。
把方程中不需要枚举步数的项提出来:
\(dp[i]=max\{dp[i-j]-sum[i-j][jian(k,j)]-cst[jian(k,j)]\}+sum[i][k]\)
由于步数是要被优化掉的,所以我们保留时间和地点两个状态,设置辅助变量\(qwq[i][j]=dp[i]-sum[i][j]-cst[j]\)
新的方程:\(dp[i]=max\{qwq[i-k][j-k]\}+sum[i][j]\),其中k枚举步数,我们要优化掉这一维,发现第二维每次枚举的时候会+1,于是可以各种乱搞
由于博主用不优化的代码卡过了所以优化代码先咕咕咕叭
(逃)(害怕被打.jpg) 跟我读:可持久化咕咕咕
P1070道路游戏题解的更多相关文章
- 洛谷 P1070 道路游戏 解题报告
P1070 道路游戏 题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有\(n\)个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依 ...
- 洛谷P1070 道路游戏
P1070 道路游戏 题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将 ...
- 洛谷 P1070 道路游戏 DP
P1070 道路游戏 题意: 有一个环,环上有n个工厂,每个工厂可以生产价格为x的零钱收割机器人,每个机器人在购买后可以沿着环最多走p条边,一秒走一条,每条边不同时间上出现的金币是不同的,问如何安排购 ...
- [luogu]P1070 道路游戏[DP]
[luogu]P1070 道路游戏 题目描述小新正在玩一个简单的电脑游戏.游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针 ...
- 【题解】洛谷P1070 道路游戏(线性DP)
次元传送门:洛谷P1070 思路 一开始以为要用什么玄学优化 没想到O3就可以过了 我们只需要设f[i]为到时间i时的最多金币 需要倒着推回去 即当前值可以从某个点来 那么状态转移方程为: f[i]= ...
- 洛谷P1070 道路游戏(dp+优先队列优化)
题目链接:传送门 题目大意: 有N条相连的环形道路.在1-M的时间内每条路上都会出现不同数量的金币(j时刻i工厂出现的金币数量为val[i][j]).每条路的起点处都有一个工厂,总共N个. 可以从任意 ...
- P1070 道路游戏
题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编 ...
- 洛谷 P1070 道路游戏(noip 2009 普及组 第四题)
题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 nn个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 nn个机器人工厂编 ...
- luogu P1070 道路游戏
传送门 这里设\(f_i\)表示时刻\(i\)的答案 转移的话在\([i-p+1,i-1]\)之间枚举j,然后考虑从哪个点走过来 复杂度为\(O(n^3)\) // luogu-judger-enab ...
随机推荐
- LInux安装MySQL5.7.24详情
安装包下载 MySQL 的官网下载地址:http://www.mysql.com/downloads/ 我安装的是5.7版本 第二步: 选择:TAR (mysql-5.7.24-el7-x86_64. ...
- java8学习之Collectors工厂类源码分析与实战
如上一节[http://www.cnblogs.com/webor2006/p/8360232.html]在结尾处谈到的,彻底理解了Collector收集器之后,有必要对其系统Collectors实现 ...
- python生成器并行实例
生成器并行实例: send发送值被yield接受到赋值给baozi变量 #yield作用只是在这里保存这个值的当前状态然后返回之后在调用next,又回到yield #单纯调用next不会给yield传 ...
- JAVA笔记9-多态(动态绑定、池绑定)
1.动态绑定:执行期间(而非编译期间)判断所引用对象的实际类型,根据实际的类型调用相应方法. 2.多态存在的三个必要条件(同时):继承.重写.父类引用指向子类对象. 这三个条件满足后,当调用父类中被重 ...
- JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、jinfo、jconsole使用详解
JDK本身提供了很多方便的JVM性能调优监控工具,除了集成式的VisualVM和jConsole外,还有jps.jstack.jmap.jhat.jstat等小巧的工具,本博客希望能起抛砖引玉之用,让 ...
- ES使用中的总结整理
最近项目中使用了ES搜索,开始时自己搭建了ES环境做测试,后面申请了公司的云平台应用, 对接ES的过程中颇具波折,遇到了很多问题,在这里统一整理记录下: 1,ES的9200 及 9300端口说明 92 ...
- laravel发送邮件模板中点击的链接url动态生成
邮件模板里有url链接,生成链接有三种方式(目前总结出这三种方式)这个链接可以是: http://www.xxx.com/active?id=xxx&token=xxx 这种形式是把url ...
- 在百度ueditor上粘贴从word中copy的图片和文字 图片无法显示的问题
我这边从world 里面复制粘贴图片到编辑器中,它自动给我上传了,但是我是用的第三方的要设置一个token值,我找了很久,也没有找到应该在哪里设置这个上传的参数,如果是点击图片上传,我知道在dialo ...
- THUSC2016 成绩单
题目链接:Click here Solution: 我们设\(f[l][r][x][y]\)表示在原区间\(l\sim r\) 内还未被取走的值最大为\(x\)最小为\(y\)时的代价,这里我们只考虑 ...
- apply,call,bind函数作用与用法
作用 可以把方法借给其它对象使用,并且改变this的指向 a.apply(b,[3,2]);//this指向由a变为b, a的方法借给b使用 实例: function add(a,b){ ...