「JSOI2014」打兔子
「JSOI2014」打兔子
首先要特判 \(k \ge \lceil \frac{n}{2} \rceil\) 的情况,因为此时显然可以消灭所有的兔子,也就是再环上隔一个点打一枪。
但是我们又会发现当 \(n = 3, k = 2\) 时,这种情况也满足上述条件但是我们只能打掉两群兔子,所以选兔子最多的两个格子打。
对于剩下的情况我们可以考虑 \(\text{DP}\) 。
我们可以发现一件事,就是说如果我们把环弱化成链,那么顺着打就可以包含所有状态了。
所以说我们就可以有一个性质:两个相邻的格子不会被同时打。
然后我们就在链上先跑 \(\text{DP}\) :设 \(dp_{i, j, 0 / 1}\) 表示在前 \(i\) 个格子中开了 \(j\) 枪,第 \(i\) 个格子有没有开枪的最大收益。
转移就是:
- 第 \(i+1\) 个格子不开 : \(dp_{i + 1, j, 0} \leftarrow \max\{dp_{i, j, 0}, dp_{i, j, 1}\}\)
- 第 \(i\) 个格子不开,第 \(i + 1\)个格子开:\(dp_{i + 1, j + 1, 1} \leftarrow dp_{i, j, 0} + a_{i + 1}\)
- 第 \(i\) 个格子开,第 \(i + 1\) 个格子不开,第 \(i + 2\) 个格子开:\(dp_{i + 2, j + 1, 1} \leftarrow dp_{i, j, 0} + a_{i + 1} + a_{i + 2}\)
然后对于环的问题,我们就讨论一下第 \(1\) 个格子和第 \(n\) 个格子的开枪情况即可。
参考代码:
#include <algorithm>
#include <cstring>
#include <cstdio>
#define rg register
#define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
using namespace std;
template < class T > void chkmax(T &a, const T& b) { a = a > b ? a : b; }
template < class T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while ('0' > c || c > '9') f |= c == '-', c = getchar();
while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
s = f ? -s : s;
}
const int _ = 4010;
int n, k, a[_], dp[_][_][2];
inline void DP() {
for (rg int i = 1; i < n; ++i)
for (rg int j = 0; j <= k; ++j) {
chkmax(dp[i + 1][j][0], max(dp[i][j][0], dp[i][j][1]));
if (j + 1 <= k) chkmax(dp[i + 1][j + 1][1], dp[i][j][0] + a[i + 1]);
if (j + 1 <= k && i + 2 <= n) chkmax(dp[i + 2][j + 1][1], dp[i][j][1] + a[i + 1] + a[i + 2]);
}
}
inline int calc1() {
memset(dp, 0xaf, sizeof dp), dp[1][0][0] = 0;
DP();
return dp[n][k][0];
}
inline int calc2() {
int tmp = a[n]; a[n - 1] += tmp, a[n] = 0;
memset(dp, 0xaf, sizeof dp), dp[1][1][1] = a[1], DP();
a[n] = tmp, a[n - 1] -= tmp;
return dp[n][k][0];
}
int main() {
#ifndef ONLINE_JUDGE
file("cpp");
#endif
read(n), read(k);
for (rg int i = 1; i <= n; ++i) read(a[i]);
int ans = 0;
if (k >= (n + 1) / 2) {
if (n == 3 && k == 2)
sort(a + 1, a + n + 1), printf("%d\n", a[2] + a[3]);
else {
for (rg int i = 1; i <= n; ++i) ans += a[i];
printf("%d\n", ans);
}
return 0;
}
chkmax(ans, calc1());
chkmax(ans, calc2());
reverse(a + 1, a + n + 1);
chkmax(ans, calc2());
printf("%d\n", ans);
return 0;
}
「JSOI2014」打兔子的更多相关文章
- 「JSOI2014」矩形并
「JSOI2014」矩形并 传送门 我们首先考虑怎么算这个期望比较好. 我们不难发现每一个矩形要和 \(n - 1\) 个矩形去交,而总共又有 \(n\) 个矩形,所以我们把矩形两两之间的交全部加起来 ...
- 「JSOI2014」电信网络
「JSOI2014」电信网络 传送门 一个点选了就必须选若干个点,最大化点权之和,显然最大权闭合子图问题. 一个点向它范围内所有点连边,直接跑最大权闭合子图即可. 参考代码: #include < ...
- 「JSOI2014」学生选课
「JSOI2014」学生选课 传送门 看到这题首先可以二分. 考虑对于当前的 \(mid\) 如何 \(\text{check}\) 我们用 \(f_{i,j}\) 来表示 \(i\) 对 \(j\) ...
- 「JSOI2014」歌剧表演
「JSOI2014」歌剧表演 传送门 没想到吧我半夜切的 这道题应该算是 \(\text{JSOI2014}\) 里面比较简单的吧... 考虑用集合关系来表示分辨关系,具体地说就是我们把所有演员分成若 ...
- 「JSOI2014」支线剧情2
「JSOI2014」支线剧情2 传送门 不难发现原图是一个以 \(1\) 为根的有根树,所以我们考虑树形 \(\text{DP}\). 设 \(f_i\) 表示暴力地走完以 \(i\) 为根的子树的最 ...
- 「JSOI2014」强连通图
「JSOI2014」强连通图 传送门 第一问很显然就是最大的强连通分量的大小. 对于第二问,我们先把原图进行缩点,得到 \(\text{DAG}\) 后,统计出入度为零的点的个数和出度为零的点的个数, ...
- 「JSOI2014」序列维护
「JSOI2014」序列维护 传送门 其实这题就是luogu的模板线段树2,之所以要发题解就是因为学到了一种比较NB的 \(\text{update}\) 的方式.(参见这题) 我们可以把修改操作统一 ...
- 「AHOI2014/JSOI2014」宅男计划
「AHOI2014/JSOI2014」宅男计划 传送门 我们首先要发现一个性质:存货天数随买食物的次数的变化类似于单峰函数. 具体证明不会啊,好像是二分加三分来证明?但是没有找到明确的严格证明. 感性 ...
- 「AHOI2014/JSOI2014」拼图
「AHOI2014/JSOI2014」拼图 传送门 看到 \(n \times m \le 10^5\) ,考虑根号分治. 对于 \(n < m\) 的情况,我们可以枚举最终矩形的上下边界 \( ...
随机推荐
- Java“被迫”退出争霸,Python继续霸占首位!老牌程序员:我不服
2019年转眼已经接近尾声,如果盘点下2019年最火的语言,除了Python还能有谁?你心中的王者语言又是谁? 这一年Python风光无限 这一年JAVA走向右边 这一年,我们都很感慨,你呢? 关于P ...
- 使用git上传项目解决码云文件次数上传限制(原文)
起因:个人免费版的码云上传文件时限制: 1个小时内只能上传20个文件 解决方法:在码云创建空的项目仓库,使用git客户端下载码云的项目,把需要上传的文件复制到该项目中去,用git提交! 1.配置git ...
- 密码学笔记——Rot13
Rot13:将每个在字母表上的字母,用后数13个后的字母代替,若超过时则重新绕回26字母开头即可. eg:A换成N.B换成O.依此类推到M换成Z,然后序列反转:N换成A.O换成B.最后Z换成M 1.密 ...
- bugku 管理员系统
这一个是伪造ip X-FORWARDED-FOR:127.0.0.1 用到了XFF头 首先打开网站会发现一个登录界面 然后用开发者工具看一下 后台会发现一串用base64加密的密文 用base64解密 ...
- angular2项目打包部署的坑
1.ng项目打包后,打开index.html,发现页面是空白的,F12查看,发现js和css引入的路径不对 这里要将package.json文件的打包命令改成 ng build --prod --ba ...
- ORACLE_BASE、ORACLE_HOME有什么区别
ORACLE_BASE.ORACLE_HOME有什么区别 ORACLE_BASE下是admin和productORACLE_HOME下则是ORACLE的命令.连接库.安装助手.listener等等 ...
- ARM架构安装Anaconda3出现错误:cannot execute binary file: Exec format error
ARM架构安装Anaconda3出现错误:cannot execute binary file: Exec format error 原因是:安装包格式不对. 在Anaconda官网上只有x86(32 ...
- WEB前后端约定接口
- 【网搜】禁止 number 输入非数字(Android仍有问题)
目的:使用 number 表单,让其只可输入数字. 问题:ios 可正常限制,Android 仍可输入 [ e | . | - | + ] 这4个字符.猜测这4个字符在数值中为科学记数.小数 ...
- EntityFramework 插入自增ID主从表数据
原因: 数据库中的两个表是主从表关系,但是没有建外键,而表的id用的是数据库的自增整数,导致在使用EF导入主从表数据时,需要先保存主表数据,取到 主表的自增id后才能插入从表数据,这样循环之下,数据插 ...