zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    0923------APUE 学习笔记----------Linux系统的启动流程
    0915-----Linux设备驱动 学习笔记----------一个简单的字符设备驱动程序
    0815------算法笔记----------矩阵连乘问题
    0806------Linux网络编程----------Echo 网络库 学习笔记
    事件学习
    信息系统需求分析阶段的实践经验之二---如何有效地获得用户需求【转】
    信息系统需求分析阶段的实践经验之一---需求分析概述[转]
    Lambda表达式【转】
    C#委托的介绍(delegate、Action、Func、predicate)【转】
    css3选择器——导图篇
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9703595.html
Copyright © 2011-2022 走看看