Codeforces Round #695 (Div. 2) C. Three Bags (貪心,思維)
阿新 • • 發佈:2021-01-19
- 題意:有三個揹包,每個揹包裡都用一些數字,你可以選擇某一個揹包的數字\(a\),從另外一個揹包拿出\(b\)(拿出之後就沒有了),然後將\(a\)替換為\(a-b\),你可以進行任意次這樣的操作,使得最後只剩下一個數,問這個數最大能是多少.
- 題解:我的思路是,先任意選兩個揹包,假設\(x\)和\(y\),我們假設選\(x\)中的最大值,\(y\)中的最小值,很明顯,我們讓\(y\)的最小值減去沒有選的揹包的所有數和除了\(x\)最大值的所有數一定是最優的,但是\(y\)中除了最小值的其他數不好處理,這裡我們可以先讓\(x\)中的最小值減去\(y\)除了最小值的其他數,因為小的減大的可以使貢獻損失最小,這裡要注意,假如減完後,\(x\)
- 程式碼:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int n1,n2,n3; ll s1,s2,s3; int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); cin>>n1>>n2>>n3; vector<ll> a(n1),b(n2),c(n3); for(auto &w:a) cin>>w,s1+=w; for(auto &w:b) cin>>w,s2+=w; for(auto &w:c) cin>>w,s3+=w; n1--,n2--,n3--; sort(a.begin(),a.end()); sort(b.begin(),b.end()); sort(c.begin(),c.end()); ll ans=0; //max_1,min_2 ll sum1=s1-a[n1]-a[0]; ll sum2=s2-b[0]; ll sum3=s3; ans=max(ans,a[n1]-(b[0]-sum3-sum1-abs(a[0]-sum2))); //max_1,min_3 sum1=s1-a[n1]-a[0]; sum2=s2; sum3=s3-c[0]; ans=max(ans,a[n1]-(c[0]-sum2-sum1-abs(a[0]-sum3))); //max_2,min_1 sum1=s1-a[0]; sum2=s2-b[n2]-b[0]; sum3=s3; ans=max(ans,b[n2]-(a[0]-sum3-sum2-abs(b[0]-sum1))); //max_2,min_3 sum1=s1; sum2=s2-b[n2]-b[0]; sum3=s3-c[0]; ans=max(ans,b[n2]-(c[0]-sum1-sum2-abs(b[0]-sum3))); //max_3,min_1 sum1=s1-a[0]; sum2=s2; sum3=s3-c[n3]-c[0]; ans=max(ans,c[n3]-(a[0]-sum2-sum3-abs(c[0]-sum1))); //max_3,min_2 sum1=s1; sum2=s2-b[0]; sum3=s3-c[n3]-c[0]; ans=max(ans,c[n3]-(b[0]-sum1-sum3-abs(c[0]-sum2))); cout<<ans<<'\n'; return 0; }