<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      多重背包問題

      本文包含的內容:

      <1> 問題描述

      <2> 基本思路(和完全背包類似)

      <3> 轉換為01背包問題求解(直接利用01背包)

      ---------------------------------------------

      1、問題描述

       

      已知:有一個容量為V的背包和N件物品,第i件物品最多有Num[i]件,每件物品的重量是weight[i],收益是cost[i]。

      問題:在不超過背包容量的情況下,最多能獲得多少價值或收益

      舉例:物品個數N = 3,背包容量為V = 8,則背包可以裝下的最大價值為64.

      ----------------------------------------------

       

      2、基本思路(直接擴展01背包的方程)

      由于本問題和完全背包很類似,這里直接給出方程。

       

      1. 狀態轉移方程:  
      2.   
      3. f[i][v]:表示前i件物品放入重量為v的背包獲得的最大收益  
      4. f[i][v] = max(f[i][v],f[i - 1][V - k * Weight[i]] + k * Value[i]);  
      5. 其中0 <= k <= min(Num[i],V/Weight[i]);//這里和完全背包不同。   
      6. 邊界條件  
      7. f[i][0] = 0;  
      8. f[v][0] = 0;  
      狀態轉移方程:
      
      f[i][v]:表示前i件物品放入重量為v的背包獲得的最大收益
      f[i][v] = max(f[i][v],f[i - 1][V - k * Weight[i]] + k * Value[i]);
      其中0 <= k <= min(Num[i],V/Weight[i]);//這里和完全背包不同。
      邊界條件
      f[i][0] = 0;
      f[v][0] = 0;

      代碼:

       

       

      1. #include <iostream>   
      2. using namespace std;  
      3. const int N = 3;//物品個數   
      4. const int V = 8;//背包容量   
      5. int Weight[N + 1] = {0,1,2,2};  
      6. int Value[N + 1] = {0,6,10,20};  
      7. int Num[N + 1] = {0,10,5,2};  
      8. int f[N + 1][V + 1] = {0};  
      9. /* 
      10. f[i][v]:表示把前i件物品放入容量為v的背包中獲得的最大收益。 
      11. f[i][v] = max(f[i - 1][v],f[i - 1][v - k * Weight[i]] + K * Value[i]);其中1 <= k <= min(Num[i],V/Weight[i]) 
      12. //初始化 
      13. f[i][0] = 0; 
      14. f[0][v] = 0; 
      15. */  
      16. int MultiKnapsack()  
      17. {  
      18.     int nCount = 0;  
      19.     //初始化   
      20.     for (int i = 0;i <= N;i++)  
      21.     {  
      22.         f[i][0] = 0;  
      23.     }  
      24.     for (int v = 0;v <= V;v++)  
      25.     {  
      26.         f[0][v] = 0;  
      27.     }  
      28.     //遞推   
      29.     for (int i = 1;i <= N;i++)  
      30.     {  
      31.         for (int v = Weight[i];v <= V;v++)  
      32.         {  
      33.             f[i][v] = 0;  
      34.             nCount = min(Num[i],v/Weight[i]);//是當前背包容量v,而不是背包的總容量   
      35.             for (int k = 0;k <= nCount;k++)  
      36.             {  
      37.                 f[i][v] = max(f[i][v],f[i - 1][v - k * Weight[i]] + k * Value[i]);  
      38.             }  
      39.         }  
      40.     }  
      41.     return f[N][V];  
      42. }  
      43. int main()  
      44. {  
      45.     cout<<MultiKnapsack()<<endl;  
      46.     system("pause");  
      47.     return 1;  
      48. }  
      #include <iostream>
      using namespace std;
      const int N = 3;//物品個數
      const int V = 8;//背包容量
      int Weight[N + 1] = {0,1,2,2};
      int Value[N + 1] = {0,6,10,20};
      int Num[N + 1] = {0,10,5,2};
      int f[N + 1][V + 1] = {0};
      /*
      f[i][v]:表示把前i件物品放入容量為v的背包中獲得的最大收益。
      f[i][v] = max(f[i - 1][v],f[i - 1][v - k * Weight[i]] + K * Value[i]);其中1 <= k <= min(Num[i],V/Weight[i])
      //初始化
      f[i][0] = 0;
      f[0][v] = 0;
      */
      int MultiKnapsack()
      {
      	int nCount = 0;
      	//初始化
      	for (int i = 0;i <= N;i++)
      	{
      		f[i][0] = 0;
      	}
      	for (int v = 0;v <= V;v++)
      	{
      		f[0][v] = 0;
      	}
      	//遞推
      	for (int i = 1;i <= N;i++)
      	{
      		for (int v = Weight[i];v <= V;v++)
      		{
      			f[i][v] = 0;
      			nCount = min(Num[i],v/Weight[i]);//是當前背包容量v,而不是背包的總容量
      			for (int k = 0;k <= nCount;k++)
      			{
      				f[i][v] = max(f[i][v],f[i - 1][v - k * Weight[i]] + k * Value[i]);
      			}
      		}
      	}
      	return f[N][V];
      }
      int main()
      {
      	cout<<MultiKnapsack()<<endl;
      	system("pause");
      	return 1;
      }

      復雜度分析:

       

      程序需要求解N*V個狀態,每一個狀態需要的時間為O(v/Weight[i]),總的復雜度為O(NV*Σ(V/Weight[i]))。

      3、轉換為01背包問題求解(直接利用01背包)

      思路 1、直接對每一件物品進行拆分成min(Num[i],V/Weight[i])件,之后在拆分后的集合上進行01背包的求解。

      時間復雜度:和基本思路一樣,沒有降低。

      思路 2、采用二進制拆分的思想。對每i件物品,拆分的策略為:新拆分的物品的重量等于1件,2件,4件,..,(2^(k - 1)),Num[i] - (2^(k - 1))件,其中k 是滿足Num[i] - 2^k + 1 > 0 的最大整數。

      注意,

      (1)最后一個物品的件數的求法和前面不同,其直接等于 該物品的最大件數 - 前面已經分配之和。

      (2)分成的這幾件物品的系數和為

      Num[i],表明第i種物品取的件數不能多于Num[i]。

       

      舉例:某物品為13件,則其可以分成四件物品,其系數為1,2,4,6.這里k = 3。

       

      當然,這里使用二進制的前提還是使用二進制拆分能

      保證對于0,,,Num[i]間的每一個整數,均可以用若干個系數的和表示。

      具體使用時,有一個小優化,即:

      我們不對所有的物品進行拆分,因此物品一旦拆分,其物品個數肯定增加,那么復雜度肯定上去。

       

      此時,我們可以選擇性地對物品進行拆分:

       

      (1)如果第i個物品的重量Weight[i] * 物品的個數Num[i] >= 背包總重量V,可以不用拆分。

       

      (2)如果第i個物品的重量Weight[i] * 物品的個數Num[i] < 背包總重量V,可以不用拆分。

       

      其實,拆不拆分,就看該物品能不能滿足完全背包的條件。即,看該物品能不能無限量供應。

       

      解釋:為啥滿足Weight[i] * 物品的個數Num[i] >= 背包總重量V的物品可以不用拆分?

       

      此時,滿足該條件時,此物品原則上是無限供應,直到背包放不下為止。

       

      最終,對于不需要拆分的物品,可以看出完全背包的情況,調用處理完全背包物品的函數。對于需要拆分的物品,可以看出01背包的情況,調用處理01背包物品的函數。

       

      這樣,由于不對滿足完全背包的物品進行拆分,此時物品個數就沒有對所有物品拆分時的物品個數多,即程序中外層循環降低,復雜度也就下去了。

       

      偽代碼:

       


       

      這里:C表示該物品的重量。M表示該物品的個數。V表示背包的最大容量。W表示該物品的收益。

       

      代碼:

       

       

       

      1. #include <iostream>   
      2. using namespace std;  
      3.   
      4. const int N = 3;//物品個數   
      5. const int V = 8;//背包容量   
      6. int Weight[N + 1] = {0,1,2,2};  
      7. int Value[N + 1] = {0,6,10,20};  
      8. int Num[N + 1] = {0,10,5,2};  
      9.   
      10. int f[V + 1] = {0};  
      11. /* 
      12. f[v]:表示把前i件物品放入容量為v的背包中獲得的最大收益。 
      13. f[v] = max(f[v],f[v - Weight[i]] + Value[i]); 
      14. v的為逆序 
      15. */  
      16. void ZeroOnePack(int nWeight,int nValue)  
      17. {  
      18.     for (int v = V;v >= nWeight;v--)  
      19.     {  
      20.         f[v] = max(f[v],f[v - nWeight] + nValue);  
      21.     }  
      22. }  
      23.   
      24. /* 
      25. f[v]:表示把前i件物品放入容量為v的背包中獲得的最大收益。 
      26. f[v] = max(f[v],f[v - Weight[i]] + Value[i]); 
      27. v的為增序 
      28. */  
      29. void CompletePack(int nWeight,int nValue)  
      30. {  
      31.     for (int v = nWeight;v <= V;v++)  
      32.     {  
      33.         f[v] = max(f[v],f[v - nWeight] + nValue);  
      34.     }  
      35. }  
      36.   
      37. int MultiKnapsack()  
      38. {  
      39.     int k = 1;  
      40.     int nCount = 0;  
      41.     for (int i = 1;i <= N;i++)  
      42.     {  
      43.         if (Weight[i] * Num[i] >= V)  
      44.         {  
      45.             //完全背包:該類物品原則上是無限供應,   
      46.             //此時滿足條件Weight[i] * Num[i] >= V時,   
      47.             //表示無限量供應,直到背包放不下為止.   
      48.             CompletePack(Weight[i],Value[i]);  
      49.         }  
      50.         else  
      51.         {  
      52.             k = 1;  
      53.             nCount = Num[i];  
      54.             while(k <= nCount)  
      55.             {  
      56.                 ZeroOnePack(k * Weight[i],k * Value[i]);  
      57.                 nCount -= k;  
      58.                 k *= 2;  
      59.             }  
      60.             ZeroOnePack(nCount * Weight[i],nCount * Value[i]);  
      61.         }  
      62.     }  
      63.     return f[V];  
      64. }  
      65.   
      66. int main()  
      67. {  
      68.     cout<<MultiKnapsack()<<endl;  
      69.     system("pause");  
      70.     return 1;  
      71. }  

       

       

      posted @ 2015-04-07 00:40  柳下_MBX  閱讀(314)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲综合一区二区三区| 亚洲国产精品一区二区第一页| 国内精品无码一区二区三区| 亚洲欧美日韩综合一区二区| 99福利一区二区视频| 人人色在线视频播放| 东京热人妻中文无码| 日韩精品人妻中文字幕| 伊通| 亚洲中文字幕无码日韩精品| 99999久久久久久亚洲| 久久精品免费自拍视频| 亚洲日韩日本中文在线| 国产日产免费高清欧美一区| 一区二区三区四区自拍视频| 日韩有码中文字幕第一页| 国产95在线 | 欧美| 国产午夜精品福利免费看| 我要看特黄特黄的亚洲黄片| 99国产精品欧美一区二区三区| 人妻一区二区三区三区| 九九热精品在线观看| 国产精品久久精品| 四虎影视www在线播放| 国产精品一国产精品亚洲| 日韩成人无码影院| 日本xxxx色视频在线播放| 国产网友愉拍精品视频手机| 日韩幕无线码一区中文| 深夜福利国产精品中文字幕| 日产精品久久久久久久| 国产精品麻豆欧美日韩ww| 中文字幕人妻无码一夲道| 国产在线永久视频| 中文字幕一区二区三区麻豆| 无码免费大香伊蕉在人线国产| 清水河县| 成人福利一区二区视频在线| 精品久久久久国产免费| 欧美精品国产综合久久| 亚洲日韩国产二区无码|