zoukankan      html  css  js  c++  java
  • [BZOJ] 3163: [Heoi2013]Eden的新背包问题

    这个复杂度不能接受,但是确实能过。

    二进制拆分多重背包可过,做的时候记录前缀后缀和,就是不优化背包的第一维。

    nlogn件物品,预处理复杂度O(nmlogn),看起来还行

    每次询问暴力合并,O(qm),3*10^8,看起来有点难受。

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=1024<<3;
    
    int a[MAXN],val[MAXN],tot;
    
    int f[MAXN][1024],g[MAXN][1024];
    
    int n,m;
    
    int pos[MAXN];
    
    int main(){
        n=rd();
        int x,y,z;
        for(int i=1;i<=n;i++){
            x=rd();y=rd();z=rd();
            for(int j=0;(1<<j)<=z;j++){
                z-=(1<<j);a[++tot]=x*(1<<j);val[tot]=y*(1<<j);
            }
            if(z){a[++tot]=x*z;val[tot]=y*z;}
            pos[i]=tot;
        }
        for(int i=1;i<=tot;i++){
            for(int j=1000;j>=0;j--){
                f[i][j]=f[i-1][j];
                if(j>=a[i])f[i][j]=max(f[i-1][j],f[i-1][j-a[i]]+val[i]);
            }
        }
        for(int i=tot;i>=1;i--){
            for(int j=1000;j>=0;j--){
                g[i][j]=g[i+1][j];
                if(j>=a[i])g[i][j]=max(g[i+1][j],g[i+1][j-a[i]]+val[i]);
            } 
        }
        m=rd();
        int ans=0;
        for(int i=1;i<=m;i++){
            x=rd()+1;y=rd();ans=0;
            for(int j=0;j<=y;j++){
                ans=max(f[pos[x-1]][j]+g[pos[x]+1][y-j],ans);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    未经许可,禁止搬运。
  • 相关阅读:
    欧拉回路
    2018 年 ACM-ICPC 焦作站现场赛感受
    3.1 基础-抛小球
    2.2 进阶-禁忌雷炎
    初学Java-循环输入直到文件结束
    1.1 基础-取近似值
    1.2 进阶-对称的二叉树
    LEETCODE
    算法
    算法
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9507562.html
Copyright © 2011-2022 走看看