01-package 解题报告
2009-08-24 01:21
120 查看
01-package
时间限制(普通/Java):1000MS/10000MS运行内存限制:65536KByte总提交:32测试通过:7
描述
给定一个背包的容量k,给定n个物品的体积和价值,物品不可分割,将n个物品中选若干个物品放入背包,求背包内物品的最大价值总和,在价值总和最大的前提下求背包内的最小物品个数c。
输入
第一行是一个整数t,表示测试数据的组数t。
对于每组测试数据,第一行是两个整数n和k,表示物品的个数和背包的容量;
接下来n行,每行两个整数,分别是物品的价值和体积。所有整数都不超过1000。
输出
输出背包内物品的最大价值v,在价值最大的前提下求背包内的最小物品个数c,中间用一个空格隔开。
样例输入
1 310 45 65 1010
样例输出
101
01背包问题动态规划详解2009-08-1116:02
|
分析:新想法。
经典的01背包是:list[i][j]=max(list[i-1][j-pack[i].c]+pack[i].v,list[i-1][j]);
现在要统计最大价值下的最小个数我的想法是每个矩阵的元素都记录当前的物品个数,新加进来的
list[i][j]=max(list[i-1][j-pack[i].c]+pack[i].v,list[i-1][j]);
就这句要换了....换成
{
//如果(要加入的物品价值+((当前背包容量-要加物品的容量)的背包价值))大于不加该物品的当前价值
if((list[i-1][j-pack[i].c]+pack[i].v)>list[i-1][j])
{
list[i][j]=list[i-1][j-pack[i].c]+pack[i].v;
num[i][j]=num[i-1][j-pack[i].c]+1;//把该物品加入
}
//如果(要加入的物品价值+((当前背包容量-要加物品的容量)的背包价值))等于不加该物品的当前价值
elseif((list[i-1][j-pack[i].c]+pack[i].v)==list[i-1][j])
{
//比较((当前背包容量-要加物品的容量)的背包物品数量+1与当前不加该物品时候的背包里物品数目取小的一个
num[i][j]=min(num[i-1][j],num[i-1][j-pack[i].c]+1);
}
}[/code]
代码参考:
#defineM300//M表示物品数目
#defineMAX399999999
#definemin(x,y)x>y?y:x
typedefstructin
{
intc;
intv;
}node;
nodepack[M];
intlist[M+1][500],num[M+1][500];
intdp_bb(nodepack[],intn,intc)//n表示输入物品个数,c表示背包容量
{
inti,mv,t=0,j;
for(i=0;i<=n;i++)//从1开始物品,now初始化
{
list[i][0]=0;
}
for(i=0;i<=c;i++)
{
num[0][i]=0;
list[0][i]=0;
}//完毕初始化
//核心代码
for(i=1;i<=n;i++)
{
for(j=1;j<=c;j++)
{
list[i][j]=list[i-1][j];
num[i][j]=num[i-1][j];
if(j>=pack[i].c)
{
if((list[i-1][j-pack[i].c]+pack[i].v)>list[i-1][j])
{
list[i][j]=list[i-1][j-pack[i].c]+pack[i].v;
num[i][j]=num[i-1][j-pack[i].c]+1;
}
elseif((list[i-1][j-pack[i].c]+pack[i].v)==list[i-1][j])
{
num[i][j]=min(num[i-1][j],num[i-1][j-pack[i].c]+1);
}
}
}
}
mv=list
[c];
returnmv;
}
intmain()
{
intn,c;
intmv;
intt,i;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&c);
for(i=1;i<=n;i++)
{
scanf("%d%d",&pack[i].v,&pack[i].c);
}
mv=dp_bb(pack,n,c);
printf("%d%d/n",mv,num
[c]);
}
return0;
}[/code]
补充:
上面是用二维数组做的0-1背包的,其实一维的就可以完成了的。
从数组最后开始处理,处理起来完全一直。不过要注意下标从1开始都。
代码:
#include<string.h>
#definemax_size1005
#defineT_size10005
#definemin(x,y)x>y?y:x
typedefstruct
{
intw,v;
}node;
nodething[T_size];
intdlist[max_size],num[max_size];
intmain()
{
intt,i,j,c,n;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&t,&c);
memset(dlist,0,sizeof(dlist[0])*(c+1));
memset(num,0,sizeof(num[0])*(c+1));
for(i=1;i<=t;i++)
{
scanf("%d%d",&thing[i].v,&thing[i].w);
}
for(i=t;i>=1;i--)
{
for(j=c;j>=thing[i].w;j--)
{
if(dlist[j]<(dlist[j-thing[i].w]+thing[i].v))
{
dlist[j]=dlist[j-thing[i].w]+thing[i].v;
num[j]=num[j-thing[i].w]+1;
}
elseif(dlist[j]==(dlist[j-thing[i].w]+thing[i].v))
{
num[j]=min(num[j-thing[i].w]+1,num[j]);
}
}
}
printf("%d%d/n",dlist[c],num[c]);
}
return0;
}
[/code]
相关文章推荐
- 洛谷OJ P1141 01迷宫 解题报告
- 解题报告:POJ 1837 Balance 01背包变形
- [Leetcode] 542. 01 Matrix 解题报告
- 最大报销额 (HDU 1864)解题报告(DP - 01 - 背包)
- 洛谷P1141 01迷宫 解题报告
- 解题报告:POJ_2923 Relocation 状态压缩+01背包
- pku 3621 01分数规划 sightseeing cows 解题报告
- HDU-2602___Bone Collector——解题报告 01背包
- 01 Matrix解题报告
- 【LeetCode】01 Matrix 解题报告
- Leetcode 474. Ones and Zeroes 01组合 解题报告
- 动态规划之01背包详解【解题报告】
- 水题解题报告01---校门外的树(POJ原2808)
- 01距离 解题报告
- 第八届湖南省大学生程序设计大赛 - 笑不语@USC 随笔,感想,解题报告
- SRM 556 DIV2 解题报告
- POJ 1056 解题报告 Trie 树
- 【数论】MMT数解题报告
- 强迫症 解题报告
- POJ 1013 Counterfeit Dollar 解题报告