链接:https://ac.nowcoder.com/acm/contest/1113/K
来源:牛客网

The cows have reverted to their childhood and are playing a game similar to human hopscotch. Their hopscotch game features a line of N (3 <= N <= 250,000) squares conveniently labeled 1..N that are chalked onto the grass.

Like any good game, this version of hopscotch has prizes! Square i is labeled with some integer monetary value  ViV_iVi​ (-2,000,000,000 <= ViV_iVi​ <= 2,000,000,000). The cows play the game to see who can earn the most money.

The rules are fairly simple:

* A cow starts at square '0' (located just before square 1; it has no monetary value).

* She then executes a potentially empty sequence of jumps toward square N. Each square she lands on can be a maximum of K (2 <= K <= N) squares from its predecessor square (i.e., from square 1, she can jump outbound to squares 2 or 3 if K==2).

* Whenever she wishes, the cow turns around and jumps back towards square 0, stopping when she arrives there. In addition to the restrictions above (including the K limit), two additional restrictions apply:

* She is not allowed to land on any square she touched on her outbound trip (except square 0, of course).

* Except for square 0, the squares she lands on during the return trip must directly precede squares she landed on during the outbound trip (though she might make some larger leaps that skip potential return squares altogether).

She earns an amount of money equal to the sum of the monetary values of all the squares she jumped on. Find the largest amount of cash a cow can earn.

By way of example, consider this six-box cow-hopscotch course where K has the value 3:
Square Num: 0 1 2 3 4 5 6
+---+ +---+ +---+ +---+ +---+ +---+ +---+
|///|--| |--| |--| |--| |--| |--| |
+---+ +---+ +---+ +---+ +---+ +---+ +---+
Value: - 0 1 2 -3 4 5
One (optimal) sequence Bessie could jump (shown with respective bracketed monetary values) is: 1[0], 3[2], 6[5], 5[4], 2[1], 0[0] would yield a monetary total of 0+2+5+4+1+0=12.
If Bessie jumped a sequence beginning with 0, 1, 2, 3, 4, ... then she would be unable to return since she could not legally jump back to an untouched square.

输入描述:

* Line 1: Two space separated integers: N and K
* Lines 2..N+1: Line i+1 contains a single integer: ViV_iVi​

输出描述:

* Line 1: A single line with a single integer that is the maximum amount of money a cow can earn
示例1

输入

复制

6 3
0
1
2
-3
4
5

输出

复制

12

题意:给定一个 n 个格子,每个格子有一个价值,一头牛一开始在 0 格子,每次最多跳 k 个,每当它跳到某个格子上,它就能够获得该格子的价值,并且它随时可以往后跳,但是有两 个限制,一个就是不能再跳已经跳过的格子,再就是必须跳到以前曾经跳过的格子的前一个,直到它跳到 0 格子结束,求它最多能获得多少价值。

析:很容易看出来是一个DP,但是有一个条件特别烦,那就是必须要回来,这个就是对后面的状态有影响,我们必须要消除这个影响,那就是在向前跳的时候就要把已经往后跳的格子也一块算出来,就没有影响了,dp[i] 表示跳到 i 位置,并且 i-1位置是回来要跳的格子,dp[i] = max{dp[j] | i-j >= k && j <= i-2}, 这个状态方程很容易写出来,但是它是不对的,为什么是不对的呢,因为如果 i-k ~ i-2 这些格子中可能它在向前的时候也跳过了,只不过在往后跳的时候没跳过,这样的格子我们没有计算过,再考虑这些格子肯定都是正数,我们不可能去跳负数。状态方程就改变成了 dp[i] = max{dp[j] + sum[i-2]-sum[j] | i-j >= k && j <= i-2},这里 sum[i] 是表示 1~i 这个区间内的所有正数的和。还有一个问题就是 k 太大了,所以直接循环是肯定要超时的,可以使用单调队列来优化, 单调队列中只要比较 dp[j] - sum[j] 就好了,因为sum[i-2]是一个常数,没有啥必要。还要考虑一些特殊情况,比如返回时只直接跳到0,等一些特殊情况。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#include <numeric>
#define debug() puts("++++")
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define be begin()
#define ed end()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
// #define all 1,n,1
#define FOR(i,n,x) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.in", "r", stdin)
#define freopenw freopen("out.out", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 250000 + 10;
const int maxm = 1e6 + 10;
const LL mod = 998244353LL;
const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
}
inline int readInt(){ int x; scanf("%d", &x); return x; } LL dp[maxn], sum[maxn];
int a[maxn], q[maxn]; int main(){
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; ++i){
scanf("%d", a + i);
sum[i] = sum[i-1] + (a[i] > 0 ? a[i] : 0);
}
LL ans = sum[min(n, m)];
int front = 0, rear = 0;
q[rear++] = 1;
dp[1] = a[1];
for(int i = 2, j = 0; i <= n; ++i, ++j){
while(front < rear && i - q[front] > m) ++front;
LL val = dp[j] - sum[j];
while(front < rear && val >= dp[q[rear-1]] - sum[q[rear-1]]) --rear;
q[rear++] = j;
int x = q[front];
dp[i] = dp[x] + a[i] + a[i-1] + sum[i-2] - sum[x];
}
for(int i = 1; i <= n; ++i)
ans = max(ans, dp[i] + sum[min(n, i-1+m)] - sum[i]);
printf("%lld\n", ans);
return 0;
}

  

Cow Hopscotch (单调队列 + DP)的更多相关文章

  1. POJ 3017 单调队列dp

    Cut the Sequence Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8764   Accepted: 2576 ...

  2. [TyvjP1313] [NOIP2010初赛]烽火传递(单调队列 + DP)

    传送门 就是个单调队列+DP嘛. ——代码 #include <cstdio> ; , t = , ans = ~( << ); int q[MAXN], a[MAXN], f ...

  3. zstu 4237 马里奥的求救——(单调队列DP)

    题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4237 这题可以转化为每次可以走g~d+x步,求最大分数,且最大分数的步数最少. ...

  4. 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP

    1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...

  5. BZOJ 5281--[Usaco2018 Open]Talent Show(分数规划&单调队列&DP)

    5281: [Usaco2018 Open]Talent Show Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 79  Solved: 58[Sub ...

  6. vijos P1243 生产产品(单调队列+DP)

      P1243生产产品   描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...

  7. POJ 1821 单调队列+dp

    题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...

  8. codeforces 1077F2. Pictures with Kittens (hard version)单调队列+dp

    被队友催着上(xun)分(lian),div3挑战一场蓝,大号给基佬紫了,结果从D开始他开始疯狂教我做人??表演如何AKdiv3???? 比赛场上:A 2 分钟,B题蜜汁乱计数,结果想得绕进去了20多 ...

  9. 【LOJ#10180】烽火传递 单调队列+dp

    题目大意:给定一个 N 个非负整数数组成的序列,每个点有一个贡献值,现选出其中若干数,使得每连续的 K 个数中至少有一个数被选,要求选出的数贡献值最小. 题解:设 \(dp[i]\) 表示考虑了序列前 ...

随机推荐

  1. ssh出现公钥错误问题的解决方法

      问题:主机app1推送公钥时,公钥判定错误   原因:之前推过公钥,用的是ip而不是主机名(即hosts文件中的对应关系不对),导致app1的~/.ssh/known_hosts中的公钥对不上. ...

  2. Oracle快速运行一指禅

      对于oracle数据库下的企业级应用开发,经常会使用到新建用户,新建表空间以及数据的迁移工作.虽然目前互联网存在很多单个问题的解决方案,但是比较零散,本博文结合研发兄弟们的实际现状,提供一套完整初 ...

  3. Spring Boot 创建动态定时任务

    1,日期格式转换 //定时任务格式转换public static String convertCronTime(Date jobDate){ //https://blog.csdn.net/qq_39 ...

  4. Oracle的查询-多表查询中的一些概念

    --笛卡尔积 select * from emp e,dept d; --等值连接 select * from emp e,dept d where e.deptno=d.deptno --内连接 s ...

  5. 微信小程序 路由跳转 异步请求 存储数据,微信登录接口

    1小程序路由跳转 wx.switchTab(Object object) 这里的tabBar是底下的导航栏指定的页面 跳转到 tabBar 页面,并关闭其他所有非 tabBar 页面 tabBar l ...

  6. selenium登录慕课网

    from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.s ...

  7. 17.tmux相关

    Linux终端复用神器-Tmux使用梳理 Tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授权.使用它最直观的好处就是,通过一个终端登录远程主机并运行tm ...

  8. java-filter and listener

    Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层. 使用 Serv ...

  9. WPF入门(1)——DataContext

    在WPF中,应用程序有两层:UI层和Data层.这里新建一个项目说明哪些是UI层,哪些是数据层. UI层很明显,就是用户看到的界面.但是数据层并不是下图所示: 上图中是UI层view的后台代码.当然, ...

  10. 论文阅读:《Bag of Tricks for Efficient Text Classification》

    论文阅读:<Bag of Tricks for Efficient Text Classification> 2018-04-25 11:22:29 卓寿杰_SoulJoy 阅读数 954 ...