【BZOJ 5038 不打兔子】
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 22 Solved: 8
[Submit][Status][Discuss]
Description
勤劳的JYY在花园里面种了好多胡萝卜!可是,今天早上JYY发现一大群从JSOI王国里面跑来的兔子把他的花园全部
占满了!兔子们把胡萝卜吃光了,JYY靠什么过冬呢!忍无可忍的JYY决定取出他的强力猎枪来消灭这些兔子。JYY
的花园是一个由N个块小菜地顺次连接所形成的圆环。菜地由1到N编号。第i号菜地和第i+1号菜地是相邻的。由于
是环形的花园,所以1号菜地和N号菜地也是相邻的。现在,第i号菜地上有Ri只兔子。JYY的猎枪有K发子弹,每次J
YY可以选择一块菜地打一枪,然后这块菜地上的兔子就全部都被消灭了。但是由于JYY的猎枪威力太大,会吓到相
邻菜地上的兔子,所以,如果JYY朝i号菜地打了一枪,那么i+1号菜地上的兔子就会跑到i+2号菜地上去,同样的,
i-1号菜地上的兔子也会跑到i-2号菜地上去。JYY想知道,如何用这K发子弹,消灭尽量多的兔子呢?
Input
输入文件的第一行包含两个整数N和K;
接下来一行N个整数,第i个整数为Ri。
3≤N≤4000,0≤K≤4000,0≤Ri≤10^5。
Output
输出一行一个整数,表示JYY最多可以消灭的兔子个数。
Sample Input
5 2
6 1 5 3 4
Sample Output
13
【样例说明】
首先JYY朝1号菜地打一枪,然后菜地里面的兔子数量就变成了
0 0 6 7 0
接着JYY再朝4号菜地打一枪就可以一共消灭13只兔子了
题解:
①尝试转化问题:先得出结论“间隔地选择开枪位置最优”,那么我们可以将连续间隔的一部分划分为一个区间(例如000000),这里面的生物都会被打死。
②划分区间后,原问题转化为区间DP:f[i][j][1/0]表示在i位置,已经开了j枪,是否向后延伸区间。
③转移建议使用草稿纸画一画:
f[i+1][j][0]=max(f[i+1][j][0],f[i][j][0]) 不开枪,继续向前走形成下一个区间
f[i+1][j+1][1]=max(f[i+1][j+1][1],f[i][j][0]+a[i+1]) 走的下一步并开一枪,同时归为当前区间
f[i+1][j][0]=max(f[i+1][j][0],f[i][j][1]) 不开枪,该区间到此为止,走入下一个区间
f[i+2][j+1][1]=max(f[i+2][j+1][1],f[i][j][1]+a[i+1]+a[i+2]) 当前开了枪,下一步不开枪并归为当前区间,所以再走一步
④处理环:如果1,n不在同一区间便没啥。如果在一个区间,就枚举是选择1开枪还是在n开枪。(代码中体现为sign)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 1000000000
#define go(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
int n,k,f[4005][4005][2],a[4005],b[4005],sum,ans;
int Dynamic_Programming(int sign)
{
if(k*2>n)return sum;
go(i,1,n)go(j,0,k)f[i][j][0]=f[i][j][1]=-inf;f[1][1][1]=a[1];if(!sign)f[1][0][0]=0;
go(i,1,n)go(j,0,k)
f[i+1][j][0]=max(f[i+1][j][0],f[i][j][0]),
f[i+1][j+1][1]=max(f[i+1][j+1][1],f[i][j][0]+a[i+1]),
f[i+1][j][0]=max(f[i+1][j][0],f[i][j][1]),
f[i+2][j+1][1]=max(f[i+2][j+1][1],f[i][j][1]+a[i+1]+a[i+2]);
if(sign)return f[n][k][1];
return max(f[n][k][0],f[n][k][1]);
}
int main()
{
scanf("%d%d",&n,&k);
go(i,1,n)scanf("%d",&b[i]),a[i]=b[i],sum+=(a[i]=b[i]);
if(n==3&&k==2){sort(a+1,a+n+1);printf("%d",a[2]+a[3]);return 0;} ans=Dynamic_Programming(0);a[1]=0;n++;k++;
go(i,1,n)a[i+1]=b[i];ans=max(ans,Dynamic_Programming(1));
go(i,1,n)a[i+0]=b[i];ans=max(ans,Dynamic_Programming(1));
printf("%d\n",ans);
}//Paul_Guderian
倦得像一朵被风折断的野花,所以我开始变了,
变得像一团滚动炽热的花火.————汪峰《花火》
【BZOJ 5038 不打兔子】的更多相关文章
- bzoj 2437 [Noi2011]兔子和鸡蛋 [二分图匹配]
叙述性说明 这些日子.兔子和蛋像一个新的棋盘游戏. 这场比赛是在 n 行 m 在船上进行列. 前,棋盘上有一 个格子是空的,其他的格子中都放置了一枚棋子,棋子或者是黑色,或者是白色. 每一局游戏总是兔 ...
- BZOJ 4027: [HEOI2015]兔子与樱花 树上dp
4027: [HEOI2015]兔子与樱花 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
- BZOJ 4027: [HEOI2015]兔子与樱花 贪心
4027: [HEOI2015]兔子与樱花 Description 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号 ...
- BZOJ 4027: [HEOI2015]兔子与樱花
贪心 #include<cstdio> #include<algorithm> using namespace std; int cnt,n,m,F[2000005],c[20 ...
- 洛谷 P2046 BZOJ 2007 海拔(NOI2010)
题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作 一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...
- 2011 Multi-University Training Contest 4 - Host by SDU
A.Color the Simple Cycle(polya计数+字符串匹配) 此题的难点在于确定置换的个数,由a[i+k]=a[i], e[i+k]=e[i]联想到KMP. 于是把原串和原串扩大两倍 ...
- BZOJ 1001 [BeiJing2006] 狼抓兔子(平面图最大流)
题目大意 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的.而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
- 【BZOJ】【4027】【HEOI2015】兔子与樱花
贪心 树上贪心问题……跟APIO2015练习赛的C很像啊…… 我的思路是:从叶子向上考虑,令a[x]表示x这个节点上樱花数量与儿子个数的和(即对于任意的x,都有$a[x]\leq m$)每次从儿子的a ...
- 【BZOJ】【1001】 【BJOI2006】狼抓兔子
平面图最小割->对偶图最短路 平面图最小割转对偶图最短路= = 想到了就比较好写了…… 可能是我对区域的标号方式比较奇特?反正我没有特判n==1||m==1也能过2333(机智吧-(滚开啦你个自 ...
随机推荐
- ReentrantReadWriteLock的使用
ReentrantReadWriteLock的规则是: 多线程情况下:读-写互斥.写-读互斥.写-写互斥.读-读共享 验证“读-写互斥.写-读互斥.写-写互斥.读-读共享” //单个线程 读-读 不互 ...
- Java 程序设计总复习题
Java程序设计总复习题 1.编写一个Java程序在屏幕上输出“你好!”. //programme name Helloworld.java public class Helloworld { pub ...
- Oracle 系统表
--如果一个表拥有DBA\\ALL\\USERS三个前缀 --DBA_前缀表示DBA拥有的或者可以访问的所有关系表 --ALL_前缀表示当前用户做拥有的或者可以访问的所有关系表 --USERS-前缀表 ...
- Sass和gulp的简单了解
一.sass less css预处理器 sass里面有2种语法 第一种语法是sass 后缀名必须是sass 第二种语法是scss 后缀名必须是scss ...
- P4746 C’s problem(c)
时间: 1000ms / 空间: 655360KiB / Java类名: Main 背景 冬令营入学测试 描述 题目描述 小C是一名数学家,由于它自制力比较差,经常通宵研究数学问题. 这次它因为这个数 ...
- 洛谷P1048采药
这道题一看就知道是01背包,我门用f[i]来表示时间剩余i时的最大的价值 一共只有两种选择取或者不取,可以得到方程式f[i]=max(f[i],f[i-a[i]]+v[i])(a[i]是表示时间,v[ ...
- Java,集合按自定义规则排序
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.u ...
- ArcGis API for JavaScript学习——离线部署API
ArcGis API for JavaScript开发笔记——离线部署API 以3.18版API为例: 在加载图图前引用GIS服务是必须的.有两种方法,一是在线引用,而是离线部署引用. 在线引用: & ...
- Codeforces 664D Graph Coloring 二分图染色
题意: 一个无向图的每条边为红色或蓝色,有这样一种操作:每次选一个点,使与其相邻的所有边的颜色翻转. 求解是否可以经过一系列操作使所有的边颜色相同,并输出最少操作次数和相应的点. 分析: 每个点要么选 ...
- go经典练习题涉及流程控制-字符串-struct-map的数据类型的处理
one:求1到100之间的质数 package main import ( "fmt" ) func isPrime(n int) bool { var flag = true f ...