• 回溯法——01背包问题


    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    #define MAXN 10
    
    struct Goods_Info
    {
    	int v;		//价值
    	int w;		//重量
    	double vw;	//价值重量比
    }goods[MAXN];
    
    int n;
    int maxValue;
    bool solu[MAXN];
    bool optimalSolu[MAXN];
    
    bool Cmp(const Goods_Info a, const Goods_Info b)
    {
    	return a.vw > b.vw;
    }
    
    //可装入一部分物品时,取得的最优价值
    double Bound(int i, double v, int c)
    {
    	//以物品的价值重量比递减将物品装入背包
    	while (i <= n && goods[i].w <= c)
    	{
    		v += goods[i].v;
    		c -= goods[i].w;
    		i++;
    	}
    	//将背包装满
    	if (i <= n)
    	{
    		v += (goods[i].vw * c);
    	}
    	return v;
    }
    
    void Backtrack(int k, int cv, int rc)
    {
    	if (k > n)
    	{
    		if (cv > maxValue)
    		{
    			maxValue = cv;
    			int i;
    			for (i = 1; i <= n; i++)
    			{
    				optimalSolu[i] = solu[i];
    			}
    		}
    	}
    	else
    	{
    		if (goods[k].w <= rc) //当前物品能否装入背包
    		{
    			solu[k] = true;
    			Backtrack(k+1, cv+goods[k].v, rc-goods[k].w);
    		}
    		if (Bound(k+1, cv, rc) > maxValue) //剩余物品的最优价值是否更优
    		{
    			solu[k] = false;
    			Backtrack(k+1, cv, rc);
    		}
    	}
    }
    
    int main(void)
    {
    	int c;
    	while (scanf("%d%d", &n, &c) != EOF)
    	{
    		int i;
    		for (i = 1; i <= n; i++)
    		{
    			scanf("%d%d", &goods[i].v, &goods[i].w);
    			goods[i].vw = (double)goods[i].v / goods[i].w;
    		}
    
    		//将物品按照价值重量比递减排序
    		sort(goods+1, goods+n+1, Cmp);
    
    		maxValue = 0;
    		Backtrack(1, 0, c);
    
    		printf("%d\n", maxValue); //最优值
    		
    		/*
    		//最优解
    		printf("value:");
    		for (i = 1; i <= n; i++)
    		{
    			printf("\t%d", goods[i].v);
    		}
    		printf("\nweight:");
    		for (i = 1; i <= n; i++)
    		{
    			printf("\t%d", goods[i].w);
    		}
    		printf("\nstatus:");
    		for (i = 1; i <= n; i++)
    		{
    			printf("\t%d", optimalSolu[i]);
    		}
    		printf("\n");
    		*/
    	}
    	return 0;
    }
    
    /*
    5 27
    8 3
    12 7
    10 5
    8 4
    15 9
    
    5 27
    8 8
    12 12
    10 10
    8 8
    15 15
    
    5 26
    8 8
    12 12
    10 10
    8 8
    15 15
    
    5 28
    8 8
    12 12
    10 10
    8 8
    15 15
    
    5 29
    8 8
    12 12
    10 10
    8 8
    15 15
    */


  • 相关阅读:
    C# 一个数组集合,任意组合,不遗漏,不重复
    C# 对象遍历 string类型 null转空字符串和去前后空格
    mysql中varchar可以存多少汉字
    ping ipconfig telnet
    mysql 生成UUID() 即 ORACLE 中的guid()函数
    a标签的href和onclick
    JQuery设置checkbox选中或取消等相关操作
    JS eval()函数
    ztree设置节点checked,选中某节点等相关操作
    Windows数据库定时备份
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3040021.html
Copyright © 2020-2023  润新知