6309. 完全背包
(File IO): input:backpack.in output:backpack.out
Time Limits: 1000 ms Memory Limits: 262144 KB Detailed Limits
Description
Input
Output
Sample Input
Sample 1: 2 15 3 2 5 3 Sample 2: 3 70 71 100 69 1 1 2
Sample Output
Sample 1: 10 Sample 2: 140
Data Constraint
Source / Author: backpack
题解:
把物品按性价比排序 ,尽量取性价比高的。(AC只限此题)
这种方法是个水法 ,但对完全背包一类问题的正确率可以达到90percent。
为什么正确率能这么高 ?
可以发现 , 一个性价比高的物品 , 在完全背包问题中 , 优势可以变得很大(买很多) ,当背包容量很大时便更显示出其优势。
10percent是什么情况?
比如现在背包容量为16 , 物品有6种:
代价 : 贡献:
10 3
2 3
3 5
4 5
6 4
4 3
根据性价比排序后 , 排在第一位的是第3件物品,根据90per的贪心 , 我们尽量选他 , 于是选了5个,得到了25的贡献 , 剩下1容量:很浪费,什么也干不了。
但是,我们可以只选4个3物品 , 贡献为20 , 剩余容量4 , 然后再买两个2物品,20+6 = 26 >25!!!
这就是贪心错的原因了 。
附上dp:(注意最终不能只取f[m],有可能m不能刚好取到)
mem(f,128);
f[0]=0;
for(int i=1;i<=n;i++) for(int j=0;j<=m;j++) (j - a[i]>=0) && (f[j] = max(f[j] , f[j - a[i]] + b[i]));
for(int i=0;i<=m;i++) ans = max(ans , f[i]);
return ;
附上贪心:
in(m) , in(n);
for(ll i=1;i<=n;i++) in(a[i]) , in(b[i]);
for(ll i=1;i<=n;i++) c[i] = (node){(double) b[i] / a[i] , i};
sort(c+1,c+1+n ,cmpnode);
for(ll i=1;i<=n;i++)
{
ll can = m / a[c[i].id];
ans+=b[c[i].id] * can;
m-=a[c[i].id] * can;
if(m==0) break;
printf("%d\n" , c[i].id);
}
printf("%lld",ans);