1. 程式人生 > >揹包九講 c++實現完整程式碼

揹包九講 c++實現完整程式碼

3)程式碼:

#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;
#define maxV 1000
#define maxG 100

int main(void) {
	int cases, n, v, ci[maxV], wi[maxV], di, f[maxV];
	freopen("7.txt", "r", stdin);
	cin >> cases;
	while (cases--) {
		memset(f, 0, sizeof(f));
		cin >> n >> v;
		
		// group[i]空表示i號物品有依賴,因此存放到其他組裡
		// 只有一個元素表示i號物品既無依賴也不被依賴
		// 有多個元素表示i號物品被依賴,這裡自己的編號i也被存放進group[i]
		vector<vector<int> > groups(n); 

		// 讀入資料並儲存起來
		for (int i = 0; i < n; i++) {
			cin >> ci[i] >> wi[i] >> di;
			if (di == -1) groups[i].push_back(i);
			else groups[di].push_back(i);
		}

		// 對每個有多個元素的組進行01揹包
		for (int i = 0; i < n; i++) {
			if (groups[i].size() > 1) {
				vector<int> giOri; //group[i]的拷貝,排除i本身
				int newV = v - ci[i];

				// 複製group[i]中的元素,排除i
				for (int j = 0; j < groups[i].size(); j++) {
					if (groups[i][j] != i)
						giOri.push_back(groups[i][j]);
				}

				// 把等效物品組存入group[i]中
				groups[i].clear();
				groups[i].resize(newV + 1, 0);
				for (int j = 0; j < giOri.size(); j++) {
					for (int k = newV; k >= 0; k--) {
						if (ci[giOri[j]] <= k) {
							groups[i][k] = max(groups[i][k], groups[i][k - ci[giOri[j]]] + wi[giOri[j]]);
						}
					}
				}
			}
		}

		// 進行分組揹包
		for (int i = 0; i < n; i++) {
			if (groups[i].size() == 0) continue;
			else if (groups[i].size() == 1) { // i物品無依賴且不被依賴
				for (int j = v; j >=0; j--) {
					if (j >= ci[i])
						f[j] = max(f[j], f[j - ci[i]] + wi[i]);
				}
			} else { // i物品被依賴, i組第k個物品的cost為k + ci[i], weight為group[i][k] + wi[i]
				for (int j = v; j >= 0; j--) { 
					for (int k = 0; k < groups[i].size(); k++) {
						if (j >= k + ci[i])
							f[j] = max(f[j], f[j - k - ci[i]] + groups[i][k] + wi[i]);
					}
				}
			}
		}
		
		cout << f[v] << endl;
	}
}

4)測試檔案:

2
3 10
3 5 -1
4 6 0
7 10 0

4 15
4 1 -1
6 8 0
7 10 0
10 4 -1


相關推薦

揹包 c++實現完整程式碼

3)程式碼: #include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std; #define maxV 1000 #defi

揹包--多重揹包的原理及程式碼實現

本文節選這篇部落格:http://blog.csdn.net/tinyguyyy/article/details/51203935 這篇文章的內容RT 個人認為01揹包和完全揹包揹包九講講的很具體了,多重揹包關於二進位制思想的我的沒有接觸過,有點不求甚解,所

『基礎DP專題:LIS,LCS和揹包(不包括泛化物品)及實現

<前言> <更新提示> <第一次更新>重點揹包 <正文> 序列dp問題 LIS問題(最長上升子序列) 求長度為n的序列A中最長上升子序列的長度。 分析 狀態:f[i]代表以a[i]結尾的最長上升子

二叉樹的鏈式儲存結構及實現C語言完整程式碼+詳細註釋)

鏈式儲存結構儲存二叉樹,實際上就是採用連結串列儲存二叉樹。 既然是使用連結串列,首先需要構建連結串列中節點的結構。考慮到儲存物件為二叉樹,其各個節點最多包含 3 部分,依次是:左孩子、節點資料和右孩子,因此,連結串列的每個節點都由這 3 部分組成: 圖 1 二叉連結串列結點構成 圖 1 中,Lchi

dd大牛的揹包

P01: 01揹包問題  題目  有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。  基本思路  這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放

揹包學習筆記

參考資料:https://www.cnblogs.com/jbelial/articles/2116074.html     揹包九講      https://www.cnblogs.com/-guz/p/9866118.html   感謝HMR姐姐的部

揹包-致謝

        感謝一下名單: 阿坦 jason911 donglixp LeafDuo 他們每人都最先指出了本文曾經存在的某個並非無關緊要的錯誤。謝謝你們如此仔細地閱讀拙作並彌補我的疏漏。    

揹包-聯絡方式

        如果有任何意見和建議,特別是文章的錯誤和不足,或者希望為文章新增新的材料,可以通過http://kontactr.com/user/tianyi/這個網頁聯絡我。         

揹包-附錄(二) 揹包問題的搜尋解法

        《揹包問題九講》的本意是將揹包問題作為動態規劃問題中的一類進行講解。但鑑於的確有一些揹包問題只能用搜索來解,所以這裡也對用搜索解揹包問題做簡單介紹。大部分以01揹包為例,其它的應該可以觸類旁通。 簡單的深搜   &n

揹包-附錄(一) USACO中的揹包問題

        USACO是USA Computing Olympiad的簡稱,它組織了很多面向全球的計算機競賽活動。         USACO Trainng是一個很適合初學者的題庫,我認為它

C語言和cuda C實現程式碼(教科書上的格式)

一般教科書都這麼寫,感覺不如STL的好。記下以便查閱。 #include <cuda_runtime.h> #include <iostream> #include <stdio.h> __global__ void vector_add_gpu_2(fl

第三講 多重揹包問題(對揹包的學習)

題目 有N種物品和一個容量為V的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。 基本思路: 對每個物品都考慮拿幾個(這個很好理解) 遞推式:f[i][v]=max{f[i-1][v-k*c[i]]+

【轉載】揹包

P01: 01揹包問題 題目 有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。 基本思路 這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。 

揹包(六) 分組的揹包問題

問題         有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。這些物品被劃分為若干組,每組中的物品互相沖突,最多選一件。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。 演算法         這個問題變成

揹包揹包問題問法的變化

        以上涉及的各種揹包問題都是要求在揹包容量(費用)的限制下求可以取到的最大價值,但揹包問題還有很多種靈活的問法,在這裡值得提一下。但是我認為,只要深入理解了求揹包問題最大價值的方法,即使問法變化了,也是不難想出演算法的。          例如,求解最多可以放

dd大牛的揹包-揹包問題彙總

揹包九講 目錄  第一講 01揹包問題  第二講 完全揹包問題  第三講 多重揹包問題  第四講 混合三種揹包問題  第五講 二維費用的揹包問題  第六講 分組的揹包問題  第七講 有依賴的揹包問題  第八講 泛化物品  第九講 揹包問題問法的變化  附:USACO中的

揹包

0-1揹包問題 有n個重量和價值分別為 wi,viwi,vi 的物品。從這些物品中挑選出總重量不超過 WW 的物品, 求所有挑選方案中價值總和的最大值。 樣例: n=4 (w,v)=(2,3),(1,2),(3,4),(2,2) W=5n=4 (w,v)=(2,3

C#實現完整的防盜自制監控系統

因此 進制 oid 目錄 打電話 相關信息 reader 異步 了解 在您的手機中通知您家中的入侵者,並拍攝他們的照片 介紹 在本文中,我將展示一些DIY東西??,用於安裝監控系統,檢測家中的入侵者,拍攝照片並通過手機通知您,必要時可以打電話給警察並提供照片以便快速識別劫匪

AVL樹的實現(完整程式碼)

AVL樹的實現 1.類的架構 public class AvlTree<T extends Comparable<? super T>> { private static class AvlNode<T> { 待實現 } // AVL樹的節點類

揹包【ORZ式教學】

揹包問題 P01: 01揹包問題 1.1 問題 有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使價值總和最大。 1.2 基本思路 在不超過揹包容量的情況下,最多能獲得多少價值 子