bzoj 2151 种树

题目大意:

n个数组成的环中取m个互不相邻的数使这些数和最大

思路:

贪心 先用链表把数存起来

然后每次选一个最大的$a[x]$,把链表左右两边的删掉

把这个值替换为$a_{left[x]}+a_{right[x]}-a_x$ 这样在堆里重复m次即可

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<stack>
 9 #include<queue>
10 #include<map>
11 #define rep(i,s,t) for(register int i=(s),i__end=(t);i<=i__end;++i)
12 #define dwn(i,s,t) for(register int i=(s),i__end=(t);i>=i__end;--i)
13 #define ren for(int i=fst[x];i;i=nxt[i])
14 #define Fill(x,t) memset(x,t,sizeof(x))
15 #define ll long long
16 #define ull unsigned long long
17 #define inf 1LL<<60
18 #define MAXN 200100
19 #define MOD 998244353
20 using namespace std;
21 inline int read()
22 {
23     int x=0,f=1;char ch=getchar();
24     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
25     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
26     return x*f;
27 }
28 int n,m,g[MAXN],ans,r[MAXN],l[MAXN],vis[MAXN];
29 struct data {int id,val;};
30 bool operator < (const data a,const data b) {return a.val<b.val;}
31 bool operator == (const data a,const data b) {return a.val==b.val&&a.id==b.id;}
32 priority_queue <data> q;
33 void work()
34 {
35     while(vis[q.top().id]) q.pop();data x=q.top();ans+=x.val;q.pop();
36     g[x.id]=g[l[x.id]]+g[r[x.id]]-g[x.id],vis[l[x.id]]=vis[r[x.id]]=1;
37     q.push((data){x.id,g[x.id]});r[l[l[x.id]]]=l[r[r[x.id]]]=x.id;
38     l[x.id]=l[l[x.id]],r[x.id]=r[r[x.id]];
39 }
40 int main()
41 {
42     n=read(),m=read();if(m>(n>>1)) {puts("Error!");return 0;}rep(i,1,n) g[i]=read(),q.push((data){i,g[i]});
43     rep(i,1,n) l[i]=i-1,r[i]=i+1;l[1]=n,r[n]=1;rep(i,1,m) work();printf("%d\n",ans);
44 }
View Code

bzoj 1150 数据备份

几乎同上,由于一定选相邻的两个建筑,将问题转换为n-1个数构成的链取$m$个互不相邻的数使和最大

做的时候开一个空节点,构成环,该点值为inf

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #include<cstring>
 7 #include<vector>
 8 #include<stack>
 9 #include<queue>
10 #include<map>
11 #define rep(i,s,t) for(register int i=(s),i__end=(t);i<=i__end;++i)
12 #define dwn(i,s,t) for(register int i=(s),i__end=(t);i>=i__end;--i)
13 #define ren for(int i=fst[x];i;i=nxt[i])
14 #define Fill(x,t) memset(x,t,sizeof(x))
15 #define ll long long
16 #define ull unsigned long long
17 #define inf 1000000007
18 #define MAXN 1001000
19 #define MOD 998244353
20 using namespace std;
21 inline int read()
22 {
23     int x=0,f=1;char ch=getchar();
24     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
25     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
26     return x*f;
27 }
28 int n,m,g[MAXN],r[MAXN],l[MAXN],vis[MAXN];
29 ll ans;
30 struct data {int id;ll val;};
31 bool operator < (const data a,const data b) {return a.val>b.val;}
32 priority_queue <data> q;
33 void work()
34 {
35     while(vis[q.top().id]) q.pop();data x=q.top();ans+=x.val;q.pop();
36     g[x.id]=g[l[x.id]]+g[r[x.id]]-g[x.id],vis[l[x.id]]=vis[r[x.id]]=1;
37     q.push((data){x.id,g[x.id]});r[l[l[x.id]]]=l[r[r[x.id]]]=x.id;
38     l[x.id]=l[l[x.id]],r[x.id]=r[r[x.id]];
39 }
40 int main()
41 {
42     n=read(),m=read();rep(i,1,n) g[i]=read();rep(i,1,n-1) g[i]=g[i+1]-g[i];
43     rep(i,1,n-1) q.push((data){i,g[i]});
44     rep(i,1,n-1) l[i]=i-1,r[i]=i+1;l[1]=n,g[n]=inf;
45     rep(i,1,m) work();printf("%lld\n",ans);
46 }
View Code

 

posted @ 2018-12-26 07:52  jack_yyc  阅读(139)  评论(0编辑  收藏  举报