zoukankan      html  css  js  c++  java
  • [HEOI2013] Eden 的新背包问题

    Description

    多重背包,多次询问,每次询问都将给出新的总价钱,并且会去掉某种物品,再问此时的多重背包的答案,(1 leq n leq 1000)(1 leq q leq 3 imes 10^5)(1 leq a_i,b_i,c_i leq 100)(0 leq d_i < n)(0 leq e_i leq 1000)

    Solution

    正反各运行一次多重背包,分别记为 (f[][],g[][])

    对于一个询问 (d,e),答案则为 (max_i (f[d][i]+g[d+2][e-i]))(下标错位)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1005;
    
    int f[N][N],g[N][N],n,q,a[N],b[N],c[N],d,e;
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i]>>b[i]>>c[i];
        }
    
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<N;j++) f[i][j]=f[i-1][j];
            int tmp=c[i];
            for(int k=0;k<=20;k++)
            {
                if(tmp>(1<<k))
                {
                    tmp-=1<<k;
                    for(int j=N-1;j>=(1<<k)*a[i];j--)
                    {
                        f[i][j]=max(f[i][j],f[i][j-(1<<k)*a[i]]+(1<<k)*b[i]);
                    }
                }
            }
            for(int j=N-1;j>=tmp*a[i];j--)
            {
                f[i][j]=max(f[i][j],f[i][j-tmp*a[i]]+tmp*b[i]);
            }
        }
    
        for(int i=n;i>=1;--i)
        {
            for(int j=0;j<N;j++) g[i][j]=g[i+1][j];
            int tmp=c[i];
            for(int k=0;k<=20;k++)
            {
                if(tmp>(1<<k))
                {
                    tmp-=1<<k;
                    for(int j=N-1;j>=(1<<k)*a[i];j--)
                    {
                        g[i][j]=max(g[i][j],g[i][j-(1<<k)*a[i]]+(1<<k)*b[i]);
                    }
                }
            }
            for(int j=N-1;j>=tmp*a[i];j--)
            {
                g[i][j]=max(g[i][j],g[i][j-tmp*a[i]]+tmp*b[i]);
            }
        }
    
        cin>>q;
        while(q--)
        {
            cin>>d>>e;
            int ans=0;
            for(int i=0;i<=e;i++)
            {
                ans=max(ans,f[d][i]+g[d+2][e-i]);
            }
            cout<<ans<<endl;
        }
    }
    
    
  • 相关阅读:
    144.二叉树的前序遍历
    103.二叉树的锯齿形层次遍历
    shiro系列二、身份验证和授权
    shiro系列一、认识shiro
    发送短信——java
    redis系列二: linux下安装redis
    redis系列一: windows下安装redis
    BootstrapValidator 表单验证超详细教程
    Linux ps 命令详解
    Vmvare 虚拟机固定IP
  • 原文地址:https://www.cnblogs.com/mollnn/p/13206179.html
Copyright © 2011-2022 走看看