【C++揹包】喜歡衝突的分組揹包問題

上次我們講了二維費用的揹包問題與混合揹包問題,今天,我們來介紹一下喜歡 打架 的揹包問題——分組揹包問題。

分組揹包問題

最初始的問題

例【n+n】一個旅行者有一個容量爲V的超級揹包。現在有n件物品,他們有各自的重量,他們也有各自對應的價值。這些物品被劃分爲若干組,每個組的每個物品之間都有矛盾,所以,爲了讓他們 打架 不打架,所以每組只能派出一位“代表”進入揹包。請問,能裝下的最大價值是多少?

誒喲喂,這物品都開始打架了,這年頭······

算法分析

這個問題呢,就把原來的01揹包問題分組成了在每個組裏頭都有n種選擇。例如:

只能選擇一樣
一樣
一樣
其中一個組
某件物品
另一件物品
又一件物品
揹包

此時,這個組裏有多少個物品就有多少種在組內選擇1件物品的方法。根據這個思路,我們發現,在每一個組裏面都有(物品數)+1種選擇的方法,那個+1就指的是不選擇的情況。於是,我們設f[k][v] 表示前k組物品使費用剩下v能取得的最大價值,則,列出方程:
f(k)(v)=max(f(k1)(v),f(k1)(vw(i))+c(i)ik) f(k)(v)=max(f(k-1)(v),f(k-1)(v-w(i))+c(i)|條件:物品i屬於第k組)
於是,我們想想,如何滿足物品i屬於第k組這個條件。這時候,我們想到了在最裏層與最外層修改for循環,即可滿足條件。
代碼如下:

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int f[5000],c[5000],w[5000],a[5000][5000],i,j,n,m,s,k,t,p;
int main ()
{
 cin>>n>>m>>t;
 for (i=1; i<=m; i++)
   {
   cin>>w[i];
   cin>>c[i];
   cin>>p;
   a[p][0]++;
   a[p][a[p][0]]=i;
   }
 for (k=1; k<=t; k++)  
   for (i=n; i>=0; i--)
     for (j=1; j<=a[k][0]; j++)
       if (i>=w[a[k][j]])
         f[i]=max(f[i],f[i-w[a[k][j]]]+c[a[k][j]]);
 cout<<f[n];
 return 0; 
}

啊,這麼簡單?????只有打五個?纔可以理解我的瘋狂!


今天稍微寫短一點,希望大家多多支持點贊!


今天超級 大福利

分組揹包問題的測試數據點!來一波!

178 26 4
43 1527 3
130 1077 1
74 527 2
155 74 3
157 186 3
144 1796 2
159 727 3
129 929 3
47 338 1
17 1302 1
133 1725 2
124 1998 1
125 1332 2
162 207 3
21 583 3
137 613 1
163 126 2
98 1858 2
140 553 1
152 395 3
34 580 1
40 555 1
66 333 3
38 1594 3
173 1840 1
99 1186 1
4754

測測你的程序,加油哦!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章