动态规划之0-1背包问题

动态规划之0-1背包问题

动态规则:把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的方法。

题目描述:

       有编号分别为a,b,c,d,e的五件物品(各只有一件),它们的重量分别是4,5,6,2,2,它们的价值分别是6,4,5,3,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

0-1背包问题,是用来介绍动态规划算法最经典的例子。

0-1背包的状态转换方程:f[i, j] = Max{ f[i - 1, j - Wi] + Vi, f[i - 1, j] },(j >= Wi)

 - f[i,j]:表示在前i件物品中选择若干件放在承重为j的背包中,可以取得的最大价值。

 - Wi:是第i种物品的重量;

 - Vi:表示第i件物品的价值。

决策:为了背包中物品总价值最大化,第i件物品应该放入背包中吗?

nameweightvalue12345678910
a460006666666
b54000666661010
c65000666661011
d23033669991011
e26066991212151515

根据上面的公式可以很容易的得出这张表,最右下边的值15即为解。

代码实现:

#include <stdio.h>

int dp[2014][1024];
char item[] = { 'a', 'b', 'c', 'd', 'e' };



int max(int x, int y)
{
	return x > y ? x : y;
}

void packgeProblem(int sumW, int n, int *w, int *v, int *x)
{
	for (int i = 0; i <= n; i++)
		dp[i][0] = 0;  // 首行清0
	for (int j = 0; j <= sumW; j++)
		dp[0][j] = 0;  // 首列清0(其实这步没有必要)

	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= sumW; j++)
		{
			if (j >= w[i - 1]) 
				dp[i][j] = max(dp[i - 1][j], v[i-1] + dp[i - 1][j-w[i - 1]]); // 取(上格)与(些物品价值+剩余重量所能装的上行价值)最大值
			else 
				dp[i][j] = dp[i - 1][j]; // 如果背包剩余重量不足,取上行值
		}
	}
	
	for (int i = n,j=sumW; i > 0; i--)  // 标识所选物品
	{
		if (dp[i][j] > dp[i - 1][j])
		{
			x[i - 1] = 1;  // 已选
			j -= w[i - 1];
		}
		else x[i - 1] = 0;   // 未选
	}
	for (int i = 0; i < n; i++)
		if (x[i] == 1) printf("%c ", item[i]);
		
	printf("\n");
}


int main()
{
	int w[6] = {4, 5, 6, 2, 2 };
	int v[6] = {6, 4, 5, 3, 6 };
	int sumW = 10;
	int x[6] = { 0, 0, 0, 0, 0 };

	packgeProblem(sumW, 5, w, v, x);

	getchar();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值