• P1064 金明的预算方案


    传送门

    思路:

      有条件的 01背包(有依赖的背包)。

      可分为四种情况来做 01背包 :①不买主件 ②买主件 ③买主件+副件1 ④买主件+副件2 ⑤买主件+副件1+副件2

      转移条件:

      ①没有附件,按最基本的 01背包来做。  

      ②该附件和主件的重量(为区分价格和价值,接下来的所有分析都按背包理解)之和 ≤ 现在在判断的 j (背包剩余容量)(也是按照 01背包 的模板做)

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<queue>
    #include<vector>
    #include<deque>
    #include<stack>
    #include<map>
    #include<set>
    using namespace std;
    #define maxn 40000
    int m,n,v,p,q;//m背包容量,n物品数量,v物品价格,p重要程度,q判断是否为主件 
    int mw[maxn],mv[maxn],fw[maxn][3],fv[maxn][3];
    //mw主件重量,mv主件价值,fw主件对应的附件重量,fv主副价值,n总重量,m总个数   
    int f[maxn];
    inline int read()
    {
        int kr=1,xs=0;
        char ls;
        ls=getchar();
        while(!isdigit(ls))
        {
            if(!(ls^45))
            kr=-1;
            ls=getchar();
        }
        while(isdigit(ls))
        {
            xs=(xs<<1)+(xs<<3)+(ls^48);
            ls=getchar();
        }
        return kr*xs;
    }
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            v=read();p=read();q=read();
            if(!q)//如果是主件
            {
                mw[i]=v;//主件重量 
                mv[i]=v*p;//主件价值与重量乘积   
            }
            else//如果是附件
            {
                fw[q][0]++;//记录主件的附件个数(只记录在fw就行,fv那里没用 
                fw[q][fw[q][0]]=v;//主件的个数是用来确定该附件应该填在第一个还是第二个格子里  
                fv[q][fw[q][0]]=v*p;//(是第一个还是第二个附件)   
            }
        }
        for(int i=1;i<=m;i++)
            for(int j=n;j>=mw[i];j--)//01背包模板   
            { //每一个if的前提是背包能不能装下该物品  
                f[j]=max(f[j],f[j-mw[i]]+mv[i]);//情况1:只要主件和什么都不要比较  
                if(j>=mw[i]+fw[i][1])//情况2:主件和附件1 和上面选出的较大值比较   
                    f[j]=max(f[j],f[j-mw[i]-fw[i][1]]+mv[i]+fv[i][1]);
                if(j>=mw[i]+fw[i][2]) //情况3:主件和附件2 和上面选出的较大值比较   
                    f[j]=max(f[j],f[j-mw[i]-fw[i][2]]+mv[i]+fv[i][2]);
                if(j>=mw[i]+fw[i][1]+fw[i][2])//情况4:都要   
                    f[j]=max(f[j],f[j-mw[i]-fw[i][1]-fw[i][2]]+mv[i]+fv[i][1]+fv[i][2]);
            }
        printf("%d
    ",f[n]);//输出  
    return 0;
    }
  • 相关阅读:
    Linux tcpdump命令详解
    移动开发网站收集
    Struts+2权威指南基于WebWork核心的MVC开发源码下载
    Eclipse+php插件+Xdebug搭建PHP完美开发/调试环境指南
    java相对目录和绝对目录解析
    python学习网站搜集
    window下开发iphone程序环境搭建iphone tool chain
    Windows下编译objectiveC
    java class路径获取
    完全优化MySQL数据库性能的八个方法
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9703595.html
Copyright © 2020-2023  润新知