码迷,mamicode.com
首页 > 其他好文 > 详细

背包的。

时间:2015-01-26 16:27:31      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:

首先是自由评述:这几天的背包问题

0 1包:逆序。结果由上一组元素刷过去的结果得来的。

 

技术分享
 1 void ZeroOnePack(int val,int vol)
 2 {
 3 
 4     int i;
 5     for(i=V;i>=vol;i--)
 6     {
 7         if(dp[i-vol]+val>dp[i])
 8         {
 9             dp[i] = dp[i-vol]+val;
10         }
11     }
12 }
01背包

 

 

 

满 包:初始化的时候。这个有个好方法 -inf 其中const int inf = 1<<28-1;这样的。写在顶部

    结果符合的得重新附值。 dp[0]=0常见的。

    原理:明确的是这个值要足够小或者大。能导致过滤掉这个结果。

       可以用这个来做 至多和至少问题。已经必须放入多少个的问题。

       我想法是弄成二维的 然后至少往上搜。至多往下搜。已经必须放入多少的直接在这一层搜索。

完全背包:顺序。注意这个复杂度只有N*V了。因为不是一个物品刷一层循环 而是一种物品刷一层循环。并不能用01包的原理去单纯解释。

 

技术分享
 1 void ZeroOnePack(int val,int vol)
 2 {
 3 
 4     int i;
 5     for(i=vol;i<=V;i+)
 6     {
 7         if(dp[i-vol]+val>dp[i])
 8         {
 9             dp[i] = dp[i-vol]+val;
10         }
11     }
12 }
完全背包

 

 

多重背包:如果说是利用完全包的刷一层方法。并不好知道你的个数使用了多少来维护个数!。所以分完全包的情况vol*num>=V 也就是说在这个范围内你     可以随意数量放置。(当然拉。必须是最优的。)而如果小于这个值 就用01包。 但是是用bin优化过的再进行01包。 这个时候是顺序还是逆序     呢?是顺序的。理解可以用01包去里面。当初错误理解完全包的方法可以在这里得到好的解释。所以用一个变量k=1 来进行。最后还得进行一次     num的01至于为什么 这个和bin 有关

 

技术分享
 1 void MulPack(int val,int vol,int num)  
 2 {  
 3     if(val*num>=aver)  
 4     {  
 5         ComPack(val,vol);  
 6         return;  
 7     }  
 8    
 9     int k=1;  
10     while(k<num)  
11     {  
12         ZeroOnePack(k*val,k*vol);  
13  
14         num -= k;  
15         k *= 2;  
16     }
17     ZeroOnePack(num*val,num*vol); 
18 }
多重背包

 

混合背包:这种背包并不难,只要传入方式正确。以及注意满包问题。

 

技术分享
 1 int max(int a,int b)
 2 {
 3     return a>b?a:b;
 4 }
 5 void OneZeroPack(int val,int vol)
 6 {
 7     int j;
 8     for(j=V;j>=vol;j--)
 9     {
10         dp[j] = max(dp[j],dp[j-vol]+val);
11     }
12 }
13 void ComPack(int val,int vol)
14 {
15     int j;
16     for(j=vol;j<=V;j++)
17     {
18         dp[j] = max(dp[j],dp[j-vol]+val);
19     }
20 }
21 void MulPack(int val,int vol,int num)
22 {
23     if(val*num>=V)
24     {
25         ComPack(val,vol);
26         return;
27     }
28     int k = 1;
29     while(k<num)
30     {
31         OneZeroPack(val,vol);
32         num -= k;
33         k *= 2;
34     }
35     OneZeroPack(val,vol);
36 }
上述三种在一起。

 

 

二维费用:说白了是添加一个数组。多一层循环。实际上经常和满包之类的在一起。这个时候注意初始化即可。另外,二维费用经常出现的是数目的限制。

     必须放入指定M个数目。这个时候往往就是满包问题了。状态划分也得注意其含义的变化了。其实如果没有这类问题。那个数目限制还有什么意     义啊!。也对。其实我们是为了满足条件才使用的二维。然后状态方程使用来源法即可。

 

背包的。

标签:

原文地址:http://www.cnblogs.com/Milkor/p/4250461.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!