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 }
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 }