BZOJ 2288 【POJ Challenge】生日礼物(贪心+优先队列)

【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=2288

【题目大意】

  给出一列数,求最多取m段连续的数字,使得总和最大

【题解】

  首先我们对数据进行合并处理,连续的一段正数或者连续的一段负数处理成一个数字,
  之后我们发现,如果正数的个数小于等于m,那么直接输出正数的总和即可,
  如果大于m,我们有些正数不选,或者选择一些负数把左右两端的正数并起来。
  这个负数的选择过程相当于减去这个数的绝对值,
  正数选择拿出去的过程也相当于减去这个数的绝对值,
  在选择一个负数合并的过程中,两边的正数必须是没有被操作过的,
  同样,选择一个正数删去的过程中,两边的负数肯定也必须是没有操作过的,
  那么问题就转化为,给你一些数,请你选择其中k个不相邻的数,使得其和最小,
  等同于BZOJ 1150 [CTSC2007]数据备份Backup

【代码】

#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
typedef pair<int,int> P;
const int N=100010;
const int INF=0x3f3f3f3f;
int n,m,a[N],b[N],l[N],r[N];
int main(){
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        while(a[n]<=0)n--;int st=1;
        while(a[st]<=0)st++;
        int cnt=0,ans=0;
        for(;st<=n;st++){if(!((a[st]>0)^(a[st-1]>0)))b[cnt]+=a[st];else b[++cnt]=a[st];}
        for(int i=1;i<=cnt;i++)if(b[i]>0){ans+=b[i];m--;}else b[i]=-b[i];
        if(m>=0){printf("%d\n",ans);continue;}
        priority_queue<P,vector<P>,greater<P> >Q;
        for(int i=1;i<=cnt;i++)l[i]=i-1,r[i]=i+1,Q.push(P(b[i],i));
        r[cnt]=0;
        for(int i=1;i<=-m;i++){
            while(b[Q.top().second]!=Q.top().first)Q.pop();
            int x=Q.top().second;Q.pop();
            ans-=b[x];
            if(!l[x]){b[r[x]]=INF;l[r[x]]=0;}
            else if(!r[x]){b[l[x]]=INF;r[l[x]]=0;}
            else{
                b[x]=b[l[x]]+b[r[x]]-b[x];
                b[l[x]]=b[r[x]]=INF;
                r[l[x]=l[l[x]]]=l[r[x]=r[r[x]]]=x;
                Q.push(P(b[x],x));
            }
        }printf("%d\n",ans);
    }return 0;
}
时间: 2024-08-29 14:41:25

BZOJ 2288 【POJ Challenge】生日礼物(贪心+优先队列)的相关文章

POJ 1862 Stripies 贪心+优先队列

http://poj.org/problem?id=1862 题目大意: 有一种生物能两两合并,合并之前的重量分别为m1和m2,合并之后变为2*sqrt(m1*m2),现在给定n个这样的生物,求合并成一个的最小重量 思路: m1+m2 >=  2*sqrt(m1*m2) 所以每次取大的去合并,能变小. 直接优先队列就可以啦. #include<cstdio> #include<cmath> #include<queue> using namespace std;

poj -3614 Sunscreen(贪心 + 优先队列)

http://poj.org/problem?id=3614 有c头奶牛在沙滩上晒太阳,每头奶牛能忍受的阳光强度有一个最大值(max_spf) 和最小值(min_spf),奶牛有L种防晒霜,每种可以固定阳光强度在某一个值,每种的数量是cover[i] ,每头奶牛只能用一瓶防晒霜,问最多有多少头奶牛能在沙滩上晒太阳. 理解题意之后还是挺好做的. 首先确定的贪心策略是,在满足min_spf的条件下,尽量用spf小的用在max_spf大的奶牛身上,用一个最小堆维护max_spf的最小值即可. 先对奶牛

[bzoj2288][POJ Challenge]生日礼物

用堆维护双向链表来贪心... 数据范围显然不容许O(nm)的傻逼dp>_<..而且dp光是状态就n*m个了..显然没法优化 大概就会想到贪心乱搞了吧...一开始想贪心地通过几段小的负数把正数连接成一段,但到底是要连接在一起还是直接扔掉不好判断 然后就跑去翻题解了...题解讲的挺好的,连我都看懂了>_<..题解网址:http://www.cnblogs.com/tuigou/p/4868127.html 虽然选正数和负数的意义不同,但实际的操作都是把两边的数合并起来.还有就是,对于在

BZOJ 2287 POJ Challenge 消失之物

BZOJ题目不完整,看了看题解.发现他们都要取模10,还以为是dp的限制.改了两小时,之后猛然发现.卧槽原本我少了一个取模. 写法1:暴力写法最简单的想法(只要你会背包dp)我在枚举每次不选哪个物品做01背包,时间复杂度 O(N*N*M) 卡一卡常就跑过去了 #include <cstdio> #include <algorithm> #include <cstring>    int n,m; int w[3005]; int dp[4000005];    int

BZOJ 2287 POJ Challenge 消失之物 分治+背包

题目大意:给定n个物品,每个物品有一个体积,对于所有的1≤i≤n,1≤j≤m输出在不使用第i个物品的情况下装满大小为j的背包的方案数 我这傻逼居然真的去写了分治背包-- 第i个物品存在的时间为[1,i?1]和[i+1,n]两个区间 然后分治-- 时间复杂度O(n2logn) 黄学长我仰慕您 #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include &

poj 2431 Expedition 贪心+优先队列

Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7707   Accepted: 2263 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor drivers, the cows unfortunately managed to

【BZOJ 2288】 2288: 【POJ Challenge】生日礼物 (贪心+优先队列+双向链表)

2288: [POJ Challenge]生日礼物 Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知道选择元素之和的最大值.你能帮助她吗? Input 第1行,两个整数 N (1 ≤ N ≤ 105) 和 M (0 ≤ M ≤ 105), 序列的长度和可以选择的部分. 第2行, N 个整数 A1, A2, ..., AN (0

Bzoj 2288 生日礼物题解

2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 856  Solved: 260[Submit][Status][Discuss] Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知道选择元素之和的最大值.你能帮助她吗? Input

BZOJ2288: 【POJ Challenge】生日礼物

2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 771  Solved: 238[Submit][Status][Discuss] Description ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1, A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物. 自然地,ftiasch想要知道选择元素之和的最大值.你能帮助她吗? Input

poj 2431 Expedition (贪心+优先队列)

Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6890   Accepted: 2065 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor drivers, the cows unfortunately managed to