bzoj 1150&2151&2288(双向链表+堆)(贪心)
经典模型:在n个点中选k个点,要求两两不相邻,且总权值最大/最小。
做法:用双向链表串起来,把所有点丢进堆里,选择一个点的时候把它左右两个点从双向链表和堆中去除,然后把这个点的权值加进ans,出堆后改为左右两边的权值-当前权值重新入堆,重复k次,ans即为答案
原理:左右两边的权值-当前权值相当于这个点不选,改为选左右两边的点,并且多选了一个点,重复k次后必然取到k个点
三道同类型题
bzoj1150:显然一段网线肯定接在相邻的两个点,于是把相邻的点的距离求出来,问题就变成经典模型了
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
const int maxn=,inf=1e9;
struct poi{int pos,dis;};
priority_queue<poi>q;
bool operator<(poi a,poi b){return a.dis>b.dis;}
int n,k,a[maxn],dis[maxn],pre[maxn],next[maxn];
ll ans;
bool v[maxn];
void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
inline void del(int x)
{
int l=pre[x],r=next[x];
pre[x]=next[x]=;
next[l]=r;pre[r]=l;
}
int main()
{
read(n);read(k);
for(int i=;i<=n;i++)read(a[i]);
for(int i=;i<n;i++)dis[i]=a[i+]-a[i],q.push((poi){i,dis[i]});dis[]=dis[n]=inf;
for(int i=;i<n;i++)pre[i]=i-,next[i]=i+;
for(int i=;i<=k;i++)
{
poi t=q.top();
while(v[t.pos])q.pop(),t=q.top();
ans+=t.dis;v[pre[t.pos]]=v[next[t.pos]]=;
dis[t.pos]=dis[pre[t.pos]]+dis[next[t.pos]]-dis[t.pos];
q.pop();q.push((poi){t.pos,dis[t.pos]});
del(pre[t.pos]);del(next[t.pos]);
}
printf("%lld\n",ans);
return ;
}
bzoj2151:双向链表首尾串起来,问题就变成经典模型了
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
const int maxn=,inf=1e9;
struct poi{int pos,dis;};
priority_queue<poi>q;
bool operator<(poi a,poi b){return a.dis<b.dis;}
int n,k,a[maxn],dis[maxn],pre[maxn],next[maxn];
ll ans;
bool v[maxn];
void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
inline void del(int x)
{
int l=pre[x],r=next[x];
pre[x]=next[x]=;
next[l]=r;pre[r]=l;
}
int main()
{
read(n);read(k);
if(k>n>>)return puts("Error!"),;
for(int i=;i<=n;i++)read(dis[i]),q.push((poi){i,dis[i]});
for(int i=;i<=n;i++)pre[i]=i-,next[i]=i+;pre[]=n;next[n]=;
for(int i=;i<=k;i++)
{
poi t=q.top();
while(v[t.pos])q.pop(),t=q.top();
ans+=t.dis;v[pre[t.pos]]=v[next[t.pos]]=;
dis[t.pos]=dis[pre[t.pos]]+dis[next[t.pos]]-dis[t.pos];
q.pop();q.push((poi){t.pos,dis[t.pos]});
del(pre[t.pos]);del(next[t.pos]);
}
printf("%lld\n",ans);
return ;
}
bzoj2288:
这题比较复杂。首先可以发现正数连续的一段和负数连续的一段要取肯定是都得同时取的,那么就可以把连续的同正负的数缩成一个了。然后如果正数个数不大于k,直接取所有正数即可。如果正数个数大于k,我们考虑舍弃一些正数,或者选择一些负数。只要将所有数取绝对值,问题就变成经典模型了。为什么呢?
我们选择的是总权值最小的数,如果他是个正数,相当于舍弃,如果是负数,相当于把左右两端的正数连成一段。显然不可能同时选两个相邻的数,否则一定是正负一起选,那负数完全可以不选,因为既然你要丢弃这个正数,为何还要选择一个负数呢,选择负数的作用只有连接左右两端的正数。
因此,这个题也能转化为经典模型,就可以写了。
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<map>
#define ll long long
using namespace std;
const int maxn=,inf=1e9;
struct poi{int pos,dis;};
priority_queue<poi>q;
bool operator<(poi a,poi b){return a.dis>b.dis;}
int n,m,flag,N,now,l,r,ans;
int a[maxn],s[maxn],pre[maxn],next[maxn];
bool v[maxn];
void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
inline void del(int x)
{
int l=pre[x],r=next[x];
pre[x]=next[x]=;
pre[r]=l;next[l]=r;
}
int main()
{
read(n);read(m);
for(int i=;i<=n;i++)read(a[i]);
int l=,r=n;
while(a[l]<=&&l<=n)l++;
while(a[r]<=&&r)r--;
for(int i=l;i<=r;)
{
if(a[i]>=)flag=;else flag=-;
for(now=;flag*a[i]>=&&i<=r;i++)now+=a[i];
s[++N]=now;
}
for(int i=;i<=N;i+=)ans+=s[i];
if(m>=(N+)>>)return printf("%d\n",ans),;
for(int i=;i<=N;i++)q.push((poi){i,s[i]=(s[i]>?s[i]:-s[i])});
for(int i=;i<=N;i++)pre[i]=i-,next[i]=i+;s[]=inf;s[N+]=inf;
int up=((N+)>>)-m;
for(int i=;i<=up;i++)
{
poi t=q.top();
while(v[t.pos])q.pop(),t=q.top();q.pop();
s[t.pos]=s[pre[t.pos]]+s[next[t.pos]]-s[t.pos];
ans-=t.dis;q.push((poi){t.pos,s[t.pos]});
v[pre[t.pos]]=v[next[t.pos]]=;
del(pre[t.pos]);del(next[t.pos]);
}
printf("%d\n",ans);
return ;
}
bzoj 1150&2151&2288(双向链表+堆)(贪心)的更多相关文章
- BZOJ 1029: [JSOI2007]建筑抢修 堆+贪心
1029: [JSOI2007]建筑抢修 Description 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有 ...
- BZOJ 1150--数据备份(链表&堆&贪心)
1150: [CTSC2007]数据备份Backup Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2572 Solved: 1038[Submit ...
- [BZOJ 1150] [CTSC2007] 数据备份Backup 【贪心 + 链表】
题目链接:BZOJ - 1150 题目分析 可以看出,我们选的 k 条边一定是相邻两点之间的线段.我们可以将每条边看成一个点,那么我们就是要在 n-1 个点中选出互不相邻的 k 个,使它们的和最小. ...
- [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)
[BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...
- 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)
洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...
- BZOJ_2802_[Poi2012]Warehouse Store_堆+贪心
BZOJ_2802_[Poi2012]Warehouse Store_堆+贪心 Description 有一家专卖一种商品的店,考虑连续的n天. 第i天上午会进货Ai件商品,中午的时候会有顾客需要购买 ...
- BZOJ_1150_[CTSC2007]数据备份Backup_堆+贪心
BZOJ_1150_[CTSC2007]数据备份Backup_堆+贪心 Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏 ...
- P4053 [JSOI2007]建筑抢修 堆贪心
思路:堆贪心 提交:1次 题解: 先按时间\(sort\),然后如果能修就直接扔堆里,不能修取堆顶比一下时间长短,把时间短的扔进堆: #include<cstdio> #include&l ...
- HDU5124lines题解-堆+贪心的一个新方法
题目链接 https://cn.vjudge.net/problem/HDU-5124 胡扯 感觉说新方法好像有点不太好,但是翻了十几篇博客都是清一色离散化之类的... 为什么会做这道题呢?因为前几天 ...
随机推荐
- hdu1848Fibonacci again and again(sg函数)
Fibonacci again and again Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...
- 如何理解一台服务器可以绑定多个ip,一个ip可以绑定多个域名
一个域名只能对应一个IP的意思是域名在DNS服务器里做解析的时候 一条记录只能指向一个IP地址.这个是死规定,试想一下,如果一个子域名指向了2个ip ,当访问者打开这个域名的时候,浏览器是展示哪个IP ...
- 学好三角学(函数) — SWIFT和JAVASCRIPT游戏开发的必备技能 iFIERO.com
不论是使用哪种平台进行开发,三角学在游戏当中都被广泛的使用,因此,小编iFERO认为,三角学是必须得掌握的技能之一. 游戏图片由 摘自 Razeware LLC 先以Javascript为例 一.角度 ...
- 1.1.0 Unity零基础入门2——Roll a Ball
1. 游戏界面 2.代码 //FoodRotate - - 控制cube旋转 using System.Collections; using System.Collections.Generic; u ...
- 一键部署pxe环境
系统:Centos6.5 环境:VMware Workstation12 #!/bin/bash # Please prepare CentOS ISO image first # root pass ...
- Elasticsearch 相同内容文档,不同score(评分)的奇怪问题
原文:http://stackoverflow.com/questions/14580752/elasticsearch-gives-different-scores-for-same-documen ...
- UVa 1586 - Molar Mass - ACM/ICPC Seoul 2007 - C语言
关键在于判断数字是两位数还是单位数,其他部分没有难度. #include"stdio.h" #include"string.h" #include"c ...
- 为什么安装beego和框架的失败 以及常用命令
1.安装了几个版本,版本之间相互影响. 把没用的删掉 2.网上找的教程存在问题. 都是相互抄袭.最权威的还是官网. which go rm -rf test/ echo path 获取路径 vim ~ ...
- Linux error:No space left on device
一台Oracle数据库服务器在关机重启后,Oracle监听无法启动,提示错误 Linux error:no space left on device 提示可知:问题是出在磁盘空间不足 但是初步查看分区 ...
- 【转】Backbone.js学习笔记(二)细说MVC
文章转自: http://segmentfault.com/a/1190000002666658 对于初学backbone.js的同学可以先参考我这篇文章:Backbone.js学习笔记(一) Bac ...