首页 > 其他分享 >BZOJ 1915: [Usaco2010 Open]奶牛的跳格子游戏 单调队列优化dp

BZOJ 1915: [Usaco2010 Open]奶牛的跳格子游戏 单调队列优化dp

时间:2023-07-07 13:33:40浏览次数:48  
标签:钱数 ch 格子 Usaco2010 sum include 1915 dp



1915: [Usaco2010 Open]奶牛的跳格子游戏


Time Limit: 4 Sec  Memory Limit: 64 MB

Submit: 281  Solved: 110

[Submit][Status][Discuss]

Description


奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子,(3 <=N <= 250,000),编号为1..N。就像任何一个好游戏一样,这样的跳格子游戏也有奖励!第i个格子标有一个数字V_i(-2,000,000,000 <=V_i <= 2,000,000,000)表示这个格子的钱。奶牛们想看看最后谁能得到最多的钱。规则很简单: * 每个奶牛从0号格子出发。(0号格子在1号之前,那里没钱) * 她向N号格子进行一系列的跳跃(也可以不跳),每次她跳到的格子最多可以和前一 个落脚的格子差K格(1 <= K <= N)(比方说,当前在1号格,K=2, 可以跳到2号和3号格子) *在任何时候,她都可以选择回头往0号格子跳,直到跳到0号格子。另外,除了以上规则之外,回头跳的时候还有两条规则: *不可以跳到之前停留的格子。 *除了0号格子之外,她在回来的时候,停留的格子必须是恰巧过去的时候停留的某个格子的前一格(当然,也可以跳过某些过去时候停留的格子)。简单点说,如果i号格子是回来 停留的格子,i+1号就必须是过去停留的格子,如果i+1号格子是过去停留的格子,i号格子不一定要是回来停留的格子。(如果这里不太清楚的可以去看英文原文)她得到的钱就是所有停留过的格子中的数字的和,请你求出最多奶牛可以得到的钱数。 在样例中,K=2,一行5个格子。 

 一个合法的序列Bessie可以选择的是0[0], 1[0], 3[2], 2[1], 0[0]。(括号里的数表示钱数) 这样,可以得到的钱数为0+0+2+1+0 = 3。 如果Bessie选择一个序列开头为0, 1, 2, 3, ...,那么她就没办法跳回去了,因为她没办法再跳到一个之前没跳过的格子。序列0[0], 2[1], 4[-3], 5[4], 3[2], 1[0], 0[0]是最大化钱数的序列之一,最后的钱数为(0+1-3+4+2+0 = 4)。

Input


* 第1行 1: 两个用空格隔开的整数: N 和 K * 第2到N+1行: 第i+1行有一个整数: V_i


Output


* 第一行: 一个单个的整数表示最大的钱数是多少。


Sample Input


5 2
0
1
2
-3
4


Sample Output


4

OUTPUT DETAILS:

还有一种可能的最大化钱数的序列是: 0 2 4 5 3 1 0




用dp[i]表示走到i并且回到i-1最大收益

用sum[i]表示到i的正权值和

所以在k之后的点j的最大收益为dp[j-k]+sum[j]-sum[j-k],在k之前的最大为sum[k]

用单调队列优化一下

dp[i]=dp[q[head]]+sum[i-2]-sum[q[head]]+val[i]+val[i-1]


#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<queue>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
const ll N=250100;
ll dp[N],q[N],val[N],sum[N],n,k;
int main()
{
	n=read();k=read();
	for(ll i=1;i<=n;i++)val[i]=read(),sum[i]=sum[i-1]+max(0ll,val[i]);;
	ll head=0,tail=1;
	for(ll i=1;i<=n;i++)
	{
		while(q[head]<i-k&&head<tail)head++;
		dp[i]=dp[q[head]]+sum[i-2]-sum[q[head]]+val[i]+val[i-1];
		while(dp[q[tail-1]]-sum[q[tail-1]]<dp[i]-sum[i]&&head<tail)tail--;
		q[tail++]=i;
	}
	ll ans=sum[k]; 
	for(ll i=1;i<=n;i++)ans=max(dp[i]+sum[min(i+k,n)]-sum[i],ans);
	printf("%lld\n",ans);
	return 0;
}




标签:钱数,ch,格子,Usaco2010,sum,include,1915,dp
From: https://blog.51cto.com/u_16181403/6652014

相关文章

  • 概率/期望dp刷题整理
    Bagofmice题意:有w只白鼠和b只黑鼠,公主和龙轮流抓老鼠,其中龙每抓一只老鼠就会有一只未被抓住的老鼠逃走,先抓到一只白鼠的获胜,问公主获胜的概率是多少Solution令dp[i][j]表示还剩i只白鼠和j只黑鼠时公主获胜的概率如果公主直接抓住一只白鼠,获胜的概率是\[\frac{i}{i+j}\]如......
  • 230706 // 换根 DP 复习
    菌:园什是我笋子元首:我是你打野我:元首耳朵得治G.求树的重心http://222.180.160.110:1024/contest/3744/problem/7我们知道,重心的定义是,将其切除后,每个连通块的大小不超过\(\dfracn2\)。连通块分为其子树和整棵树减去该结点引导的子树,所以我们记录size,在每次搜索结束后......
  • package com.ws.byd.bmgl.bmzdpz:编码字典------bydobject
    controller:packagecom.ws.byd.bmgl.bmzdpz.controller;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.apache.commons.lang.O......
  • [Typescript] OverloadedReturnType & OverloadedParameters
    typeOverloadedReturnType<T>=Textends{(...args:any[]):inferR;(...args:any[]):inferR;(...args:any[]):inferR;(...args:any[]):inferR}?R:Textends{(...args:any[]):inferR;(...args:any[]):inferR;(...args:any......
  • WordPress主题,当前页面使用了哪个template模板文件?
    对于页面与模板的对应情况一般都是能确定的,不过新朋友一时不熟悉可能还是需要花一点时间。其实,可以有一个小技巧,可以快速确定当前页面对应的模板文件。想要实现上面的效果,只需将下面代码加入主题的 functions.php 文件。functionzhuige_admin_bar_init(){//Ifnota......
  • DP 优化
    1.单调队列优化DP1.1简介当一个选手比你小还比你强,你就打不过他了。这是对单调队列简单形象的概括。单调队列在转移的过程中不断排除不可能成为决策点的元素,使每次转移寻找决策点的时间复杂度降为\(O(1)\)。一般地,可被单调队列优化的转移式可被写为如下形式:\[F_i=\max_{l_......
  • DP优化
    优化DP笔记P6040「ACOI2020」课后期末考试滑溜滑溜补习班设\(f_i\)表示老师解决到第\(i\)个学生需要最少的精力,答案显然是\(f_n\)边界:对于\(i=1\),\(f_1=a_1\)对于其他的\(i\)号学生,我们假设老师是从第\(j\)位学生过来的,所以状态转移方程分为三项\(f_j\)......
  • UDP 编程不能太随意
    UDP相比TCP虽然是是无连接的,看似发送接收都很随意,但是在发送——接收过程中,仍然有些问题需要重视。在整个通讯过程中至少有两点需要注意,一方面要防止发送方的一厢情愿,另一方面是在允许的条件下,尽量保证数据的完整性。防止发送方的一厢情愿是指在发送时要确保对方有套接字可以......
  • Wordpress:安装Astra主题后,无法找到主题模板?
    在使用Wordpress安装Astra后,发现侧栏Appearance没有出现StarterTemplates,这样就无法使用很多Astra相关的免费模板,如何解决?1.点击Plugins,在搜索框输入StarterTemplates,安装后激活 2.在Appearance找到StarterTemplates,进入即可选择喜欢的模板。 ......
  • Python基础37 基于tcp、udp套字编程、粘包现象、struct模块
    基于tcp协议的套接字编程(sochet编程)什么是socket?通常翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把tcp/ip层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中。套接字分类:AF_UNIX:用在局域网中AF_INET:用在互联网中客户端和服务端启动顺序......