01背包回溯问题

假设某一机器由 n 个部件组成,每一种部件都可以从 m 个不同的供应商处购得。设 wij 从供应商 j 处购得的部件 i 的重量,cij 是相应的价格。试设计算法求出总价格不超过 c 的最小重量机器设计,其中,n=2, m=3, c=850,每个部件的重量和价格如下表所示。

 

#include<cstdio>
#include<algorithm>
using namespace std;
int n;				//需要n个部件 
int m;				//m个供应商 
int sum_value;		//总价格上限 
/*定义一个包含部件重量和部件价格的结构体*/
struct stu
{
	int weight;
	int value; 
}component[1003][1003];

int min_weight = 999999;			//存储最小的重量
int max_value = 0; 					//存储最大的价格
int cur_weight = 0;					//存储当前的重量
int cur_value = 0; 					//存储当前的价格
int best[100003] = {0}; 			//最佳选择方案(记录供应商的序号1~m) 
int cur_best[100003] = {0};			//当前选择方案(记录供应商的序号1~m)
	
/*回溯、变量为部件的值*/
int traceback(int num) 
{
	if(num == n)
	{ 
        if(cur_weight < min_weight)
		{
            min_weight = cur_weight; 			//更新最小重量 
            max_value = cur_value; 				//更新最大价格 
            for(int i=0; i<n; i++)
            { 
                best[i] = cur_best[i] + 1;		//更新最佳选择方案,数组从0开始,输出要加1
			} 
        }
    }
    
    for(int i=0; i<m; i++) 
	{ 
        cur_best[num] = i;
        cur_weight += component[num][i].weight;
        cur_value += component[num][i].value;
        if(cur_weight < min_weight && cur_value <= sum_value) //等号必须加 
            traceback(num + 1);
        cur_weight -= component[num][i].weight;
        cur_value -= component[num][i].value;
        cur_best[num] = 0;
    }
} 
int main()
{
	printf("请依次输入部件的个数、供应商的个数、总价格上限:\n");
	scanf("%d%d%d",&n, &m, &sum_value);
	for(int i=0; i<n; i++)
	{
		printf("请依次输入部件%d相对应的供应商1~m的重量以及价格:\n",i + 1);
        for(int j=0; j<m; j++)
		{
            scanf("%d%d", &component[i][j].weight, &component[i][j].value);
        }
    }
    traceback(0);		//回溯   传递的参数是部件、数组从0开始 
    printf("最小的重量为%d\n",min_weight);
    printf("最大的价值为%d\n",max_value);
	printf("=====此时的选择方案为=====\n\n");
    for(int i=0; i<n; i++)
	{
        printf("部件%d从供应商%d处购买\n",i + 1, best[i]);
    }
	return 0;
}

 

猜你喜欢

转载自blog.csdn.net/tian_he_he/article/details/86025114