首先这题中,没有一个数可以扔掉,不能直接背包。
但是转念一想:如果把背包的上限设成平均值,然后选出最接近平均值的物品即可。
但是还有一个问题:都是浮点数。
可以转化成百分比,由于题目中说误差不会在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;
}