您的位置:首页 > 其它

算法竞赛入门经典:第九章 动态规划初步 9.1恰好型01背包

2015-08-19 09:44 447 查看
/*
恰好型01背包问题:
与01背包问题的唯一不同在于:初始化状态时,除了dp[0]=0之外,其余dp[j]全为INT_MAX,而且需要判断状态是否可以得到

问题:采药。不同草药,采每一株需要一些时间,每一株有自己价值,如何让采到的价值最大。
输入:第一行有两个整数T(1<=T<=1000)和M(1<=M<=100),T代表总共能够用来采药的时间,M代表山洞里的草药数目。
     接下来的M行,每行包括两个在1到100之间(包括1和100)的整数,分别表示采摘某株草药的时间和这株草药的价值
输出:在规定时间内,可以猜到的草药的最大总价值
输入:
70(T采药总时间) 3(M,M行,每行是采药时间和价值)
71 100
69 1
1 2
输出:
3
*/
#include <stdio.h>

#define INT_MAX 0x7fffffff//必须采用负无穷,否则每次比大的时候都比掉了
#define INT_MIN -INT_MAX
#define MAXSIZE 1001

typedef struct Goods
{
	int iWeight;
	int iValue;
}Goods;

int max(int a,int b)
{
	return a > b ? a : b;
}

int gatherHerbs(Goods* goods,int n ,int s)
{
	int dp[MAXSIZE];
	for(int j = 0 ; j <= s; j++)
	{
		dp[j] = INT_MIN;
		//dp[j] = 0;
	}
	dp[0] = 0;
	for(int i = 1; i <= n ; i++)
	{
		for(int j = s; j >= goods[i].iWeight; j--)//逆序更新的原因:保证更新dp[j]时,dp[j-goods[i].iWeight]的状态尚未因为本次更新发生改变,即dp[j-goods[i].iWeight]转移得到dp[i][j]
		{
			if(INT_MIN != dp[j-goods[i].iWeight])//如果状态可得到,用于剪枝,过滤无效状态
			{
				dp[j] = max(dp[j],dp[j-goods[i].iWeight] + goods[i].iValue);
			}
		}
	}
	if(INT_MIN != dp[s])
	{
		return dp[s];
	}
	else
	{
		return -1;
	}
}

void process()
{
	int T,M;
	while(EOF != scanf("%d %d",&T,&M))
	{
		Goods goods[101];
		for(int i = 1 ; i <= M ; i++)
		{
			scanf("%d %d",&goods[i].iWeight,&goods[i].iValue);
		}
		printf("%d\n",gatherHerbs(goods,M,T));
	}
}

int main(int argc,char* argv[])
{
	process();
	getchar();
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: