ARC128 C - Max Dot(貪心+構造)
阿新 • • 發佈:2021-11-01
目錄
Description
有一個數組 \(a\), 要求構造一個數組 \(x\),滿足 \(\sum{a_i*x_i}\) 最大
其中 \(x_i\) 的大小不超過 \(m\),而且 \(\sum{x_i}=S\),\(0<=x_1<=x_2<=....x_n<=m\)
State
\(1<=n<=5000\)
\(1<=m<=10^6\)
\(1<=S<=10^6\)
\(1<=a_i<=10^6\)
Input
3 2 3
1 2 3
Output
8.00000000000000000000
Solution
先考慮一種極端的情況, \(a\) 陣列為降序,此時 \(x\) 陣列每個數為 \(\frac{S}{n}\)
這是題目才有下手點,我們可以從後向前找 \(\frac{sum_i}{n-i+1}\) 的最大值,如果沒有 \(m\) 的限制,\(x=\frac{S}{n-i+1}\) ,此時可以貪心驗證一下正確性
如果 \(x>m\) 就令這一段的 \(x\) 為 \(m\),然後重複上述過程,直至 \(S=0\)
Code
const int N = 5e3 + 5; int n, m, k, _; int a[N]; double ans[N]; signed main() { // IOS; double m, s; while(~ sd(n)){ sf(m), sf(s); rep(i, 1, n) sd(a[i]); int st = n; while(st > 0){ double sum = 0; int pos; double maxx = 0; for(int i = st; i; i --){ sum += a[i]; if(sum / (st - i + 1) > maxx){ maxx = sum / (st - i + 1); pos = i; } } double now = min(m, s / (st - pos + 1)); for(int i = st; i >= pos; i --){ ans[i] = now; s -= now; } if(s <= 0) break; st = pos - 1; } double sum = 0; for(int i = 1; i <= n; i ++){ sum += a[i] * ans[i]; } pf(sum); } // PAUSE; return 0; }