1. 程式人生 > 其它 >codeforces 1467C. Three Bags

codeforces 1467C. Three Bags

談談心路歷程:

模擬完樣例後直覺挑出合法的最大和最小(不在一個包裡)

讓最小減去最大,然後如果最小所在的集合只有它自己的話,就可以開始瘋狂堆了。

但樣例2告訴我們可能最小所在的集合可能不只有自己,那麼最小的小夥伴一定要被吃掉。

我們就要在剔除前面已經用過的兩個數的情況下,再跑一次上述流程。

理論上是對的,實現起來我不會寫。

在寫的演算法又長又爛的過程中,發現:

-a-b+abs(a-b)等價於-min(a,b)*2;

那麼取最大那步可以去掉了。

再緊接著,怎麼優化如果最小的集合不只有自己的情況?

標解是暴力。

我對暴力有了更深的理解——管它什麼情況,統統算一下取極值好了!

這就是6種情況的由來:

其中ans-min1*2-min2*2....,指的就是最小所在的集合不只有自己,要再湊一個;

而ans1+ans2-ans3,就是最小所在的集合只有自己,通過模擬發現這樣操作實際上只有最小的貢獻是負的。

坑點是:

#不開longlong見祖宗

#final=max(final,xxx)

不能寫成final=max(xxx,yyy;

再final=max(zzz,ppp);

..(我的問題

#include<bits/stdc++.h>
using namespace std;
int main( )
{ long long a,b,c,ans=0,ans1=0,ans2=0,ans3=0
,m1,m2,m3; // freopen("lys.in","r",stdin); cin>>a>>b>>c; m1=m2=m3=0x3f3f3f3f; for(int i=1;i<=a;i++) { long long x; cin>>x; ans1+=x; ans+=x; m1=min(m1,x); } for(int i=1;i<=b;i++) { long
long x; cin>>x; ans2+=x; ans+=x; m2=min(m2,x); } for(int i=1;i<=c;i++) { long long x; cin>>x; ans3+=x; ans+=x; m3=min(m3,x); } long long final; final=max(max(ans-m1*2-m3*2,ans-m2*2-m3*2),ans-m1*2-m2*2); final=max(final,max(max(ans1+ans2-ans3,ans2+ans3-ans1),ans1+ans3-ans2)); //q p t printf("%lld\n",final); }