zoukankan      html  css  js  c++  java
  • Gym

    pro:给定N,M。输入N个物品,(si,vi)表示第i个物品体积为si,价值为vi,s<=300,vi<=1e9; N<1e6;现在要求,对于背包体积为1到M时,求出最大背包价值。

    sol:显然直接跑背包会爆炸。 发现物品体积都比较小,我们先对相同体积的排序,对于体积相同的一起处理。

    然后发现转移都是在差为体积整数倍之间,按照容量对体积取模分组 ,发现组内部转移满足神奇的决策单调性。 然后就是s次分治。

    O(KClogC)

    #include<bits/stdc++.h>
    #define ll long long
    #define rep(i,a,b) for(int i=a;i<=b;i++)
    #define rep2(i,a,b) for(int i=b;i>=a;i--)
    using namespace std;
    const int maxn=310;
    const int maxm=100010;
    ll dp[2][maxm];
    vector<ll>G[maxn]; int x,d,t;
    void get(int L,int R,int l,int r)
    {
        if(L>R) return ;
        int Mid=(L+R)>>1,pos=Mid;
        for(int i=min(r,Mid-1);i>=l;i--){
            if(Mid-i>G[x].size()) break;
            if(dp[t][d+Mid*x]<dp[t^1][d+i*x]+G[x][Mid-i-1]){
                pos=i; dp[t][d+Mid*x]=dp[t^1][d+i*x]+G[x][Mid-i-1];
            }
        }
        get(L,Mid-1,l,pos);
        get(Mid+1,R,pos,r);
    }
    int main()
    {
        int N,M,s;ll v;
        scanf("%d%d",&N,&M);
        rep(i,1,N){
            scanf("%d%lld",&s,&v);
            G[s].push_back(v);
        }
        rep(i,1,300){
            if(G[i].size()==0) continue;
            sort(G[i].begin(),G[i].end(),greater<int>() );
            for(int j=1;j<G[i].size();j++) G[i][j]+=G[i][j-1];
            t^=1;  rep(j,1,M) dp[t][j]=dp[t^1][j];
            rep(j,0,i-1){
                d=j;  x=i;
                get(0,(M-j)/i,0,(M-j)/i);
            }
            rep(j,1,M) dp[t][j]=max(dp[t][j],dp[t][j-1]);
        }
        rep(i,1,M) printf("%lld ",dp[t][i]);
        return 0;
    }
  • 相关阅读:
    hadoop 异常及处理总结-02(小马哥精品)
    Linux环境变量(小马哥推荐)
    Apache Tomcat 8.5 安全配置与高并发优化
    深入理解分布式系统中的缓存架构(上)
    Redis的n种妙用,不仅仅是缓存
    springBoot整合ecache缓存
    Spark Streaming实时处理应用
    Spark 实践
    spark性能调优
    Spark调优
  • 原文地址:https://www.cnblogs.com/hua-dong/p/10546963.html
Copyright © 2011-2022 走看看