• 背包问题


    1.  01背包

    为题描述:s件物品, 背包容量为  m  ,给出每件物品的cost,与 value 求在背包容量内最大的价值是多少?

     
    void pack_01(int weight,int value)
    {
        for(int i=背包容量;i>=weight;i--)
            dp[i]=max(dp[i],dp[i-weight]+value);
    }
    
    int DP()
    {
        for(int i=0;i<物品件数;i++)
            pack_01(weight[i],value[i]);
        return dp[背包容量];
    }

    
    2.完全背包
    

    物品件数为正无穷的背包

    scanf("%d",&n);
    for(i=0; i<n; i++)
    {
        scanf("%d%d",&p,&w);
        for(j=w; j<=m; j++) //与01背包相比倒过来
        {
            dp[j]=max(dp[j],dp[j-w]+p);    // dp[i] 表示i容量的背包最多装的价值。
        }
    }


    3.多重背包


    int v[10],dp[MM];
    int sum;
    void pack01(int weight,int val)
    {
        int i;
        for(i=sum; i>=weight; i--)
            dp[i]=max(dp[i],dp[i-weight]+val);
    }
    void packcomplete(int weight,int val)
    {
        int i;
        for(i=weight; i<=sum; i++)
            dp[i]=max(dp[i],dp[i-weight]+val);
    }
    void packmul(int weight,int val,int coutt)
    {
        if(weight*coutt>=sum)  
        {
            packcomplete(weight,val);
            return ;
        }
        int k=1,tot=0;;
        while(k<coutt)   //二进制优化
        {
            pack01(k*weight,k*val);
            coutt-=k;
            k=k*2;
        }
        pack01(coutt*weight,coutt*val);
    }
    void DP()
    {
        int i;
        for(i=0; i<=sum; i++)
            dp[i]=-INF;
        dp[0]=0;
        for(i=1; i<=6; i++)
        {
            packmul(i,i,v[i]);
        }
    }


    杭电题目  题目链接>点这里打开<


    AC代码

    #include<iostream>
    #include<stdio.h>
    #include<math.h>
    #include<algorithm>
    #include<string.h>
    #include<stack>
    #include<queue>
    #include<vector>
    #include<stdlib.h>
    #include<map>
    
    using namespace std;
    const int INF=10000000;
    const int MM=60005;
    
    int v[10],dp[MM];
    int sum;
    void pack01(int weight,int val)
    {
        int i;
        for(i=sum; i>=weight; i--)
            dp[i]=max(dp[i],dp[i-weight]+val);
    }
    void packcomplete(int weight,int val)
    {
        int i;
        for(i=weight; i<=sum; i++)
            dp[i]=max(dp[i],dp[i-weight]+val);
    }
    void packmul(int weight,int val,int coutt)
    {
        if(weight*coutt>=sum)
        {
            packcomplete(weight,val);
            return ;
        }
        int k=1,tot=0;;
        while(k<coutt)
        {
            pack01(k*weight,k*val);
            coutt-=k;
            k=k*2;
        }
        pack01(coutt*weight,coutt*val);
    }
    void DP()
    {
        int i;
        for(i=0; i<=sum; i++)
            dp[i]=-INF;
        dp[0]=0;
        for(i=1; i<=6; i++)
        {
            packmul(i,i,v[i]);
        }
    }
    int main()
    {
        int ncase=0;
        while(1)
        {
            int i;
            ncase++;
            sum=0;
            for(i=1; i<=6; i++)
            {
                cin>>v[i];
                sum+=i*v[i];
            }
            if(!sum) break;   //如果全是0  程序结束
            printf("Collection #%d:
    ",ncase);
            if(sum%2==1)  //总和为奇数个数则不可能评分
            {
                printf("Can't be divided.
    
    ");
                continue;
            }
            sum=sum/2;  //背包容量减半
            DP();
            if(dp[sum]>=0)
                printf("Can be divided.
    
    ");
            else
                printf("Can't be divided.
    
    ");
        }
        return 0;
    }
    



  • 相关阅读:
    面向对象的程序设计---组合练习
    一个简单的爬网页内容程序
    5.关于类和对象
    sql 查询至少连续n天下单的用户
    SQL 行转列 (统计每天,每个用户的消费金额)及sql 查询连续天数示例
    SQL 分组后进行相关统计
    SQL 分组内取前几名的问题
    JAVA-给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。
    SQL 刷题(CREATE FUNCTION,rank)
    机考刷题(SearchChar)
  • 原文地址:https://www.cnblogs.com/coded-ream/p/7208006.html
Copyright © 2020-2023  润新知