0-1揹包問題,用滾動陣列,動態規劃解決
接觸了很多的0-1揹包的問題,這個問題是動態規劃的經典題,總結一下,加深自己的印象,也
為大家做個參考,對blog有問題可以直接評論,我會盡快的回答!
題目:有N件物品和一個容量為V的揹包,第i件物品的體積w[i],價值是c[i],求解將那些物品裝入揹包
可使這些物品的費用總和不超過揹包容量,且使揹包內的物品價值總和最大!
F[i][w]----對於前i物品而言,使體積為w的揹包內物品價值總和最大,最大的價值為F[i][w].
下面這個方程為整個揹包問題的核心:
F[i][w]=max{ F[i-1][w] , F[i-1][w-w[i]]+c[i] }
對於第i件物品,你可以選擇把它裝入揹包,還可以選擇前i-1件物品對於體積為w的揹包的最優解,
選擇其中的最大值,就是F[i][w]的值了!
話不多說,直接上程式碼,更加清楚得了解!
程式碼1:
這個程式碼是,對於二維陣列而言,一旦物品數和重量多了起來,程式的複雜度就很大,所以#include<iostream> using namespace std; int F[100][100]; //定義一個二維陣列 int w[100]; //體積陣列 int c[100]; //價值陣列 int n; //物品總數 int V; //揹包的體積 int max(int a,int b); int main() { while(cin>>n&&cin>>V) { int i,j; for(i=1;i<=n;i++)//初始化資料 cin>>w[i]>>c[i]; for(i=1;i<=n;i++) for(j=1;j<=V;j++) if(j>w[i]) F[i][j]=max(F[i-1][j],F[i-1][j-w[i]]+c[i]); else F[i][j]=F[i-1][j]; cout<<F[n][V]; } } int max(int x,int y) { return x>y?x:y; }
必須減少時間複雜度,可以從優化空間的角度來看這個問題!
可以用一個滾動陣列來代替二維陣列,讓陣列動起來,
如果你認真看了程式碼1,程式碼2就比較簡單的理解!
程式碼2:
#include<iostream> using namespace std; int F[100]; //定義一個一維陣列 int w[100]; //體積陣列 int c[100]; //價值陣列 int n; //物品總數 int V; //揹包的體積 int max(int a,int b); int main() { while(cin>>n&&cin>>V) { int i,j; for(i=1;i<=n;i++)//初始化資料 cin>>w[i]>>c[i]; for(i=1;i<=n;i++) for(j=V;j>=w[i];j--)//從V開始,這是個技巧,我在這就走了很多彎路,有興趣的同學可以思考 一下 F[j]=max(F[j],F[j-w[i]]+c[i]); cout<<F[V]; } } int max(int x,int y) { return x>y?x:y; }
另外我想說的是,大家可以換個角度思考問題,可以從物品的價值著手!而不是從物品的重量,在某些
特定的條件下,這個是很好用的!
F[i][c]------對於前i物品而言,使揹包裝上c價值的物品,所需的最小體積!
核心方程:
F[i][c] = min { F[i-1][c] , F[i-1][c-c[i]] + w[i] }
對於第i件物品,你可以選擇把它裝入揹包,還可以選擇前i-1件物品對於裝入價值為c的
揹包的最小體積的最優解,
問題得到了解決!
程式碼3:
#include<iostream>
using namespace std;
int w[100];//體積
int v[100];//價值
int F[100];//一維陣列
int Getdata(long int n);//輸入資料
int newdata();//初始化陣列
int min(int a,int b);
int main()
{
int n;
int W;
while(cin>>n&&cin>>W)
{
Getdata(n);
newdata();
int i,j;
int max=0;
int vm=0;//暫存價值的大小
for(i=1;i<=n;i++)//為了時間複雜度的考慮我用了滾動陣列
{
vm=vm+v[i];
for(j=vm;j>=1;j--)
if(j>v[i])
F[j]=min(F[j],F[j-v[i]]+w[i]);
else F[j]=min(F[j],w[i]);
}
for(i=1;i<=vm;i++)//找出體積為V的C最大的那個元素
{
if((F[i]<=W)&&(i>max))
max=i;
}
cout<<max<<endl;
}
return 1;
}
int Getdata( int n)
{
int i;
for(i=1;i<=n;i++)
cin>>w[i]>>v[i];
return 1;
}
int newdata()//把陣列初始化為最大值
{
int i;
for(i=0;i<100;i++)
F[i]=10000;
return 1;
}
int min(int a,int b)
{
if(a>b) return b;
else return a;
}
大家有興趣的話可以做一下這道題:0-1揹包實戰題
如果大家有問題,可以私聊我,我一定會回答的!共同學習,進步,哈哈!相關推薦
0-1揹包問題,用滾動陣列,動態規劃解決
接觸了很多的0-1揹包的問題,這個問題是動態規劃的經典題,總結一下,加深自己的印象,也 為大家做個參考,對blog有問題可以直接評論,我會盡快的回答! 題目:有N件物品和一個容量為V的揹包,第i件物品的體積w[i],價值是c[i],求解將那些物品裝入揹包 可使這些物品的費
0-1揹包:使用滾動陣列時為何要逆序列舉
問題簡述:有一揹包,最大體積是10,有三個物品,體積分別是3,4,5,重量分別是4,5,6,求在不超過揹包體積的前提下,所放物品的最大重量是多少。 答:最大重量是11,選擇的物品是2和3,其體積是9,小於揹包體積10 我們已經知道,對於0-1揹包問題,我們可以使用動態規劃
0-1揹包問題簡單實現程式碼(動態規劃)
import java.util.Scanner; /** * @ClassName Backpack * @Description 0-1揹包問題 * @Author lzq * @Date 2018/12/6 17:51 * @Version 1.0 **/ class
【HDU - 2546】飯卡 (dp,0-1揹包,貪心思想)
電子科大本部食堂的飯卡有一種很詭異的設計,即在購買之前判斷餘額。如果購買一個商品之前,卡上的剩餘金額大於或等於5元,就一定可以購買成功(即使購買後卡上餘額為負),否則無法購買(即使金額足夠)。所以大家都希望儘量使卡上的餘額最少。 某天,食堂中有n種菜出售,每種菜可購買一次。已知每種菜
動態規劃之0-1揹包問題,鋼條切割
動態規劃 首先說說動態規劃:動態規劃與分治法相似,都是組合子問題的解來解決原問題的解,與分治法的不同在於:分治法的子問題是相互獨立存在的,而動態規劃應用於子問題重疊的情況。 設計動態規劃演算法的步驟: 1、刻畫一個最優解的結構特徵 2、遞迴地定義最優解的
0/1揹包問題(遞迴解決,遞推解決)
0-1揹包問題: 有N件物品和一個容量為V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。 這個問題的特點是:每種物品只有一件,可以選擇放或者不放。 輸入格式:V,NW1,V1W2,V2.
51Nod1085 0-1揹包(一維和二維陣列實現)
揹包是典型的動態規劃問題,關於揹包問題的詳解,推薦部落格:點選開啟連結(這篇部落格有點錯誤,程式碼for迴圈裡錯了,不過講解 的很詳細) 題目如下: 在N件物品取出若干件放在容量為W的揹包裡,每件物品的體積為W1,W2……Wn(Wi為整數),與之相對應的價值為P1,P2……Pn(Pi為整數)
0-1揹包與完全揹包 SDNUOJ1033採藥(一維陣列)1043採藥2(一維陣列)
1033(一維陣列)(揹包容量 j 逆序列舉)0-1揹包 #include<iostream> #include<cstring> #include<cmath> using namespace std; #define N 1005 int v[N]
OpenCV 4.0.1 和 3.4.5 釋出,Intel 開源的計算機視覺庫
OpenCV 4.0.1 和 3.4.5 已釋出,OpenCV 是 Intel 開源的計算機視覺庫。它由一系列 C 函式和少量 C++ 類構成,實現了影象處理和計算機視覺方面的很多通用演算法。OpenCV 擁有包括 300 多個 C 函式的跨平臺的中、高層 API。 這兩
java 泛型詳解(普通泛型、 萬用字元、 泛型介面,泛型陣列,泛型方法,泛型巢狀)
JDK1.5 令我們期待很久,可是當他釋出的時候卻更換版本號為5.0。這說明Java已經有大幅度的變化。本文將講解JDK5.0支援的新功能-----Java的泛型. 1、Java泛型 其實Java
用模擬退火演算法解決0-1揹包問題
clear clc a = 0.95 k = [5;10;13;4;3;11;13;10;8;16;7;4]; k = -k; % 模擬退火演算法是求解最小值,故取負數 d = [2;5;18;3;2;5;10;4;11;7;14;6]; restriction = 46;
通過埠1433連線到主機127.0.0.1的 TCP/IP 連線失敗,錯誤:“connect timed out”的解決方法
解決方案: 1. 開啟SQLServer 配置管理器------->SQLServer for MSQLSERVER------->TCP/IP------->如果沒有啟動,則啟動------->右鍵屬性------->IPAddres
osx升級到10.10後,用pod install報錯終於解決的方法
... tar font tails http fat error: hat space 先依照這個文章做:http://blog.csdn.net/dqjyong/article/details/37958067 大概過程例如以下: Open Xcode 6O
Django-views,用戶認證,login_requierd()
strong ron 驗證碼錯誤 alt view sta cnblogs img close 分別是認證,登入,註銷的功能 authenticated():驗證是否登錄 user = authenticate(username=‘someone‘,password
UX術語幸運飛艇源碼下載詳解:任務流,用戶流,流程圖以及其它全新術語
希望 演示 重要 職位 flow 重新 生成 img 所有 用戶幸運飛艇源碼下載【大神源碼論壇】dsluntan.com 【布丁源碼論壇】budingbbs.com 企娥3393756370 體驗擁有一長串專業的術語和可交付內容。當在線查看UX相關職位描述時,所羅列的這類
洛谷P2900 [USACO08MAR]土地征用Land Acquisition(動態規劃,斜率優化,決策單調性,線性規劃,單調隊列)
tps include 寫法 lan clas com mat 成了 dong 用兩種不一樣的思路立體地理解斜率優化,你值得擁有。 題意分析 既然所有的土地都要買,那麽我們可以考慮到,如果一塊土地的寬和高(其實是蒟蒻把長方形立在了平面上)都比另一塊要小,那麽肯定是直接並購,
陣列-BAT面試經典試題:絕對眾數,零子陣列,最大子陣列和
1.絕對眾數問題 定義:給定N個數,稱出現次數最多的數為眾數:若某眾數出現的次數大於N/2,稱該眾數為絕對眾數。 如:A={1,2,1,3,2}中,1和2都是眾數,但都不是絕對眾數;A={1,2,1,3,1}中,1是絕對眾數。 已知給定的N個整數存在絕對眾數,以最低的時空負責度計算該
逆序對的三種求法(歸併排序,樹狀陣列,線段樹)
求逆序對個數的三種方法 逆序對: 對於一個序列 $a_1$,$a_2$,$a_3$..$a_n$,如果存在$a_i$>$a_j$且i<j,則$a_i$和$a_j$為一個逆序對。 這裡將介紹3種求逆序對對數的方法。 在此之前,預設為你已經會了歸併排序,樹狀陣列和線段樹。(不會的可以百度學習一下)
0-1揹包回溯
限定條件: 如果放入該物品<剩餘揹包容量則回溯。 如果當前價值+剩餘容量下剩餘物品的最大價值<當前最大價值則回溯。(剩下在怎麼放都不會比當前最大價值大,就沒必要算了) 測試: 第一行分別輸入物品數量n與揹包容量c 用例: 10 30095 8975 5923 1973 4350 100
彈層蒙版(mask),ios滾動穿透,我們專案的解決方案
問題描述 專案開發遇到一個ios獨有的問題,在wkwebview中穩定復現 問題: 彈出一個蒙版,當在蒙版上面滑動的時候蒙版後面的內容滾動了 這當然是ios的bug,但是經過我們測試iphone7也會復現這個問題,所以沒辦法需要相容。 百度了下好多思路 方法1: 直接禁用滾動容器的overflow,