1. 程式人生 > >遞迴解決揹包問題

遞迴解決揹包問題

  • 問題描述:有不同價值、不同重量的物品n件,求從這n件物品中選取一部分物品的方案,使得選中物品的總重量不超過指定的限制重量,但選中的物品總價值最大。
  • 揭解法描述:採用遞迴尋找物品的尋找方案。設前面已有多種選擇方案,並保留其中總價值最大的方案與一個數組option[]中,該方案的總價值存於變數maxval中,當前正在考慮新方案,其物品選擇情況存於陣列cop[]中。假設當前方案已經考慮了前i-1件物品,現在要考慮第i件物品;當前方案已包含的物品中良之和為tw;至此,若其餘物品都選擇是可能的話,本方案能到達的中間值得期望為tv。演算法引入tv是當一旦當前方案的總價值的期望也小於前面方案的總價值maxval時,繼續考察當前方案變成無意義的工作,應終止當前方案,立即去考察下一方案。因為當前方案的總價值不比maxval大時,該方案不會再被考慮,這同時保證函式後找到的方案一定會比前面的方案好。對於第i件物品的選擇考慮有兩種情況:(1):考慮物品 i 被選擇,這種可能性僅當包含他不會超過總重量限制時才是可行的。選中後,繼續遞迴去考查其餘物品的選擇。(2):考慮物品 i 不被選擇,這種可能性僅當不包含物品 i 也有可能找到價值更大的方案的情況。

程式碼

#include<iostream>
using namespace std;
struct bag
{
	int weight;  //包的重量
	int value;   //包的價值
}arr[100];

int option[100];  //用於儲存滿足的最大值方案
int cop[100];     //用於標識每個包是否被選取
int maxv, limitw, totv;
int n;
void find(int i, int tw, tv)
{
	int k;
	if(tw + arr[i].weight <= limitw)    //該包被選取
	{
		cop[i] = 1;              //設立標記    
		if(i < n - 1)
		{
			find(i + 1, tw + arr[i].weight, tv);   //遞迴判斷下一個包
		}
		else
		{
			for(k = 0; k < n; k++)
			{
				option[k] = cop[k];   //儲存包被選取的資訊
			}
			maxv = tv;                   //獲取最大價值
		}
		cop[i] = 0;  //還原cop陣列
	}
	if(tv - arr[i].value > maxv)   //該包沒有被選取,判斷該方案的價值是否最大。如果不是,繼續尋找下一個包
	{
		if(i < n - 1)
		{
			find(i + 1, tw, tv - arr[i].value);
		}
		else
		{
			for(k = 0; k < n; k++)
			{
				option[k] = cop[k];              //儲存包被選取的資訊
			}
			maxv = tv - arr[i].value;                //獲取最大價值
		}
	}
}
int main()
{
	int k, w, v;
	cout << "please input count:";
	cin >> n;
	totv = 0;
	for( k = 0; k < n; k++)
	{
		cout << "please input the weight and val" << endl;
		cin >> arr[k].weight;
		cin>> arr[k].value;
	}
	cout << "please input limitw:";
	cin >> limitw;
	maxv = 0;
	for(k = 0; k < n; k++)
	{
		cop[k] = 0;
	}
	find(0, 0, totv);
	cout << "the result is:";
	for(k = 0; k < n; k++)
	{
		if(option[k])
		{
			cout << k + 1 << " ";
		}
	}
	cout << endl;
	cout << "the total value is:" << maxv << endl;
	return 0;
}

相關推薦

解決揹包問題

問題描述:有不同價值、不同重量的物品n件,求從這n件物品中選取一部分物品的方案,使得選中物品的總重量不超過指定的限制重量,但選中的物品總價值最大。 揭解法描述:採用遞迴尋找物品的尋找方案。設前面已有多種選擇方案,並保留其中總價值最大的方案與一個數組option

0/1揹包問題(解決解決

0-1揹包問題:  有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。  這個問題的特點是:每種物品只有一件,可以選擇放或者不放。 輸入格式:V,NW1,V1W2,V2.

解決全排列生成演算法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

經典解決漢諾塔!

演算法:當只有一個盤子的時候,只需要從將A塔上的一個盤子移到C塔上。             當A塔上有兩個盤子是,先將A塔上的1號盤子(編號從上到下)移動到B塔上,再將A塔上的2號

-- 簡單揹包問題

Description 設有一個揹包可以放入的物品重量為S,現有n件物品,重量分別是w1,w2,w3,…wn。 問能否從這n件物品中選擇若干件放入揹包中,使得放入的重量之和正好為S。 如果有滿足條件的選擇,則此揹包有解,否則此揹包問題無解。 knap( s, n)

解決求最大公約數問題

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body>

漢諾(Hanoi)塔問題的解決

漢諾塔問題: 古代有一個塔,塔內有3個座A、B、C,開始時A座有64個盤子,盤子大小不相等,大的在下,小的在上。有一個老和尚想把這64個盤子從A座移動到C座,但每次只允許移動一個盤,且在移動過程中在3個座上都始終保持大盤在下,小盤在上。在移動過程中可以利用B座,

Java解決n皇后問題

題目 八皇后問題是一個以國際象棋為背景的問題:如何能夠在 8×8 的國際象棋棋盤上放置八個皇后,使得任何一個皇后都無法直接吃掉其他的皇后?這道題目也可以稍微延伸一下,變為 N×N的棋盤上放置N個皇后,其他條件相同。 下面介紹一種比較簡單易懂的實現方式。 程式碼 impo

DFS揹包問題求最優解

揹包問題大家都知道,已知揹包的最大儲存量是V,給定n個物品,求取怎樣盛放才能是揹包價值最大。 #include<iostream> #include<algorithm> using namespace std; const int maxn=30; int n,

解決分魚問題

A、B、C、D、E這5個人合夥夜間捕魚,凌晨時都已經疲憊不堪,於是各自在河邊的樹叢中找地方睡著了。第二天日上三竿時,A第一個醒來,他將魚平分為5份,把多餘的一條扔回河中,然後拿著自己的一份回家去了;B第二個醒來,但不知道A已經拿走了一份魚,於是他將剩下的魚平分為5份,扔掉多餘的一條,然後只拿走了自己

使用JavaScript實現解決斐波那契數列及優化

遞迴的概念:若一個演算法直接地或間接地呼叫自己本身,則稱這個演算法是遞迴演算法(《資料結構—使用C語言實現;朱戰立;西安交大出版社》); 遞迴的兩個條件:自己呼叫自己和有結束條件(否則是死遞迴) 斐波那契數列 1, 1, 2,3,5,8,13,21….. 使

LeetCode 206. 反轉連結串列 解決

反轉一個單鏈表。 示例: 輸入: 1->2->3->4->5->NULL 輸出: 5->4->3->2->1->NULL 進階: 你可以迭代或遞迴地反轉連結串列。你能否用兩種方法解決這道題? 注意head是有

C語言解決fibonacci數列演算法

斐波那契數列的遞迴條件是 F(n)=1   n=0, F(n)=1   n=1, F(n)=F(n-1)+F(n-2)   n>1; 可以直接寫出遞迴函式 int f(int n) { if(n<=1) retu

C語言解決階乘問題

遞迴函式的概念是:直接或者間接地呼叫自身的演算法 遞迴函式:用函式自身給出定義的函式 而且在學習的後期  學到了分治法可以感覺到分治法產生的子問題是原問題的較小模式,這就為使用遞迴技術提供了不小的方便 即在合適的情況,使用遞迴反覆分治,大問題變相同性質的小問題,再進行遞迴求解 今天

解決漢諾塔

漢諾塔簡介 大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。 經典題目:

演算法(1)整數劃分問題之解決

  今日,閱讀《ACM/ICPC 演算法訓練》時,發現一道名為“整數劃分”的題,書上解釋極為模糊,自己研究了一下此題,將其解決,記錄下解題思路,以備以後有用時快速理解;   一,題意簡述   將整數表示成一系列正整數之和:n=n1+n2+.....+nk;   注意:4+2

解決 Tower of Hanoi 問題

     自己感覺寫的沒有原博主的那麼容易理解,於是就站在巨人的肩膀上摘蘋果,感謝部落格主。 演算法:當只有一個盤子的時候,只需要從將A塔上的一個盤子移到C塔上。             當A塔上有兩個盤子是,先將A塔上的1號盤子(編號從上到下)移動到B塔上,再將A塔上

解決全排列問題+詳細圖解執行

問題描述:字串的排列 //輸入一個字串, 按字典序打印出該字串中字元的所有排列。 //例如輸入字串abc, 則打印出由字元a, b, c所能排列出來的所有字串abc, acb, bac, bca, cab和cba。 //結果請按字母順序輸出。 //長度不超過9(可能有字

python資料結構學習筆記-2017-01-08-01-N皇后問題、迷宮問題和跳馬問題的解決

        N皇后問題         棋盤ADT #-*-coding: utf-8-*- # 二維陣列實現棋盤ADT from myarray2d import Array2D class Board(object): def __init__(se

java利用解決八皇后問題

問題簡介: 要求在一個8*8的棋盤上放置8個皇后,使任意兩個皇后都不同行不同列且不在同一條斜對角線上。採用遞迴和回溯的思想解決這一問題是較為直觀的。一開始,棋盤上的任意格子都可落子,因此可任意選擇第一個皇后的位置。放置了第一個皇后之後,棋盤上的可落子格子的分佈將發生改變,然