zoukankan      html  css  js  c++  java
  • [动态规划] Codeforces 1348E Phoenix and Berries

    题解

    设有 (n) 棵梅树,每个篮子的容量为 (k),第 (i) 棵树上的红梅数量为 (a_i),第 (i) 棵树上的蓝莓数量为 (b_i)。注意到最多只有 (n) 个篮子里面装的梅子是不同色的(如果从同一棵树上装了多个不同色的篮子,我们一定可以把这多个不同色的蓝子转化为多个同色的篮子加上一个不同色的篮子)。

    (dp[i-1][j]) 表示前 (i-1) 棵树装完梅子后,剩下 (j) 个红梅,最多能填满的篮子的数量。令 (sum=sumlimits_{p=1}^{i-1}(a_p+b_p)-dp[i-1][j] imes k),则剩下的蓝莓数量等于 (sum-j)

    枚举第 (i) 棵树生成的不同色的篮子的组成,设不同色的篮子使用红梅 (s) 个,使用蓝莓 (k-s) 个。则前 (i) 棵树所剩的红梅还有 (j-s+a_i) 个,蓝莓还有 (sum-j-k+s+b_i) 个。

    (dp[i][(j-s+a_i) mod k]=maxleft{dp[i][(j-s+a_i) mod k],dp[i-1][j]+1+leftlfloorfrac{j-s+a_i}{k} ight floor + leftlfloorfrac{sum-j-k+s+b_i}{k} ight floor ight})

    时间复杂度 (O(NK^2)) 。好像需要稍微卡一下才能过= =。

    Code

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    template<typename elemType>
    inline void Read(elemType &T){
        elemType X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        T=(w?-X:X);
    }
    
    int a[505],b[505];
    LL Sum[505],dp[505][505];
    bool exist[505][505];
    int N,K;
    
    int main(){
        Read(N);Read(K);
        exist[0][0]=true;
        RG i,j,temp,p,l,r,s;
        LL sum;
        for(i=1;i<=N;++i){
            Read(a[i]);Read(b[i]);
            Sum[i]=Sum[i-1]+a[i]+b[i];
            for(j=0;j<K;++j){
                sum=Sum[i-1]-dp[i-1][j]*(LL)K;
                if(!exist[i-1][j]) continue;
                temp=(j+a[i])%K;
                dp[i][temp]=dp[i-1][j]+(j+a[i])/K+(sum-(LL)j+(LL)b[i])/(LL)K;
                exist[i][temp]=true;
                l=max(0,K-b[i]),r=min(a[i],K);
                for(s=l;s<=r;++s){
                    p=(j-s+a[i])%K;
                    dp[i][p]=max(dp[i][p],dp[i-1][j]+1LL+(j-s+a[i])/K+(sum-j-K+s+b[i])/K);
                    exist[i][p]=true;
                }
            }
        }
        LL Ans=0;
        for(i=0;i<K;++i)
            Ans=max(Ans,dp[N][i]);
        printf("%I64d
    ",Ans);
        return 0;
    }
    
  • 相关阅读:
    Linux 学习 step by step (1)
    ubuntu server nginx 安装与配置
    ubuntu server samba服务器配置
    iOS app集成支付宝支付流程及后台php订单签名处理
    mac 连接windows 共享内容
    linux 文件查找,which,whereis,locate,find
    ubuntu server vsftpd 虚拟用户及目录
    ubuntu server 安装 mantis bug tracker 中文配置
    ubuntu server vsftpd 匿名用户上传下载及目录设置
    linux 用户管理,用户权限管理,用户组管理
  • 原文地址:https://www.cnblogs.com/AEMShana/p/12818773.html
Copyright © 2011-2022 走看看