[USACO13NOV] Pogo-Cow S

题目传送门

题解

首先,一眼DP,想想怎么推状态转移方程

朴素DP

定义二维数组 \(f[i][j]\),其中第一维表示当前所在的目标点是\(i\),第二维表示上一个到达的目标点\(j\),即是由目标点\(j\)转移到目标点\(i\),处于\(i\)点的最大得分

设\(k\)表示\(j\)的上一个目标点,易得方程:

\[f_{i,j}=max\{f_{i,j} ,f_{j,k}+p_i\}
\]

那么我们需要三层循环,分别枚举\(i,j,k\);

当然依照题意,我们需要两次DP,从左往右推和从右往左推,然后取最大值才是正确答案

就像我忘记推两遍所以多WA一次

如果你按照上面的方程打好了,提交,恭喜你TLE

单调队列优化DP

\(n\le 1000\)的限制使朴素DP被卡死,我们想办法用单调队列优化这个方程。单调队列通常用来维护单调性(多为递增或递减),在使用时只用到极值,但还是需要把每个元素进一次队列,因为题目中可能会有其他限制使当前最大值不符合要求,此时令最大值出队列,不断寻找符合条件的次大值。

题目中也有对于方程的限制条件:

每次跳跃的距离至少和上一次跳跃的距离相等,并且必须跳到一个目标点

可以得到方程的限制条件

\[f_{i,j}=max\{f_{i,j} ,f_{j,k}+p_i\}(x_i-x_j\ge x_j-x_k)
\]

改变这个方程,得到另一个方程

\[f_{i-1,j}=max\{f_{i-1,j},f_{j,k}+p_i \}(x_{i-1}-x_j\ge x_j-x_k)
\]

我们可以发现\(f_{i,j}\)可以由\(f_{i-1,j}\)转移过来,但限制条件有所不同,每次\(x_j\)是不变的,从\(f_{i-1,j}\)转移到\(f_{i,j}\)时,一定有\(x_i\ge x_{i-1}\),因此\(k\)的取值也会改变,用单调队列维护\(k\),得到符合要求的最大的\(f_{j,k}\),代入方程

\[f_{i,j}=max\{f_{i-1,j}-p_{i-1}+p_i ,f_{j,k}+p_i \}(x_i-x_j\ge x_j-x_k)
\]
\[f_{i,j}=max\{f_{i-1,j}-p_{i-1},f_{j,k} \}+p_i(x_i-x_j\ge x_j-x_k)
\]

核心代码

for(int j=1;j<=n;j++){
f1[j][j]=cow[j].p;//边界
int k=j;
for(int i=j+1;i<=n;i++){
f1[i][j]=f1[i-1][j]-cow[i-1].p;
int isaac=0;
while(k>=1&&cow[i].x-cow[j].x>=cow[j].x-cow[k].x){
isaac=Max(isaac,f1[j][k]);
k--;
}
f1[i][j]=Max(f1[i][j],isaac);
f1[i][j]+=cow[i].p;
maxn=Max(maxn,f1[i][j]);
}
}

观察上面的单调队列,好像并没有入队列的操作,其实\(k\)是从\(j\)开始维护的,相当于把从\(j\)到\(1\)的所有\(f_{j,k}\)都入了队列,且\(f_{i,j}\)是由\(f_{i-1,j}\)转移过来的,一定有\(f_{i,j}\ge f_{i-1,j}\),只需枚举每一个符合条件的\(k\)找到极大值,再进行转移,又因为\(x_i\ge x_{i-1}\),\(i\)的取值范围一定包含\(i-1\)的取值。

正确性

设\(i\)的取值范围左边界为\(k_i\) , \(i-1\)对应\(k_{i-1}\)

则\(f_{i-1,j}-p_{i-1}\)就是\(k_{i-1}\)到\(j\)的最大值,\(f_{i,j}\)直接使用\(f_{i-1,j}+p_{i-1}\),再枚举区间\([k_i,k_{i-1})\),从中取最大值进行转移,相当于直接使用$ [k_i,j]$区间最大值,保证算法正确。

时间复杂度 \(O(n^2)\)

每个元素最多出队列一次,复杂度是\(O(n)\),总的复杂度就是\(O(n^2)\)

Code

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+100;
int n,f1[N][N],maxn,f2[N][N];
struct pogo{
int x,p;
}cow[N];
bool cmp(pogo a,pogo b)
{
return a.x<b.x;
}
inline int Max(int a,int b)
{
return a>b?a:b;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&cow[i].x,&cow[i].p);
maxn=Max(maxn,cow[i].p);
}
sort(cow+1,cow+n+1,cmp);
for(int j=1;j<=n;j++){
f1[j][j]=cow[j].p;
int k=j;
for(int i=j+1;i<=n;i++){
f1[i][j]=f1[i-1][j]-cow[i-1].p;
int isaac=0;
while(k>=1&&cow[i].x-cow[j].x>=cow[j].x-cow[k].x){
isaac=Max(isaac,f1[j][k]);
k--;
}
f1[i][j]=Max(f1[i][j],isaac);
f1[i][j]+=cow[i].p;
maxn=Max(maxn,f1[i][j]);
}
}
for(int j=n;j>=1;j--){
f2[j][j]=cow[j].p;
int k=j;
for(int i=j-1;i>=1;i--){
f2[i][j]=f2[i+1][j]-cow[i+1].p;
int isaac=0;
while(k<=n&&cow[j].x-cow[i].x>=cow[k].x-cow[j].x){
isaac=Max(isaac,f2[j][k]);
k++;
}
f2[i][j]=Max(f2[i][j],isaac);
f2[i][j]+=cow[i].p;
maxn=Max(maxn,f2[i][j]);
}
}
printf("%d",maxn);
}

P3089 Pogo-Cow S的更多相关文章

  1. [luogu] P3089 [USACO13NOV]POGO的牛Pogo-Cow

    P3089 [USACO13NOV]POGO的牛Pogo-Cow 题目描述 In an ill-conceived attempt to enhance the mobility of his pri ...

  2. P3089 [USACO13NOV]POGO的牛Pogo-Cow

    P3089 [USACO13NOV]POGO的牛Pogo-Cow FJ给奶牛贝西的脚安装上了弹簧,使它可以在农场里快速地跳跃,但是它还没有学会如何降低速度. FJ觉得让贝西在一条直线的一维线路上进行练 ...

  3. DP【洛谷P3089】 [USACO13NOV]POGO的牛Pogo-Cow

    [洛谷P3089] [USACO13NOV]POGO的牛Pogo-Cow FJ给奶牛贝西的脚安装上了弹簧,使它可以在农场里快速地跳跃,但是它还没有学会如何降低速度. FJ觉得让贝西在一条直线的一维线路 ...

  4. POJ 3278 Catch That Cow(bfs)

    传送门 Catch That Cow Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 80273   Accepted: 25 ...

  5. 【BZOJ1623】 [Usaco2008 Open]Cow Cars 奶牛飞车 贪心

    SB贪心,一开始还想着用二分,看了眼黄学长的blog,发现自己SB了... 最小道路=已选取的奶牛/道路总数. #include <iostream> #include <cstdi ...

  6. HDU Cow Sorting (树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 Cow Sorting Problem Description Sherlock's N (1  ...

  7. [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居

    [BZOJ1604][Usaco2008 Open]Cow Neighborhoods 奶牛的邻居 试题描述 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发 ...

  8. 细读cow.osg

    细读cow.osg 转自:http://www.cnblogs.com/mumuliang/archive/2010/06/03/1873543.html 对,就是那只著名的奶牛. //Group节点 ...

  9. POJ 3176 Cow Bowling

    Cow Bowling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13016   Accepted: 8598 Desc ...

  10. raw,cow,qcow,qcow2镜像的比较

    在linux下,虚拟机的选择方式有很多,比如vmware for linux,virtual box,还有qemu,在以前,使用qemu的人不多,主要是使用起来有些麻烦,但现在随着Openstack的 ...

随机推荐

  1. 2023Java面试学习网站推荐

    本文给大家推荐博主收藏的6个程序员面试学习站点,按照项目简介.网站截图.是否收费供大家参考. 1. JavaGuide 网站地址:https://javaguide.cn 项目简介:「Java学习 + ...

  2. java基础-java面向对象01-day08

    1. 一个简单的类 认识类 成员变量 类方法 public class Person { //类的成员变量 int age; String name; double height; double we ...

  3. 浅谈 Docker 网络:单节点多容器

    1.同网段多容器访问 这一节将对 Docker 多容器网络进行讨论,构建容器网络示意图如下:

  4. 运筹学 | 退化的最优解 vs 无穷多最优解?

    退化的最优解: 单纯形表的基可行解中,出现等于零的基变量.或者,按最小比值来确定出基向量时,存在两个以上相同最小比值. 出现的原因:模型中存在多余的约束. 无穷多最优解: 单纯形表中,按最大检验数 σ ...

  5. Spring boot 自定义ThreadPoolTaskExecutor 线程池并进行异步操作

    本文为博主原创,转载请注明出处: 1. 使用 ThreadPoolTaskExecutor  封装自定义配置的线程池Bean ThreadPoolTaskExecutor 是Spring 中封装的一个 ...

  6. Python学习之七_input和print

    Python学习之七_input和print 摘要 python3 之后 函数必须带 () 了 因为我开始学习的比较晚, 所以准备Python3开始学起 前面主要是模仿别人的代码进行学习 后续慢慢学习 ...

  7. [转帖]xargs详解

    https://www.cnblogs.com/xiaofeng666/p/10800939.html xargs与find经常结合来进行文件操作,平时删日志的时候只是习惯的去删除,比如 # find ...

  8. [转帖]Redis子进程开销与优化

    Redis子进程开销与优化 文章系转载,便于分类和归纳,源文地址:https://blog.csdn.net/y532798113/article/details/106870299 1.CPU 开销 ...

  9. [转帖]Linux系统top命令中的io使用率,很多人都误解了它的具体含义

      https://baijiahao.baidu.com/s?id=1641356547223820839&wfr=spider&for=pc 最近在做连续数据流的缓冲系统,C语言代 ...

  10. [转帖]如何通过shell脚本对一个文件中的所有数值相加并求和

    https://developer.aliyun.com/article/886170?spm=a2c6h.24874632.expert-profile.255.7c46cfe9h5DxWK 1.背 ...