其他分享
首页 > 其他分享> > cf1458 B. Glass Half Spilled

cf1458 B. Glass Half Spilled

作者:互联网

题意:

n 个杯子,每个杯子容量为 ai,装有水 bi。可以进行任意次操作,每次从一个杯子往另一个杯子倒 x 的水,但一定会洒出 x/2。另外超过容量的会溢出。

现在对所有的 k=1,2,...,n,求 k 个杯子的最大水量。k 之间独立

\(n\le 100, a_i,b)i\le 100\)

思路:

\(f(k,c)\) 表示不进行操作,k 个杯子总容量恰为 c 的最大水量。

那么 \(ans_k = \max _c \frac{f(k,c)+\sum b_i}{2}\)

用01背包求 \(f\) 的复杂度 \(n^2na_i=1e8\)

const signed N = 103;
int n, a[N], b[N], tot, f[N][N*N]; db ans[N];
signed main() {
    iofast;
    cin >> n; for(int i = 1; i <= n; i++)
        cin >> a[i] >> b[i], tot += b[i];

    memset(f, -1, sizeof f); f[0][0] = 0;
    for(int i = 1; i <= n; i++) //考虑到i
        for(int j = i; j; j--) //前面选了j-1个
            for(int c = N*N-1; c >= a[i]; c--) //所有可能容积
                if(~f[j-1][c-a[i]]) //有效状态
                    f[j][c] = max(f[j][c], f[j-1][c-a[i]] + b[i]);
    
    for(int k = 1; k <= n; k++) {
        db ans = 0;
        for(int c = 0; c < N*N; c++)
            if(~f[k][c])
                ans = max(ans, min((db)c, (f[k][c]+tot)/2.0) );
        cout << fixed << setprecision(10) << ans << ' ';
    }
}

标签:cf1458,le,int,max,Spilled,Half,tot,ans,杯子
来源: https://www.cnblogs.com/wushansinger/p/16194507.html