01背包问题-动态规划,回溯,分支限界

01背包问题

给定 种物品和一背包。物品 的重量是wi,其价值为vi,背包的容量为 。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?

1.动态规划
来源:【动态规划】0-1背包问题(C++)
在这里插入图片描述
例子:
在这里插入图片描述
在这里插入图片描述


// 【动态规划】0-1背包问题
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 100


// 最大价值表,填表
void Knapsack(int n,int c,int w[],int v[],int x[],int m[][N])
{
   
	// 以下两个for循环是最大价值表m的最后一行
	for (int j = 0;j <= c;j++)
		m[n][j] = 0;
	for (int j = w[n];j <= c;j++)
		m[n][j] = v[n];
		
	// 以下是表m最后一行以上的部分
	for (int i = n - 1;i >= 1;i--)
	{
   
		// 背包容量<物品重量,即装不下;将m[i+1][j](下一行同列)的值赋给m[i][j]
		for (int j = 0;j <= c;j++)
			m[i][j] = m[i + 1][j];
			
		// 背包容量>=物品重量,即可以装下;放:m[i][j]=m[i + 1][j - w[i]] + v[i]
		//不放:m[i][j]=m[i + 1][j], 哪个价值大,就采取哪种方式
		for (int j = w[i];j <= c;j++)
			m[i][j] = max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]);
	}
}

// 将最优解存入数组
void Traceback(int n,int c,int w[],int v[],int x[],int m[][N])
{
   
	int cTemp = c;	// 临时背包容量
	for (int i = 1;i <= n;i++)
	{
   
		// 价值相等,说明没有放入这个物品,0
		if (m[i][cTemp] == m[i + 1][cTemp])
			x[i] = 0;
		//价值不相等,说明放入了这个物品,1	,放入了一个物品,背包剩余容量为原容量-物品重量
		else
		{
   
			x[i] = 1;	
			cTemp -= w[i]; 
		}
	}
}



int main()
{
   
	int n,c,w[N],v
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是0-1背包问题分支限界法的C语言实现示例: ```c #include <stdio.h> #define MAX_N 100 // 背包中物品的最大数量 typedef struct { int weight; // 物品的重量 int value; // 物品的价值 } Item; int maxProfit = 0; // 最大价值 int bestSolution[MAX_N]; // 最优解 int currentSolution[MAX_N]; // 当前解 int currentWeight = 0; // 当前解的总重量 int currentValue = 0; // 当前解的总价值 int remainingValue = 0; // 剩余物品的总价值 Item items[MAX_N]; // 物品数组 int n; // 物品的数量 int capacity; // 背包的容量 // 计算剩余物品的总价值 int calculateRemainingValue(int k) { int remainingValue = 0; for (int i = k + 1; i < n; i++) { remainingValue += items[i].value; } return remainingValue; } // 回溯搜索 void backtrack(int k) { if (k == n) { if (currentValue > maxProfit) { maxProfit = currentValue; for (int i = 0; i < n; i++) { bestSolution[i] = currentSolution[i]; } } return; } if (currentWeight + items[k].weight <= capacity) { currentWeight += items[k].weight; currentValue += items[k].value; remainingValue = calculateRemainingValue(k); if (currentValue + remainingValue > maxProfit) { currentSolution[k] = 1; backtrack(k + 1); currentSolution[k] = 0; } currentWeight -= items[k].weight; currentValue -= items[k].value; } if (currentValue + remainingValue > maxProfit) { currentSolution[k] = 0; backtrack(k + 1); } } int main() { printf("请输入物品的数量:"); scanf("%d", &n); printf("请输入背包的容量:"); scanf("%d", &capacity); printf("请输入每个物品的重量和价值:\n"); for (int i = 0; i < n; i++) { scanf("%d %d", &items[i].weight, &items[i].value); } backtrack(0); printf("最大价值为:%d\n", maxProfit); printf("最优解为:"); for (int i = 0; i < n; i++) { printf("%d ", bestSolution[i]); } printf("\n"); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值