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

权限题,没有传送门。

这很显然是一道DP题,刚看完题目可能会比较懵逼。这道题如果不要求回去,那么就是一道很裸的DP题。但是本题要求回去而且回去的格子的前一个格必须是之前经过的。

先不考虑回去的路程,对于一段长度在$K$之内的区间,其中的所有值为正数的点都是可以到达的。所以先搞个前缀和:

$sum_i= \sum _{j=1}^i a_j \times [a_j>0]$

这个搞完后如果不算回来的,可以得到以下转移方程:

$f[i]=max \{ f[j]+sum[i-1]-sum[j] \}$

其实到这一步,带上回去的状态转移方程也很显然了。

$f[i]=max \{f[j]+sum[i-2]-sum[j]+a[i]+a[i-1] \}$

表示第$i$个点为去时经过的点且会返回的前一个点,$sum[]$和$f[]$均存在单调性,所以可以用单调队列优化决策单调性,使得总体复杂度降为$O(N)$。

但是$f[i]_{max}$并不是最后的答案,因为对于任意一个点$i$,$[i+1,i-1+K]$都是可以到达的,所以要把这一段对答案的贡献也累加上。

在具体实现时,注意单调队列在DP前应进队0和1,因为第0个点不是必须停留的点。

 1 //BZOJ 1915
 2 //by Cydiater
 3 //2016.10.6
 4 #include <iostream>
 5 #include <cstring>
 6 #include <string>
 7 #include <algorithm>
 8 #include <queue>
 9 #include <cstdio>
10 #include <cmath>
11 #include <ctime>
12 #include <map>
13 #include <iomanip>
14 #include <cstdlib>
15 using namespace std;
16 #define ll long long
17 #define up(i,j,n)        for(int i=j;i<=n;i++)
18 #define down(i,j,n)        for(int i=j;i>=n;i--)
19 const int MAXN=3e6+5;
20 const int oo=0x3f3f3f3f;
21 inline ll read(){
22     char ch=getchar();ll x=0,f=1;
23     while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
24     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
25     return x*f;
26 }
27 ll N,K,sum[MAXN],a[MAXN],q[MAXN],head,tail,f[MAXN],ans=0;
28 namespace solution{
29     void init(){
30         memset(sum,0,sizeof(sum));
31         N=read();K=read();
32         up(i,1,N)a[i]=read();
33         up(i,1,N)sum[i]=sum[i-1]+(a[i]>0?a[i]:0);
34     }
35     void DP(){
36         head=1;tail=0;q[++tail]=0;q[++tail]=1;
37         up(i,2,N){
38             while(head<tail&&i-q[head]>K)head++;
39             f[i]=f[q[head]]+sum[i-2]-sum[q[head]]+a[i]+a[i-1];
40             while(head<tail&&f[i]-f[q[tail]]>sum[i]-sum[q[tail]])tail--;
41             q[++tail]=i;
42         }
43         up(i,1,N)ans=max(ans,f[i]+((i-1+K<=N)?(sum[i-1+K]-sum[i]):(sum[N]-sum[i])));
44     }
45     void output(){
46         cout<<ans<<endl;
47     }
48 }
49 int main(){
50     //freopen("input.in","r",stdin);
51     using namespace solution;
52     init();
53     DP();
54     output();
55     return 0;
56 }

时间: 2024-10-12 15:32:27

BZOJ1915: [Usaco2010 Open]奶牛的跳格子游戏的相关文章

【BZOJ1915】[Usaco2010 Open]奶牛的跳格子游戏 DP+单调队列

[BZOJ1915][Usaco2010 Open]奶牛的跳格子游戏 Description 奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子,(3 <=N <= 250,000),编号为1..N.就像任何一个好游戏一样,这样的跳格子游戏也有奖励!第i个格子标有一个数字V_i(-2,000,000,000 <=V_i <= 2,000,000,000)表示这个格子的钱.奶牛们想看看最后谁能得到最多的钱.规则很简单: * 每个奶牛从0号格子出发

1861 奶牛的数字游戏 2006年USACO

codevs——1861 奶牛的数字游戏 2006年USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 青铜 Bronze 题解 题目描述 Description 奶牛们又在玩一种无聊的数字游戏.输得很郁闷的贝茜想请你写个程序来帮她在开局时预测结果.在游戏的开始,每头牛都会得到一个数N(1<=N<=1,000,000).此时奶牛们的分数均为0.如果N是奇数,那么奶牛就会把它乘以3后再加1.如果N是偶数,那么这个数就会被除以2.数字每变动一次,这头奶牛就得到1分.当N的

[BZOJ1666][Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏

1666: [Usaco2006 Oct]Another Cow Number Game 奶牛的数字游戏 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 849  Solved: 746 [Submit][Status][Discuss] Description 奶牛们又在玩一种无聊的数字游戏.输得很郁闷的贝茜想请你写个程序来帮她在开局时预测结果.在游戏的开始,每头牛都会得到一个数N(1<=N<=1,000,000).此时奶牛们的分数均为0.如果N

BZOJ2097[Usaco2010 Dec] 奶牛健美操

我猜我这样继续做水题会狗带 和模拟赛的题很像,贪心搞一下. 1 #include<bits/stdc++.h> 2 using namespace std; 3 int read(){ 4 int x=0,f=1;char ch=getchar(); 5 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 6 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getch

BZOJ 1666 Usaco 奶牛的数字游戏

1 #include <cstdio> 2 #include <algorithm> 3   4 int n; 5 int tot; 6   7 int main(){ 8     scanf("%d",&n); 9     while(n!=1){ 10         if(n%2!=0){ 11             n=n*3+1; 12             tot++; 13         } 14         else if(n%

bzoj usaco 金组水题题解(2.5)

bzoj 2197: [Usaco2011 Mar]Tree Decoration 树形dp..f[i]表示处理完以i为根的子树的最小时间. 因为一个点上可以挂无数个,所以在点i上挂东西的单位花费就是i所在子树里的最小单位花费.. 所以每次求f[i]只要使子树里的数量都满足要求就好了..i的祖先还要更多的话随时可以选某个节点多挂一些.. f[i]=sum{f[j]}+mincost[i]*max(need[i]-sum{need[j]},0)..(j是i的儿子,mincost[i]表示子树i里的

[单调队列优化DP]JZOJ 3128 跳格子

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号格子进行一系列的跳

洛谷P3120 [USACO15FEB]Cow Hopscotch

题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John&apos;s cows have invented a variant of the game for themselves to play. Being played by clumsy animals weighing nearly a ton, Cow Hopscotch almost always ends in disaster, but thi

【USACO OPEN 10】hop

奶牛们正在回味童年,玩一个类似跳格子的游戏,在这个游戏里,奶牛们在草地上画了一行N个格子,(3 <=N <= 250,000),编号为1..N. 就像任何一个好游戏一样,这样的跳格子游戏也有奖励!第i个格子标有一个数字V_i(-2,000,000,000 <=V_i <= 2,000,000,000)表示这个格子的钱.奶牛们想看看最后谁能得到最多的钱. 规则很简单: * 每个奶牛从0号格子出发.(0号格子在1号之前,那里没钱) *她向N号格子进行一系列的跳跃(也可以不跳),每次她跳