C: C - Gambling
给你两个数列 每一回合A可以选择从第一个序列里面选一个数或者清除第二个序列里面选一个数 同理B能从第二序列里面选数或者清除第一个序列里面一个数
然后 求A所选的数之和-B所选数之和最大
贪心就行 两个优先队列每次比较另外一个序列最大的数是比自己序列最大的数大还是小 大就删除另一个序列的数 小就加上自己序列最大的数
可能会爆int QAQ
#include<bits/stdc++.h> using namespace std; #define LL long long priority_queue <LL ,vector<LL >,less<LL > >q,w; int main(){ LL n; cin>>n; for(LL j=0;j<n;j++){ LL x; cin>>x; q.push(x); } for(LL j=0;j<n;j++){ LL x; cin>>x; w.push(x); } for(LL j=0;j<n/2;j++){ q.push(0); w.push(0); } LL l=0; LL ans=0,ans1=0; while(!q.empty()&&!w.empty()){ LL x=q.top(),y=w.top(); if(l%2==0){ if(x<y) w.pop(); else{ ans+=x; q.pop(); } }else{ if(x>y) q.pop(); else{ ans1+=y; w.pop(); } } l++; } cout<<ans-ans1<<endl; return 0; }
给你一个序列 每次可以选两个相邻的数 组合成一个新的数 结果为 A-B
让你求当合并到一个数的时候求这个数的最大值
当全是正数(>=0) 或者全是负数的时候直接求出来最大最小 然后序列求和 减去最大或者最小*2 就可以了
当正负数组合时 就直接对序列求和
当时没考虑完全 代码有点乱
#include<bits/stdc++.h> using namespace std; #define LL long long #define inf 0x3f3f3f3f #define maxn 500000+50 LL a[maxn]; int main(){ int n,x=0; cin>>n; bool fa=0; for(int j=0;j<n;j++){ scanf("%lld",&a[j]); if(a[j]<0) fa=1; } if(n==1) cout<<a[0]<<endl; else if(n==2){ cout<<max(a[0]-a[1],a[1]-a[0])<<endl; }else{ LL ans=0; if(fa==0){ LL mi=inf; for(int j=0;j<n;j++){ mi=min(mi,a[j]); ans+=abs(a[j]); } ans-=mi*2; cout<<ans<<endl; return 0; }else{ LL i=0; for(int j=0;j<n;j++){ if(a[j]<0) i++; } if(i!=n){ for(int j=0;j<n;j++){ ans+=abs(a[j]); } cout<<ans<<endl; return 0; }else{ LL mi=-inf; for(int j=0;j<n;j++){ mi=max(mi,a[j]); ans+=abs(a[j]); } ans+=mi*2; cout<<ans<<endl; return 0; } } } return 0; }