描述 description
學校實行學分制。每門的必修課都有固定的學分,同時還必須獲得相應的選修課程學分。學校開設了n(n<300)門的選修課程,每個學生可選課程的數量m是給定的。學生選修了這m門課並考核通過就能獲得相應的學分。
在選修課程中,有些課程可以直接選修,有些課程需要一定的基礎知識,必須在選了其它的一些課程的基礎上才能選修。例如《frontpage》必須在選修了《windows操作基礎》之後才能選修。我們稱《windows操作基礎》是《frontpage》的先修課。每門課的直接先修課最多只有一門。兩門課也可能存在相同的先修課。每門課都有乙個課號,依次為1,2,3,…。 例如:
表中1是2的先修課,2是3、4的先修課。如果要選3,那麼1和2都一定已被選修過。 你的任務是為自己確定乙個選課方案,使得你能得到的學分最多,並且必須滿足先修課優先的原則。假定課程之間不存在時間上的衝突。
輸入格式 input format
輸入檔案的第一行包括兩個整數n、m(中間用乙個空格隔開)其中1≤n≤300,1≤m≤n。
以下n行每行代表一門課。課號依次為1,2,…,n。每行有兩個數(用乙個空格隔開),第乙個數為這門課先修課的課號(若不存在先修課則該項為0),第二個數為這門課的學分。學分是不超過10的正整數。
輸出格式 output format
輸出檔案只有乙個數,實際所選課程的學分總數。
樣例輸入 sample input
7 42 2
0 10 4
2 17 1
7 62 2
樣例輸出 sample output
[分析]
有些課程可能有先修課且最多只有一門先修課,而這些有先修課的課程必須是選了先修課才能選,求限選m課的情況下所能達到的最大學分。題目一讀完,顯然可以反應出這是乙個帶有依賴的揹包問題。因為每門課程最多只有一門先修課程,所以這些課程的依賴關係可以由森林來表示。這樣我們就可以把森林中的每一棵樹看成是乙個泛化物品(具體介紹見:http://ufownl.blog.163.com/blog/static/1250122200931174848906/
),這樣我們就可以對這些泛化物體作01揹包從而得到最優解。先設h[i][k]表示泛化物體i在花費代價k時所能得到的最大價值,再設s[i][j]表示僅考慮前i件泛化物體且揹包容量為j時所能得到的最大價值,可得狀態轉移方程s[i][j]=max。邊界條件和普通01揹包類似,就不再贅述了。現在想必大家最關心的問題是h[i][k]如何得到,其實這個並不困難,我們知道,如果將一棵樹的根去掉,那麼這個根原來的子樹就會形成一座森林,這個性質給了我們啟發,實際上要求一棵樹的h[i][k]我們可以遞迴的求這棵樹的每個子樹的h[i][k](即把該樹根的所有子樹看成一座森林像上面一樣按泛化物體的思想做01揹包),因為子樹對根的依賴關係,每個子樹的h[i][k]求出以後可以很容易的求到當前樹的h[i][k]。這樣h[i][k]的問題就解決了,按照這種遞迴的思想就能比較容易寫出**了。關鍵要注意的地方就是在計算某個子樹的h[i][k]時,根是必須選的,所以在動態規劃的時候要為根留出空間,dp結束過後要將根的值加到結果中,我就是開始沒注意這個問題導致最終走了n多彎路才ac。
[**]
#include
using namespace std;
struct treenode
;void solve(treenode *pnodes, int ncost, int nweight)
}if (pnodes->nweight==0) return;
for (int i=ncost+1; i>=1; i--) nweight[i]=nweight[i-1]+pnodes->nweight;
}int main()
}int nweight[301];
solve(nodes, m, nweight);
cout《通用有依賴的揹包問題模板**
struct treenode
;void solve(treenode *pnodes, int ncost, int nweight)
}if (pnodes->nweight==0) return;
for (int i=ncost+pnodes->nvolume; i>=pnodes->nvolume; i--) nweight[i]=nweight[i-pnodes->nvolume]+pnodes->nweight;
}
有依賴的揹包問題
簡化的問題 這種揹包問題的物品間存在某種 依賴 的關係。也就是說,i依賴於j,表示若選物品i,則必須選物品j。為了簡化起見,我們先設沒有某個物品既依賴於別的物品,又被別的物品所依賴 另外,沒有某件物品同時依賴多件物品。演算法 這個問題由noip2006金明的預算方案一題擴充套件而來。遵從該題的提法,...
有依賴的揹包問題
第二天叫醒我的不是鬧鐘,是夢想!有 n 個物品和乙個容量是 v 的揹包。物品之間具有依賴關係,且依賴關係組成一棵樹的形狀。如果選擇乙個物品,則必須選擇它的父節點。如果選擇物品5,則必須選擇物品1和2。這是因為2是5的父節點,1是2的父節點。每件物品的編號是 i,體積是 vi,價值是 wi,依賴的父節...
有依賴的揹包問題
題目鏈結 有 n 個物品和乙個容量是 v 的揹包。物品之間具有依賴關係,且依賴關係組成一棵樹的形狀。如果選擇乙個物品,則必須選擇它的父節點。如下圖所示 如果選擇物品5,則必須選擇物品1和2。這是因為2是5的父節點,1是2的父節點。每件物品的編號是 i,體積是 vi,價值是 wi,依賴的父節點編號是 ...