「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」打兔子的更多相关文章

  1. 「JSOI2014」矩形并

    「JSOI2014」矩形并 传送门 我们首先考虑怎么算这个期望比较好. 我们不难发现每一个矩形要和 \(n - 1\) 个矩形去交,而总共又有 \(n\) 个矩形,所以我们把矩形两两之间的交全部加起来 ...

  2. 「JSOI2014」电信网络

    「JSOI2014」电信网络 传送门 一个点选了就必须选若干个点,最大化点权之和,显然最大权闭合子图问题. 一个点向它范围内所有点连边,直接跑最大权闭合子图即可. 参考代码: #include < ...

  3. 「JSOI2014」学生选课

    「JSOI2014」学生选课 传送门 看到这题首先可以二分. 考虑对于当前的 \(mid\) 如何 \(\text{check}\) 我们用 \(f_{i,j}\) 来表示 \(i\) 对 \(j\) ...

  4. 「JSOI2014」歌剧表演

    「JSOI2014」歌剧表演 传送门 没想到吧我半夜切的 这道题应该算是 \(\text{JSOI2014}\) 里面比较简单的吧... 考虑用集合关系来表示分辨关系,具体地说就是我们把所有演员分成若 ...

  5. 「JSOI2014」支线剧情2

    「JSOI2014」支线剧情2 传送门 不难发现原图是一个以 \(1\) 为根的有根树,所以我们考虑树形 \(\text{DP}\). 设 \(f_i\) 表示暴力地走完以 \(i\) 为根的子树的最 ...

  6. 「JSOI2014」强连通图

    「JSOI2014」强连通图 传送门 第一问很显然就是最大的强连通分量的大小. 对于第二问,我们先把原图进行缩点,得到 \(\text{DAG}\) 后,统计出入度为零的点的个数和出度为零的点的个数, ...

  7. 「JSOI2014」序列维护

    「JSOI2014」序列维护 传送门 其实这题就是luogu的模板线段树2,之所以要发题解就是因为学到了一种比较NB的 \(\text{update}\) 的方式.(参见这题) 我们可以把修改操作统一 ...

  8. 「AHOI2014/JSOI2014」宅男计划

    「AHOI2014/JSOI2014」宅男计划 传送门 我们首先要发现一个性质:存货天数随买食物的次数的变化类似于单峰函数. 具体证明不会啊,好像是二分加三分来证明?但是没有找到明确的严格证明. 感性 ...

  9. 「AHOI2014/JSOI2014」拼图

    「AHOI2014/JSOI2014」拼图 传送门 看到 \(n \times m \le 10^5\) ,考虑根号分治. 对于 \(n < m\) 的情况,我们可以枚举最终矩形的上下边界 \( ...

随机推荐

  1. 虚拟机下的Linux连接校园网上网问题

    安装了CentOS7后,本地Windows系统连接用的是校园网,虚拟机用的是桥接模式,无法上网. 解决的办法是:找到连接的校园网的网卡,给虚拟机的VMnet8共享. 步骤:打开[网络和共享中心]-[更 ...

  2. bugku 多种方法解决

    首先打开链接发现是一个exe文件 实在是想不出办法了 只能回去看提示 说会有一张图片 不知道怎么就打开了hxd 然后拖进去 发现了一串 用图片base64加密的码 然后在网页中找到 解码 工具 htt ...

  3. Mysql sql语句技巧与优化

    一.常见sql技巧 1.正则表达式的使用 2.巧用RAND()提取随机行 mysql数据库中有一个随机函数rand()是获取一个0-1之间的数,利用这个函数和order by一起能够吧数据随机排序, ...

  4. Codeforces Round #599 (Div. 2) B1. Character Swap (Easy Version)

    This problem is different from the hard version. In this version Ujan makes exactly one exchange. Yo ...

  5. python 网页中文显示Unicode码

    print repr(a).decode("unicode–escape") 注:a是要输出的结果,

  6. C语言 多文件编程

    C语言 多文件编程 分文件编程 把函数声明放在头文件xxx.h中,在主函数中包含相应头文件 在头文件对应的xxx.c中实现xxx.h声明的函数 防止头文件重复包含 1.当一个项目比较大时,往往都是分文 ...

  7. vue去掉地址栏# 方法

    超简单 export default new Router({ //将mode 设置为‘history‘ 即可.默认情况是’hash’ 所以会有丑陋的# mode: 'history', routes ...

  8. Redis-复制(MasterSlave)

    Redis的复制(Master/Slave) 是什么: 行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略, 自动同步到备机的master/slaver机制,Master以写为主,Slave ...

  9. [蓝桥杯][基础训练]2n皇后问题

    Description 给定一个n*n的棋盘,棋盘中有一些位置不能放皇后.现在要向棋盘中放入n个黑皇后和n个白皇后,使任意的两个黑皇后都不在同一行.同一列或同一条对角线上,任意的两个白皇后都不在同一行 ...

  10. JAVA常量池、栈、堆的比较(转载)

    今天在学JAVA的数据存储位置的时候,看到了一篇博文感觉不错,特此转载: http://www.cnblogs.com/Eason-S/p/5658230.html JAVA中,有六个不同的地方可以存 ...