背包问题

算法代码

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

const int N=4;//品种
const int C=9;//容量

int Knapsack_optimization(int S[],int P[],int OC[])//优化O(C)空间 容量C逆序遍历 S有序
{
	for(int i=1; i<=N;i++)
		for(int j=C;j>=S[i];j--)
			OC[j]= OC[j] > (P[i] + OC[j-S[i]]) ? OC[j] : (P[i] + OC[j-S[i]]);		
	return OC[C];				//返回最大总价值
} 
int Knapsack_Positive(int S[],int P[])//优化O(2C)空间 容量C正序遍历 S有序
{
	int i,j;
	int V[C+1]={0,};//价值
	int m[C+1]={0,};//标记放入物品
	for (i=1; i<=N;i++)
	 	for (j=1;j<=C;j++)//for (j=1;j<=C&&j<2*S[i];j++) 一致		
			if (S[i] <= j&&m[j-S[i]]!=i&&V[j] < (V[j-S[i]]+P[i])) //体积不超过容量 无重复 升值 
			{
				V[j]= V[j-S[i]]+P[i] ;	//价值转移
				m[j]=i; //标记放入物品
			}
	return V[C];				//返回最大总价值
} 
int Knapsack_recursion(int S[],int P[],int key ,int s)//递归  O(2^n)  S有序 
{
	if(key>N||s+S[key]>C)   	return 0;
	if(key==N)		return P[key];
	return Knapsack_recursion(S,P,key+1,s)>(P[key]+Knapsack_recursion(S,P,key+1,s+S[key]))
		?Knapsack_recursion(S,P,key+1,s):(P[key]+Knapsack_recursion(S,P,key+1,s+S[key]));
}
int Knapsack(int S[],int P[],int V[][C+1])//  O(CN)空间
{
	for (int i=0;i<=N;i++)  
		V[i][0]=0;		//背包容量为0
	for (int j=0;j<=C;j++)
		V[0][j]=0;		//背包未装入任何物品
	for (i=1; i<=N;i++)
	 	for (j=1;j<=C;j++)
			if (S[i] > j)  		//物品ui的体积si超过容量j,不装入。
		      V[i][j]=V[i-1][j];	//取上一次的计算结果
			else//物品ui的体积si不超过容量j,可装入。
				V[i][j]=V[i-1][j]>(V[i-1][j-S[i]]+P[i])?V[i-1][j]:(V[i-1][j-S[i]]+P[i]);
	return V[N][C];				//返回最大总价值
}

void table(int S[],int P[],int V[][C+1])
{
	int i,j;
	printf("S: 0  2  3  4  5\n");
	printf("P: 0  3  4  5  7\n");
	printf("C =%2d  ",C);
	for(i=0;i<=C;i++)
		printf("%3d",i);
	printf("\n       ");
	for(i=1;i<=C+1;i++)
		printf("%3d",0);
	printf("\n");
	for(i=1;i<=N;i++)
	{
		printf("V[%d]=%2d",i,S[i]);
		for(j=0;j<=C;j++)
			printf("%3d",V[i][j]);
		printf("\n");
	}
}
void main ()
{
	int S[N+1]={0,2,3,4,5};
	int P[N+1]={0,3,4,5,7};
/*	int S[N+1]={0,6,7,8,10};
	int P[N+1]={0,6,7,8,10};*/

	int V[N+1][C+1]; 
	int OC[C+1]={0,};
	Knapsack(S,P,V);
	table(S,P,V);
	printf("\nKnapsack              : %d\n",Knapsack(S,P,V) );
    printf("\nKnapsack_recursion    : %d\n",Knapsack_recursion(S,P,1,0) );
	printf("\nKnapsack_Positive     : %d\n",Knapsack_Positive(S,P) );
    printf("\nKnapsack_optimization : %d\n\n\n",Knapsack_optimization(S,P,OC) );
	
	
	system("pause");
}

测试结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值