zoukankan      html  css  js  c++  java
  • Codeforces Round#691(Div.2-D)Glass Half Spilled

    题目大意:n个容器,每个容器有一定的容量,每个容器当前有水,容器之间可以倒水(任意),每次倒水,水会洒出来一半,问选择1-n个容器最多能得到多少水

    题目链接

    解题思路:我们观察到数据范围是比较小的,往dp上靠一下。dp[i][j][k]表示前i个容器中选择j个容量为k时,这些所选容器内的最大初始水量。当我们得到最大初始水量后,我们知道总水量和容量

    那么max((sum-dp[][][])/2+dp[][][],k)就是我们的答案,也就是max(sum+dp[][][],2*k)/2

    我们在dp时前i个容器的容量是知道的,那么容量k就是0-sum[i]的,表示前i个选择j个容量为k时初始水量最大值

    转移方程很容易写出来:dp[i][j][k]=max(dp[i][j][k],dp[i-1][j-1][k-a[i]]+b[i])

    用人话来说就是,前i个容器选j个容量为k时的最大初始水量是,不选择或者选择第i个容器,要选择第i个容器并且保证总共选择j个那么,就要从dp[i-1][j-1][k-a[i]]转移过来

    事实上我们知道当前状态的i仅仅与当前状态或上一个状态(i-1)有关,那么滚动数组减少一维

    最后找答案的时候只要在最后的dp中枚举j和k得到最大值就可以了

     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<math.h>
     4 #include<string.h>
     5 using namespace std;
     6 typedef long long ll;
     7 const int maxn=2e5+5;
     8 
     9 int n,m,t;
    10 int a[maxn],b[maxn];
    11 int dp[2][110][10010];
    12 int suma[maxn],sumb;
    13 int main(){
    14     scanf("%d",&n);
    15     for(int i=1;i<=n;i++){
    16         scanf("%d%d",&a[i],&b[i]);
    17         suma[i]=suma[i-1]+a[i];
    18         sumb+=b[i];
    19     }
    20     int now=0;
    21     memset(dp,-0x3f,sizeof(dp));
    22     dp[0][0][0]=0;
    23     for(int i=1;i<=n;i++){
    24         now^=1;
    25         for(int j=0;j<=i;j++){
    26             for(int k=0;k<=suma[i];k++){
    27                 dp[now][j][k]=dp[now^1][j][k];
    28             }
    29         }
    30         for(int j=1;j<=i;j++){
    31             for(int k=a[i];k<=suma[i];k++){
    32                 dp[now][j][k]=max(dp[now][j][k],dp[now^1][j-1][k-a[i]]+b[i]);
    33             }
    34         }
    35     }
    36     int ans=0;
    37     for(int j=1;j<=n;j++){
    38         ans=0;
    39         for(int k=0;k<=suma[n];k++){
    40             ans=max(ans,min(dp[now][j][k]+sumb,2*k));
    41         }
    42         printf("%.10f%c",1.0*ans/2,j==n?'
    ':' ');
    43     }
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    bootstrap 导航栏、输入框按钮组、栅格系统
    Python排序算法冒泡排序选择排序插入排序
    Python 解螺旋数组
    初到博客园,请多指教
    gcd, map for ocaml
    qsort for ocaml
    子序列和最大的问题
    将一个整数划分为非负整数的部分
    filter in Ocaml
    scheme中表只能操作头部带来的一个问题
  • 原文地址:https://www.cnblogs.com/noback-go/p/14330338.html
Copyright © 2011-2022 走看看