1. 程式人生 > 其它 >ARC128 C - Max Dot(貪心+構造)

ARC128 C - Max Dot(貪心+構造)

目錄

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;
}