Luogu 1070 道路游戏
看完题面想了一会发现只会写$n^3$,愣了一会才想出了单调队列优化的做法。
90分算法:
设$f_{i, j, k}$表示第$i$分钟在第$j$座城市已经走了$k$步的最大价值,转移显然,时间复杂度$O(n^3)$。
但是我没有实现它。
100分算法:
思考一下最终的答案是怎样选出来的,我们把矩阵画出来:

发现题目可以转化为在这个矩阵上选若干个斜对角线,使得每一列都有且仅有一个被选到,最后获得的总价值为所有选到的格子上的值再减去所有斜对角线开始的格子对应的代价,使这个总价值最大。
设$f_{i, j}$表示到第$i$分钟,当前再$j$能选到的最大价值,那么发现最多只能从$1-p$层上转移过来。
$f_{i, j} = max(max(f_{i - k,o}) + calc(i- k, i) - cost_{pos(j, k)}) (1 \leq k \leq p - 1) (1 \leq o \leq n)$
$calc(i, j)$表示这一条对角线(从$i$层到$j$层)上的价值总和,可以通过斜线上预处理前缀和得到,$pos(i, j)$表示$i$上移$j$层所到达的纵坐标,$cost_{i}$表示在第$i$个城市买机器人的代价。
那么对每一条斜的对角线维护一个单调队列即可。
时间复杂度$O(n^2)$。
我还是没有实现它。
介绍一种dalao的思路。(第二个id叫Ghastlcon)的大佬,他的Luogu博客中这篇文章看不了了……
有一个小trick就是把下标从$0$到$n - 1$编号,这样子上面定义的$pos(i, j) = ((i - j) \% n + n) \% n$,这样子做前缀和的时候也比较方便。
其实我们发现$f$的第二维是没r用的,所以可以直接拿掉,因为在一个结束的位置并不影响在下一个开始的位置,我们要的只是这个最大值。
把前缀和$g$完整地写出来,有:$f_{i} = max(f_{j} + g_{i} - g_{j - 1} - cost_{j}) (1 \leq i - j \leq p - 1)$。
可以把之后与$i$有关的项拿到外面来,就可以用单调队列优化了。
时间复杂度$O(n^2)$。
Code:
#include <cstdio>
#include <cstring>
using namespace std; const int N = ; int n, m, k, a[N], g[N][N], f[N]; inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > ''|| ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} struct PriQueue {
int lst[N], pos[N], l, r; inline void init() {
l = , r = ;
} inline void push(int x, int val) {
for(; l <= r && lst[r] < val; --r);
lst[++r] = val, pos[r] = x;
} inline void pop(int p) {
for(; l <= r && pos[l] < p; ++l);
} } q[N]; inline int pos(int x, int len) {
return ((x - len) % n + n) % n;
} inline void chkMax(int &x, int y) {
if(y > x) x = y;
} int main() {
read(n), read(m), read(k);
for(int i = ; i < n; i++)
for(int j = ; j <= m; j++)
read(g[i][j]);
for(int i = ; i < n; i++) read(a[i]); for(int j = ; j <= m; j++)
for(int i = ; i < n; i++)
g[i][j] += g[(i + n - ) % n][j - ]; for(int i = ; i < n; i++) q[i].init(); for(int i = ; i < n; i++) {
int now = pos(i, -);
q[now].push(, -a[i]);
} memset(f, , sizeof(f)); f[] = ;
for(int i = ; i <= m; i++) {
for(int j = ; j < n; j++) {
int now = pos(j, i - );
chkMax(f[i], q[now].lst[q[now].l] + g[pos(j, )][i]);
} for(int j = ; j < n; j++) {
int now = pos(j, i - );
q[now].pop(i - k + );
q[now].push(i, f[i] - g[pos(j, )][i] - a[j]);
}
} printf("%d\n", f[m]);
return ;
}
Luogu 1070 道路游戏的更多相关文章
- [luogu 1070]道路游戏(NOIP2009T4)
题目链接 题解: 题目描述好长啊.... 大概就是设一下$f[i]$表示第i秒的最大价值 首先枚举时间,然后因为机器人这一秒无论在哪里都是有可能的,所以要枚举一下每个点,又因为最多走p秒所以再枚举一下 ...
- [luogu]P1070 道路游戏[DP]
[luogu]P1070 道路游戏 题目描述小新正在玩一个简单的电脑游戏.游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针 ...
- luogu P1070 道路游戏
传送门 这里设\(f_i\)表示时刻\(i\)的答案 转移的话在\([i-p+1,i-1]\)之间枚举j,然后考虑从哪个点走过来 复杂度为\(O(n^3)\) // luogu-judger-enab ...
- 洛谷 P1070 道路游戏 解题报告
P1070 道路游戏 题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有\(n\)个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依 ...
- 1070 Bash游戏 V4
1070 Bash游戏 V4 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次拿的数量最少1个,最多不超过对手上 ...
- 1070 Bash 游戏 V4
传送门 1070 Bash游戏 V4 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一堆石子共有N个.A B两个人轮流拿,A先拿.每次拿的数量最少1个,最多 ...
- 洛谷P1070 道路游戏
P1070 道路游戏 题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将 ...
- 洛谷 P1070 道路游戏 DP
P1070 道路游戏 题意: 有一个环,环上有n个工厂,每个工厂可以生产价格为x的零钱收割机器人,每个机器人在购买后可以沿着环最多走p条边,一秒走一条,每条边不同时间上出现的金币是不同的,问如何安排购 ...
- 51 Nod 1070 Bash游戏v4(斐波那契博弈)
这题的证明看不太懂,日后再重做... 1070 Bash游戏 V4 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 有一堆石子共有N个.A B两个 ...
随机推荐
- 了解vue
什么是Vuex Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. 状态,其实指的是实例之间的 ...
- centos6.5 64安装ffmpeg过程支持转码mp3
百度了几个文章 大致知道了思路 首先yum源安装是木有的,只能编译安装了. 要安装ffmpeg要先安装一个yasm支持汇编优化(FFmpeg需要) 在安装一个lame,支持mp3的转码 那就是需要3步 ...
- [python爬虫] Selenium定向爬取PubMed生物医学摘要信息
本文主要是自己的在线代码笔记.在生物医学本体Ontology构建过程中,我使用Selenium定向爬取生物医学PubMed数据库的内容. PubMed是一个免费的搜寻引擎,提供生物医学方 ...
- HTML5 Canvas ( 贝塞尔曲线, 一片星空加绿地 ) quadraticCurveTo, bezierCurveTo
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 2.vo传参模式和ModerDriven传参模式
转自:https://wenku.baidu.com/view/84fa86ae360cba1aa911da02.html Copy上面的myStruts2项目,改名为myStruts2Vo项目.作如 ...
- java垃圾回收几种算法
1.引用计数法 2.标记——清除法 3.标记——整理算法 4.copying算法 5.generation算法(新生代.老年代.持久代) 详情参考:深入理解 Java 垃圾回收机制
- IP Editor IP控件
HWND hIpEdit; void __fastcall TForm2::FormCreate(TObject *Sender) { hIpEdit = CreateWindow(WC_IPADDR ...
- UILabel 自适应高度,宽度
mLabel1 = [[UILabel alloc]initWithFrame:CGRectMake(0, 20, 10, 1)]; mLabel1.text = @"my label 1, ...
- Objective C, post 请求
-(void)postData { NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithS ...
- map模块使用方法
map指令使用ngx_http_map_module模块提供的.默认情况下,nginx有加载这个模块,除非人为的 --without-http_map_module.ngx_http_map_modu ...