BZOJ 2288: 【POJ Challenge】生日礼物 贪心 + 堆 + 链表
好像是模拟费用流
Code:
#include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define P pair<int,int> #define ll long long #define maxn 100007 using namespace std; int arr[maxn],l[maxn],r[maxn],mark[maxn]; priority_queue<P, vector<P>, greater<P> >q; void del(int x) { l[r[x]]=l[x], r[l[x]]=r[x]; mark[x]=1; } int main() { // setIO("input"); int n,m,tmp=0,cnt=0; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { int x; scanf("%d",&x); if(!x) continue; if(1ll*arr[tmp]*x>0) arr[tmp]+=x; else arr[++tmp]=x; } n=tmp; int sum=0; for(int i=1;i<=n;++i) { l[i]=i-1,r[i]=i+1; if(arr[i] > 0) ++cnt, sum+=arr[i]; q.push(make_pair(abs(arr[i]), i)); } while(cnt > m) { while(mark[q.top().second]) q.pop(); int x=q.top().second; q.pop(); if((l[x]&&r[x]!=n+1) || arr[x] > 0) { sum-=abs(arr[x]); arr[x]+=arr[l[x]] + arr[r[x]]; del(l[x]), del(r[x]); --cnt; q.push(make_pair(abs(arr[x]), x)); } else del(x); } printf("%d\n",sum); return 0; }