zoukankan      html  css  js  c++  java
  • HDU 3449 Consumer

    这是一道依赖背包问题。
    背包问题通常的解法都是由0/1背包拓展过来的,这道也不例外。
    我最初想到的做法是,由于有依赖关系,先对附件做个DP,得到1-w的附件背包结果f[i]表示i花费得到的最大收益,然后把每个f[i]看成花费为i+c[i],收益为f[i]的物品依次做0/1背包。
    显然,问题是物品数目过多,复杂度为w*w,无法承受。
    同时,此问题的主件收益为0这一点也需要细加考虑,由于主件收益为0,其实际上对每个附件方案的影响只有花费+c[i],这样考虑下来我们只需要对附件进行DP,然后附加上+c[i]的影响即可。

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<cstdlib>
    using namespace std;
    #define ll long long
    #define up(i,j,k) for(int i=(j);i<=(k);i++)
    #define cmin(a,b) a=min(a,b)
    #define cmax(a,b) a=max(a,b)
    #define pii pair<int,int>
    const int maxn=101000,inf=1e9,mod=9901;
    int read(){
        int ch=getchar(),x=0,f=1;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return f*x;
    }
    int n,w;
    int f[maxn],g[maxn],p[55],m[55];
    int c[15],v[15];
    int main(){
        freopen("chad.in","r",stdin);
        freopen("chad.out","w",stdout);
        while(scanf("%d%d",&n,&w)!=EOF){
            memset(f,0,sizeof(f));
            memset(g,0,sizeof(g));
            up(i,1,n){
                scanf("%d%d",&p[i],&m[i]);
                up(j,1,m[i]){
                    scanf("%d%d",&c[j],&v[j]);
                    for(int k=w;k>=c[j];k--)
                        g[k]=max(g[k-c[j]]+v[j],g[k]);
                }
                up(j,p[i],w)f[j]=max(f[j],g[j-p[i]]);
                memcpy(g,f,sizeof(f));
            }
            
            printf("%d
    ",f[w]);
        }
        return 0;
    }
    View Code

    事实上,第一种方法也是可行的,只不过,需要先对g数组进行一个(小优化)。

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<cstdlib>
    using namespace std;
    #define ll long long
    #define up(i,j,k) for(int i=(j);i<=(k);i++)
    #define cmin(a,b) a=min(a,b)
    #define cmax(a,b) a=max(a,b)
    #define pii pair<int,int>
    const int maxn=101000,inf=1e9,mod=9901;
    int read(){
        int ch=getchar(),x=0,f=1;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return f*x;
    }
    int n,w;
    int f[maxn],g[maxn],p[55],m[55];
    int c[15],v[15],head,q[maxn];
    int main(){
        freopen("chad.in","r",stdin);
        freopen("chad.out","w",stdout);
        while(scanf("%d%d",&n,&w)!=EOF){
            memset(f,0,sizeof(f));
            memset(g,0,sizeof(g));
            up(i,1,n){
                scanf("%d%d",&p[i],&m[i]);
                memset(g,0,sizeof(g));
                up(j,1,m[i])scanf("%d%d",&c[j],&v[j]);
                up(j,1,m[i])for(int k=w;k>=c[j];k--)
                    g[k]=max(g[k-c[j]]+v[j],g[k]);
                head=0;
                for(int j=0;j<=w;j++)
                    if(!j||g[j]!=g[j-1])q[++head]=j;
                for(int j=w;j>=p[i];j--){
                    for(int k=1;q[k]+p[i]<=j&&k<=head;k++)
                        f[j]=max(f[j],f[j-p[i]-q[k]]+g[q[k]]);
                }    
            }
            printf("%d
    ",f[w]);
        }
        return 0;
    }
  • 相关阅读:
    代理与反向代理
    Spring Batch 远程分区和远程分块的区别
    XWIKI部署安装
    想写一些与技术无关的
    1104报表
    ARQC与ARPC的生成和校验方法
    学习开源框架的一些总结
    linux java -version 和 javac -version 不一致
    spring boot 概念
    Unable to open socket file: target process not responding or HotSpot VM not loaded
  • 原文地址:https://www.cnblogs.com/chadinblog/p/9204999.html
Copyright © 2011-2022 走看看