http://acm.hdu.edu.cn/showproblem.php?pid=3732
题意:已知物品的价值和cost,求在有限背包容量下的最大价值,此题的特殊之处在于 :物品的数量极大(100000),但 价值 和 cost 所有组合数只有100种,故可以将传统的01背包转换成多重背包并用二进制优化
#pragma warning (disable:4786)
#include<stdio.h>
#include<string.h>
int bag[11111],count[11][11];
int Sumc;
void multi_pack(int val,int cost,int num){
int sum=0;
int k=1;
int j;
while(sum<num){
for(j=Sumc;j>=cost*k;j--){
if(bag[j]<bag[j-cost*k]+val*k)
bag[j]=bag[j-cost*k]+val*k;
}
sum+=k;
if(sum+k*2>num)
k=num-sum;
else
k+=k;
}
}
int main()
{
int n;
while(scanf("%d%d",&n,&Sumc)==2)
{
char ip[11];
int i,j,val,cost;
memset(count,0,sizeof(count));
memset(bag,0,sizeof(bag));
for(i=1;i<=n;i++)
{
scanf("%s%d%d",ip,&val,&cost);
count[val][cost]++; //统计所有相同价值、相同cost的物品的总个数
}
//因为数据的特殊性(价值和cost的所有组合数只有10*10种,100*V*log num[i]要远小于题设的最大物品数100000 *V)
//故将原来得01背包问题转换成多重背包问题
for(i=0;i<=10;i++){
for(j=0;j<=10;j++){
if(count[i][j]>0){
multi_pack(i,j,count[i][j]);
}
}
}
printf("%d\n",bag[Sumc]);
}
return 0;
}