zoukankan      html  css  js  c++  java
  • B. Glass Half Spilled dp

    B. Glass Half Spilled dp

    题目大意:

    你有n个杯子,你可以把一个杯子里面的水倒到另外一个杯子,假设倒出来 (x) 的水,那么 (x/2) 的水会倒在桌子上,只有 (x/2) 的水会进入杯子, (x) 可以是一个实数,问最后选择 (k) 个杯子,杯子中的水最多是多少。

    题解:

    一开始感觉好难,后来仔细思考发现是一个很简单的 (dp) 问题

    (dp[j][k]) 表示选择了j个物品,还剩下k的空间,获得的最大价值。

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 110;
    int dp[maxn][maxn*maxn];
    // dp[j][k]  表示选择了j个物品,还剩下k的空间,获得的最大价值。
    int a[maxn],b[maxn];
    double ans[maxn];
    int main(){
        int n,sum = 0,S = 0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d%d",&a[i],&b[i]),sum+=a[i] - b[i],S += b[i];
        memset(dp,0xef,sizeof(dp));
        dp[0][0] = 0;
        for(int i=1;i<=n;i++){
            for(int j=n;j>=1;j--){
                for(int k=sum;k>=0;k--){
                    int val = a[i] - b[i];
                    if(k>=val) dp[j][k] = max(dp[j][k],dp[j-1][k-val]+b[i]);
    //                printf("i = %d j = %d k = %d %d
    ",i,j,k,dp[j][k]);
                }
            }
        }
        for(int j=1;j<=n;j++){
            for(int k=0;k<=sum;k++){
                double val = min(k*1.0,(S-dp[j][k])*1.0/2);
                ans[j] = max(ans[j],1.0*dp[j][k]+val);
            }
            printf("%.10f",ans[j]);
            if(j==n) printf("
    ");
            else printf(" ");
        }
        return 0;
    }
    
    
  • 相关阅读:
    WebService
    jdbc访问数据库
    ssm文件配置
    ssh文件配置
    配置数据源的三种方式和sql心跳的配置
    SQL in与exists
    套接字
    oracle 方向及资料
    ORACLE恢复数据
    SQL时间戳的使用
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/14544532.html
Copyright © 2011-2022 走看看