1. 程式人生 > 實用技巧 >洛谷P1842 [USACO05NOV]奶牛玩雜技——題解

洛谷P1842 [USACO05NOV]奶牛玩雜技——題解

題目傳送

卡在此題,貪心不過關。

對於任意的牛,她的壓扁指數等於摞在她上面的所有奶牛的總重(當然不包括她自己)減去它的力量。可見題中兩個資料:重量w和力量s是1:1加減法轉化的,於是有按照該牛重量+力量來排序的貪心策略。證明:若有相鄰兩牛x和y,有wx+sx<wy+sy,則有wx-sy<wy-sx,即x牛放y牛上答案更優,可知對於最終的答案序列,w+s一定為不下降排列;再考慮是否最優:若最終答案序列與貪心得出的不一樣,由於各w+s各不相同時從小到大的排序只有一個(相同時也無妨,因為不會影響答案,即wx+sx=wy+sy => wx-sy=wy-sx),則只能是最終答案序列存在逆序對,就不是最終答案了,矛盾,故知貪心策略正確。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 
 5 using namespace std;
 6 
 7 const int N=50005;
 8 
 9 int w[N],s[N],xu[N],n;
10 
11 inline int read()
12 {
13     int x=0;
14     char ch=getchar();
15     while(!isdigit(ch)) ch=getchar();
16     while(isdigit(ch)) x=(x<<3
)+(x<<1)+(ch^48),ch=getchar(); 17 return x; 18 } 19 20 inline bool cmp(const int &a,const int &b) 21 { 22 return w[a]+s[a]<w[b]+s[b]; 23 } 24 25 int main() 26 { 27 n=read(); 28 for(int i=1;i<=n;++i) 29 { 30 w[i]=read();s[i]=read();xu[i]=i; 31 } 32 sort(xu+1
,xu+1+n,cmp); 33 int wei=0,ans=-2100000000,d; 34 for(int i=1;i<=n;++i) 35 { 36 d=wei-s[xu[i]]; 37 ans=max(ans,d); 38 wei+=w[xu[i]]; 39 } 40 cout<<ans; 41 return 0; 42 }
AC程式碼

可聯想到,若兩資料轉化比例不為1:1,但轉化方式仍為加減轉化,可用類似操作,不過排序時變數有係數不同罷了。