\[ \texttt{Description} \]spa
有 \(n\) 頭牛,每頭牛都有本身的體重 \(W_i\) 和力量 \(S_i\) 。code
將這 \(n\) 頭牛摞在一塊兒,每頭牛的壓扁指數定義爲:壓在該牛上面的牛的體重之和 \(-\) 該牛力量 。排序
您須要找到一種摞牛方案,使得壓扁指數最大的牛的壓扁指數最小。ip
求這個壓扁指數。
\[ \texttt{Solution} \]get
微擾(鄰項交換)證實貪心好題。it
記 \(Z_i=\sum\limits_{j=1}\limits^{i}W_j\)(前 \(i\) 頭牛體重和)。io
咱們考慮任意一個鄰項,考慮交換:table
第 \(i\) 頭牛 | 第 \(i+1\) 頭牛 | |
---|---|---|
交換前壓扁指數 | \(Z_{i-1}-S_i\) | \(Z_{i-1}+W_i-S_{i+1}\) |
交換後壓扁指數 | \(Z_{i-1}-S_{i+1}\) | \(Z_{i-1}+W_{i+1}-S_i\) |
\[ \max(Z_{i-1}-S_i,Z_{i-1}+W_i-S_{i+1}) \\ \max(Z_{i-1}-S_{i+1},Z_{i-1}+W_{i+1}-S_i) \]class
\[ \max(-S_i,W_i-S_{i+1}) \\ \max(-S_{i+1},W_{i+1}-S_i) \]im
\[ \max(S_{i+1},W_i+S_i) \\ \max(S_i,W_{i+1}+S_{i+1}) \]
\[ W_i+S_i \\ W_{i+1}+S_{i+1} \]
當 \(W_i+S_i \geq W_{i+1}+S_{i+1}\) 時,上式 \(\geq\) 下式,則交換後定不比交換前劣。
至此咱們就有一個貪心策略:將這 \(n\) 頭牛以 \(W_i+S_i\) 爲關鍵字從小到大排序。儘管這個貪心策略很玄學。
\(\mathcal{O(n \log n)}\) 。
\[ \texttt{Code} \]
#include<cstdio> #include<algorithm> #define RI register int using namespace std; inline int read() { int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f; } const int N=50010; int n; struct Cow{ int W,S; }a[N]; bool cmp(Cow a,Cow b) { return a.W+a.S<b.W+b.S; } long long ans=-0x3f3f3f3f; int main() { n=read(); for(RI i=1;i<=n;i++) a[i].W=read(),a[i].S=read(); sort(a+1,a+1+n,cmp); long long sum=0; for(RI i=1;i<=n;i++) { ans=max(ans,sum-a[i].S); sum+=a[i].W; } printf("%lld\n",ans); return 0; }
\[ \texttt{Thanks} \ \texttt{for} \ \texttt{watching} \]