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两个 ...
随机推荐
- Redis如何存储对象与集合示例详解
前言 大家都知道在项目中,缓存以及mq消息队列可以说是不可或缺的2个重要技术.前者主要是为了减轻数据库压力,大幅度提升性能.后者主要是为了提高用户的体验度,我理解的是再后端做的一个ajax请求(异 ...
- 5S后返回首页
<!DOCTYPE html> <html> <head> <title>5S后返回首页</title> <meta http-equ ...
- vs2015 调试IIS
vs2015 调试IIS vs2015,menu,调试>附加到进程>w3wp 然后用浏览器打开网页,单步调试跟踪. http://blog.csdn.net/hyperhawk/artic ...
- VBA 操作 VBE
Introduction You can write code in VBA that reads or modifies other VBA projects, modules, or proced ...
- 机器学习入门-使用GridSearch进行网格参数搜索GridSeach(RandomRegressor(), param_grid, cv=3)
1.GridSeach(RandomRegressor(), param_grid, cv=3) GridSearch第一个参数是算法本身, 第二个参数是传入的参数组合, cv表示的是交叉验证的次数 ...
- wildFly(Jboss as)入门
目录 简介 安装 使用 简介 JBoss AS 从8版本起名为wildfly.JBoss是纯Java的EJB(企业JavaBean)服务器. JBoss As 由 Redhat出品的开源免费服务器,采 ...
- vue基础——组件基础
一.基本示例 这里有一个Vue组件的示例: // 定义一个名为 button-counter 的新组件 main.js Vue.component('button-counter', { data: ...
- H5 缓存机制解析
在web项目开发中,我们可能都曾碰到过这样一个棘手的问题: 线上项目需要更新一个有问题的资源(可能是图片,js,css,json数据等),这个资源已经发布了很长一段时间,为什么页面在浏览器里打开还是没 ...
- Oracle进程中的 LOCAL=NO 和 LOCAL=YES
我们在服务器上用sqlplus 连接数据库,在查看进程,会多出一条记录: oracle 16007 16006 0 10:27 ? 00:00:00 oraclenewccs (DESCRIPTION ...
- Mac和iOS开发资源汇总—更新于2013-10-14
小引本文主要汇集一些苹果开发的资源,会经常更新,建议大家把这篇文章单独收藏(在浏览器中按command+D).今天(2013年10月14日)收录了answer哥(黄爱武)的博客,欢迎大家围观! 今天( ...