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;
    }
    
  • 相关阅读:
    Java通过反射加载的类,变量无法注入
    jmeter http并发测试时报错
    spring 自定义注解
    cmd 和powershell 用git 显示乱码
    centos6.8上安装部署 jhipster-registry
    tcpdf最新版 6.2版
    微信Oauth2.0鉴权 40029 问题
    微信支付学习记录1
    win10 localhost 解析为 ipv6地址 ::1 的解决办法
    PHPExcel 导出时乱码
  • 原文地址:https://www.cnblogs.com/AEMShana/p/12818773.html
Copyright © 2011-2022 走看看