2288: 【POJ Challenge】生日礼物

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 382  Solved: 111
[Submit][Status][Discuss]

Description

ftiasch 18岁生日的时候,lqp18_31给她看了一个神奇的序列 A1A2, ..., AN. 她被允许选择不超过 M 个连续的部分作为自己的生日礼物。

自然地,ftiasch想要知道选择元素之和的最大值。你能帮助她吗?

 

Input

第1行,两个整数 N (1 ≤ N ≤ 105) 和 M (0 ≤ M ≤ 105), 序列的长度和可以选择的部分。

第2行, N 个整数 A1A2, ..., AN (0 ≤ |Ai| ≤ 104), 序列。

Output

一个整数,最大的和。

Sample Input

5 2
2 -3 2 -1 2

Sample Output

5

  先把相邻同号元素合并。
  如果能够全选正数就全选。。
  把所有数的绝对值入堆选前(正数个数-可选最大集合数个).
  选正数的意义-->不选该数
  选负数-->合并两边的正数
  每次减掉堆顶元素的fabs即可。
  和1150差不多的堆+链表
 #include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue> #define maxn 100001 inline int in()
{
int x=,f=;char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-')f=-,ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return f*x;
} struct node{
int x,c,ac;
bool operator<(const node &A)const{
return ac>A.ac;
}
}; using namespace std; priority_queue<node>q; int n,k,a[maxn*],sum=,pre[maxn*],next[maxn*],nowa[maxn*],tot=,ss=; bool vis[maxn*]; void solve()
{
int size=tot+;
for(int i=;i<=tot;i++)q.push((node){i,nowa[i],fabs(nowa[i])});
for(int i=;i<=ss;i++)
{
node Top=q.top();q.pop();
while(vis[Top.x])Top=q.top(),q.pop();
if(!pre[Top.x])
{
if(Top.c<){i--;}
else{sum-=Top.ac;}
vis[Top.x]=;
pre[next[Top.x]]=;
continue;
}
else if(next[Top.x]==tot+)
{
if(Top.c<){i--;}
else{sum-=Top.ac;}
vis[Top.x]=;
next[pre[Top.x]]=tot+;
continue;
}
node New;
sum-=Top.ac;
New.c=nowa[pre[Top.x]]+nowa[next[Top.x]]+Top.c;
New.x=++size;
nowa[size]=New.c;
next[New.x]=next[next[Top.x]],pre[next[New.x]]=New.x;
pre[New.x]=pre[pre[Top.x]],next[pre[New.x]]=New.x;
vis[Top.x]=vis[pre[Top.x]]=vis[next[Top.x]]=;
New.ac=fabs(New.c);
q.push(New);
}
} void Pre()
{
tot=;
for(int i=;i<=n;i++)
{
if(!a[i])continue;
else if(!nowa[tot])nowa[tot]=a[i];
else{
if(nowa[tot]>&&a[i]>)nowa[tot]+=a[i];
else if(nowa[tot]<&&a[i]<)nowa[tot]+=a[i];
else nowa[++tot]=a[i];
}
}
for(int i=;i<=tot;i++)next[i]=i+,pre[i]=i-;
next[]=,pre[tot+]=tot;
} int main()
{
n=in();k=in();
for(int i=;i<=n;i++)a[i]=in();
Pre();
for(int i=;i<=tot;i++)if(nowa[i]>)ss++,sum+=nowa[i];
if(ss<=k){printf("%d",sum);return ;}
ss-=k;
solve();
printf("%d",sum);
return ;
}
 

最新文章

  1. swift错误 Expressions are not allowed at the top level
  2. 谈谈jQuery之绑定事件
  3. linux下mysql开启关和重启
  4. Python与Hack之window下运行带参数的Python脚本,实现一个简单的端口扫描器
  5. (算是dp吧) 小茗的魔法阵 (fzu 2225)
  6. atititt.java定时任务框架选型Spring Quartz 注解总结
  7. 【CodeForces 621B】Wet Shark and Bishops
  8. hashtable 实现
  9. web2py--------------用web2py写 django的例子 --------建立一个投票应用(3)
  10. OFFSET &amp; FETCH
  11. AnonymousType匿名类型和对象之间的转换
  12. 【转】JAVA程序中Float和Double精度丢失问题
  13. BZOJ 1006: [HNOI2008]神奇的国度( MCS )
  14. HDU 2516 取石子游戏 斐波纳契博弈
  15. 内存不够怎么办? 1.5.1 关于隔离 1.5.2 分段(Segmention) 1.5.3 分页(Paging)
  16. svn 设置 excel 比对工具为 SPREADSHEETCOMPARE.EXE
  17. [Go] Returning Multiple Values from a Function in Go
  18. Atcoder Tenka1 Programmer Contest 2019题解
  19. git branch 误删 分支 找回
  20. 算法之杨辉三角形(Java语言)

热门文章

  1. 关于delegate, category和subclass
  2. linux中FTP自动备份VPS脚本
  3. iOS开发——Touch ID 指纹识别
  4. 利用图层的mask属性裁剪图形
  5. iOS预处理指令
  6. c# DataGridView操作
  7. (转)19个必须知道的Visual Studio快捷键
  8. (转)MongoDb的十个使用要点
  9. 双网卡route配置
  10. Git 的简单使用