【BZOJ 2288】 生日礼物
【题目链接】
https://www.lydsy.com/JudgeOnline/problem.php?id=2288
【算法】
先将这个序列的正负数合并起来,变成一个正负交替的序列
如果新序列的正数个数小于等于M,那么直接输出正数的和即可
否则,我们可以将某些正数和负数合并起来,或者不要某些正数
将所有数按绝对值排序,放入堆中,问题就转化为了 : 在这些数中选出(Cnt - M)个数(其中Cnt为正数的个数),
选了一个数后相邻的两个数就不能选,使得最后的和尽可能小
这个问题可以用CTSC2007数据备份的方法来解决,详见 : https://www.cnblogs.com/evenbao/p/9252503.html
【代码】
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + ;
const int INF = 2e9; struct info
{
int d,pos;
}; int i,n,m,l,r,cnt,ans,len;
int a[MAXN],b[MAXN],val[MAXN],pre[MAXN],nxt[MAXN];
bool visited[MAXN];
info tmp; class Heap
{
private :
int tot;
info hp[MAXN];
public :
inline bool cmp(info a,info b)
{
return a.d < b.d;
}
inline void Up(int x)
{
if (x == ) return;
int fa = x >> ;
if (cmp(hp[x],hp[fa]))
{
swap(hp[x],hp[fa]);
Up(fa);
}
}
inline void Down(int x)
{
int son = x << ;
if (son > tot) return;
if ((son + <= tot) && cmp(hp[son+],hp[son])) son++;
if (cmp(hp[son],hp[x]))
{
swap(hp[son],hp[x]);
Down(son);
}
}
inline void insert(info x)
{
tot++;
hp[tot] = x;
Up(tot);
}
inline void del()
{
swap(hp[],hp[tot]);
tot--;
Down();
}
inline info get()
{
return hp[];
}
} H; int main()
{ scanf("%d%d",&n,&m);
for (i = ; i <= n; i++) scanf("%d",&a[i]);
while (n && a[n] <= ) n--;
i = ;
while (i <= n && a[i] <= ) i++;
if (i > n)
{
printf("%d\n",);
return ;
}
for (; i <= n; i++)
{
if ((a[i] > && a[i-] > ) || (a[i] <= && a[i-] <= )) b[len] += a[i];
else b[++len] = a[i];
}
for (i = ; i <= len; i++)
{
if (b[i] > )
{
ans += b[i];
cnt++;
} else b[i] = -b[i];
}
if (cnt <= m)
{
printf("%d\n",ans);
return ;
}
for (i = ; i <= len; i++)
{
pre[i] = i - ;
nxt[i] = i + ;
H.insert((info){b[i],i});
}
b[] = b[len+] = INF;
for (i = m; i < cnt; i++)
{
tmp = H.get();
while (visited[tmp.pos])
{
H.del();
tmp = H.get();
}
ans -= tmp.d;
H.del();
visited[pre[tmp.pos]] = true;
visited[nxt[tmp.pos]] = true;
b[tmp.pos] = b[pre[tmp.pos]] + b[nxt[tmp.pos]] - tmp.d;
nxt[pre[pre[tmp.pos]]] = tmp.pos;
pre[tmp.pos] = pre[pre[tmp.pos]];
pre[nxt[nxt[tmp.pos]]] = tmp.pos;
nxt[tmp.pos] = nxt[nxt[tmp.pos]];
H.insert((info){b[tmp.pos],tmp.pos});
}
printf("%d\n",ans); return ; }
【BZOJ 2288】 生日礼物的更多相关文章
- Bzoj 2288 生日礼物题解
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 856 Solved: 260[Submit][S ...
- 【链表】BZOJ 2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 382 Solved: 111[Submit][S ...
- bzoj 2288 【POJ Challenge】生日礼物 双向链表+堆优化
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1003 Solved: 317[Submit][ ...
- 【BZOJ 2288】 2288: 【POJ Challenge】生日礼物 (贪心+优先队列+双向链表)
2288: [POJ Challenge]生日礼物 Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超 ...
- BZOJ 2288 【POJ Challenge】生日礼物(贪心+优先队列)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2288 [题目大意] 给出一列数,求最多取m段连续的数字,使得总和最大 [题解] 首先我 ...
- BZOJ 2288: 【POJ Challenge】生日礼物 堆&&链表
就是堆+链表,十分像 数据备份 对吧? 把相邻的正数和相邻的负数合并成一整个正数块和负数块,最后只剩一些交替相间的正块与负块了吧? 显然,正块的个数<=m时,全部选走就获得了最大权值,否则我们可 ...
- bzoj 2288: 【POJ Challenge】生日礼物【链表+堆】
参考:http://blog.csdn.net/w_yqts/article/details/76037315 把相同符号的连续数字加起来,合并后ans先贪心的加上所有正数,如果正数个数sum> ...
- BZOJ 2288: 【POJ Challenge】生日礼物 贪心 + 堆 + 链表
好像是模拟费用流 Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r" ...
- [BZOJ 1293] 生日礼物
Link: BZOJ 1293 传送门 Solution: 这题直接上尺取法就行了吧 先将每种颜色第一个放入优先队列,用$mx$维护当前的末尾位置 每次取出第一个颜色,更新答案.将其下一个放入队列中去 ...
随机推荐
- MySQL主从备份配置
MySQL主从热备配置 两台服务器的MySQL版本都是5.5.41master:192.168.3.119slave:192.168.3.120 MySQL主服务器配置:1.创建用于备份的用户 gra ...
- 通过offset值的设置使html元素对齐
今天是我第一次写这个随笔,为了记录我发现的一个jquery的offset的值的问题. 这个offset的值会因为页面标签是否处于隐藏状态而表现出不同的值,隐藏状态时,offset的值是相对于直接父亲的 ...
- tab切换案例
做个简单的tab切换效果,分别于jquery和js操作 (1)jQuery操作 先看下效果: <!DOCTYPE html> <html lang="en"> ...
- yum仓库配置ftpx协议
[root@localhost ~]# iptables -F[root@localhost ~]# systemctl stop firewalld[root@localhost ~]# syste ...
- 2 Button
// <summary> /// 设置透明按钮样式 /// </summary> private void SetBtnStyle(Button btn) { btn.Flat ...
- 18清明校内测试T2
一道数论好题(math) Time Limit:1000ms Memory Limit:128MB 题目描述 rsy最近在研究欧几里得算法,不会的同学可以去看下课件以及代码…… 现在她想到了一个新 ...
- R 安装car包失败
在RStudio里安装car包的时候报错 /usr/bin/ld: cannot find -llapack /usr/bin/ld: cannot find -lblas make: *** [qu ...
- PHP常用系统设置整理
1.设置时间脚本执行时间 set_time_limit(0); 2.设置最大执行内存 ini_set('memory_limit','1024M');//设置内存 memory_get_usage() ...
- git 的简单使用(3)
Git鼓励大量使用分支: 查看分支:git branch 创建分支:git branch <name> 切换分支:git checkout <name> 创建+切换分支:git ...
- 8.1.3 Row对象
假设数据以下面的方式创建并插入数据: import sqlite3 conn = sqlite3.connect(r'D:\test.db') c = conn.cursor() c.execute( ...