zoukankan      html  css  js  c++  java
  • 背包问题(01背包、完全背包、部分背包)

    之前写过一篇博客,这次看了下背包九讲,主要看的是部分背包的优化解法,转化的很巧妙,时间复杂度可以达到O(n*∑log(amount[i])*V),就是把原先每个背包的数量分成一堆一堆的。

    例如,假如物品i有14件,那么我们可以将它转化成若干个01背包问题,这几个子问题的背包价值和代价为1*price,1*cost,2*price,2*cost,4*price,4*cost, 7*price, 7*cost,这样我们总可以将1-13之内的数用这几个数来表示,一般的对于一个amout,我们只需要找到最大k,使得amout-2^(k+1) > 0. 这种优化方法,可以简单的这么理解,就是对于每一个新的子01背包,我们要么选它要么不选它,dp[w]中记录的总是满足条件的最大价值,这样我们总能遍历到任何一个1-13内的状态,使得dp[w]达到最大。

    代码如下:

    #include <iostream>
    using namespace std;
    const int m = 100;
    const int INF = -1000;
    int dp[m];
    int maxn(int a, int b)
    {
    	return a > b ? a : b;
    }
    /*
    如果要求正好装满,则初始化未INF,否则初始化未0
    */
    void init()
    {
        for(int k = 0; k <= 100; k++)
    		dp[k] = INF; //
    	dp[0]=0;
    }
    int zeroOnePack(int price, int cost, int W)
    {
    	for(int w = W; w >= 1; --w)
    	{
    		if(w >= cost)
    			dp[w] = maxn(price + dp[w - cost], dp[w]);
    	}
    	return dp[W];
    }
    int CompletePack(int price, int cost, int W)
    {
        for(int w = 1; w <= W; ++w)
    	{
    		if(w >= cost)
    			dp[w] = maxn(price+dp[w-cost], dp[w]);
    	}
    	return dp[W];
    }
    int multiPack(int price, int cost, int amount, int W)
    {
    	if(amount*cost >= W)
    		CompletePack(price, cost, W);
    	else
    	{
    		int k = 1;
    		while(k < amount)
    		{
    			zeroOnePack(k*price, k*cost, W);
    			amount -= k;
    			k *= 2;
    		}
    		zeroOnePack(amount*price, amount*cost, W);
    	}
    	cout<<dp[W]<<endl;
    	return dp[W];
    }
    int main()
    {
    	int price[5] = {1,2,3};
    	int cost[5] = {5,2,4};
    	int amount[5] = {2,2,2};
    	init();
    	for(int i = 0; i < 3; ++i)
    	    multiPack(price[i], cost[i], amount[i], 5);
    	return 0;
    }
    
  • 相关阅读:
    MQTT 连接服务端失败,报错客户机未连接(32104)
    引入其他类定义的静态变量
    Linux 中文乱码问题
    MQTT 简介
    mybatis xml 特殊字符转义
    如何科学的高效率的选择创建线程数
    【安卓自定义控件系列】自绘控件打造界面超炫功能超强的圆形进度条
    Eclipse简介和使用技巧快捷方式
    MyEclipse如何全局搜索
    JAVA面向对象-----访问修饰符
  • 原文地址:https://www.cnblogs.com/buptLizer/p/2718482.html
Copyright © 2011-2022 走看看