[Poj #1853] Cat

首先这题中,没有一个数可以扔掉,不能直接背包。
但是转念一想:如果把背包的上限设成平均值,然后选出最接近平均值的物品即可。
但是还有一个问题:都是浮点数。
可以转化成百分比,由于题目中说误差不会在0.2%以内,乘以两万强转int就行。
最后,别忘记记录路径,path[j]表示到达重量j时最后一个加入的物品编号。

#include<cstdio>
#include<cstring>
using namespace std;
int a[1010];
int path[10010],dp[100010];
double b[1010];
int main()
{
	int n,m,i,j,k,x,y,z;
	double sum;
	while(1)
	{
		scanf("%d",&n);
		if(!n)break;
		memset(dp,0,sizeof(dp));
		memset(path,0,sizeof(path));
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		sum=0;
		for(i=1;i<=n;i++)
		{
			scanf("%lf",&b[i]);
			sum+=b[i];
		}
		for(i=1;i<=n;i++)
		{
			a[i]=b[i]/sum*20000;
		}
		dp[0]=1;
		for(i=1;i<=n;i++)
		{
			for(j=10000;j>=a[i];j--)
			{
				if(!dp[j]&&dp[j-a[i]])
				{
					dp[j]=1;
					path[j]=i;
				}
			}
		}
		for(i=10000;i>=4800;i--)
		{
			if(path[i])break;
		}
		while(i)
		{
			printf("%d ",path[i]);
			i-=a[path[i]];
		}
		printf("
");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Rain142857/p/11730997.html