通過金礦模型介紹動態規劃
阿新 • • 發佈:2018-12-27
/*
=========程式資訊========
對應題目:01揹包之金礦模型
使用語言:c++
使用編譯器:Visual Studio 2005.NET
使用演算法:動態規劃
演算法執行時間:O(people * n) [people是人數,n是金礦數]
作者:貴州大學05級 劉永輝
暱稱:SDJL
編寫時間:2008年8月
聯絡QQ:44561907
E-Mail:[email protected]
獲得更多文章請訪問我的部落格:www.cnblogs.com/sdjl
如果發現BUG或有寫得不好的地方請發郵件告訴我:)
轉載請保留此部分資訊:)
*/
#include "stdafx.h"
#include <iostream>
#include <fstream>usingnamespace std;
constint max_n =100;//程式支援的最多金礦數constint max_people =10000;//程式支援的最多人數int n;//金礦數int peopleTotal;//可以用於挖金子的人數int peopleNeed[max_n];//每座金礦需要的人數int gold[max_n];//每座金礦能夠挖出來的金子數int maxGold[max_people][max_n];//maxGold[i][j]儲存了i個人挖前j個金礦能夠得到的最大金子數,等於-1時表示未知
//初始化資料 void init()
{
ifstream inputFile("beibao.in");
inputFile>>peopleTotal>>n;
for(int i=0; i<n; i++)
inputFile>>peopleNeed[i]>>gold[i];
inputFile.close();
for(int i=0; i<=peopleTotal; i++)
for(int j=0; j<n; j++ )
maxGold[i][j] =-1;//等於-1時表示未知 [對應動態規劃中的“做備忘錄”]
}
//獲得在僅有people個人和前mineNum個金礦時能夠得到的最大金子數,注意“前多少個”也是從0開始編號的int GetMaxGold(int people, int mineNum)
{
//申明返回的最大金子數int retMaxGold;
//如果這個問題曾經計算過 [對應動態規劃中的“做備忘錄”]if(maxGold[people][mineNum] !=-1)
{
//獲得儲存起來的值 retMaxGold = maxGold[people][mineNum];
}
elseif(mineNum ==0)//如果僅有一個金礦時 [對應動態規劃中的“邊界”] {
//當給出的人數足夠開採這座金礦if(people >= peopleNeed[mineNum])
{
//得到的最大值就是這座金礦的金子數 retMaxGold = gold[mineNum];
}
else//否則這唯一的一座金礦也不能開採 {
//得到的最大值為0個金子 retMaxGold =0;
}
}
elseif(people >= peopleNeed[mineNum])//如果給出的人夠開採這座金礦 [對應動態規劃中的“最優子結構”] {
//考慮開採與不開採兩種情況,取最大值 retMaxGold = max(GetMaxGold(people - peopleNeed[mineNum],mineNum -1) + gold[mineNum],
GetMaxGold(people,mineNum -1));
}
else//否則給出的人不夠開採這座金礦 [對應動態規劃中的“最優子結構”] {
//僅考慮不開採的情況 retMaxGold = GetMaxGold(people,mineNum -1);
}
//做備忘錄 maxGold[people][mineNum] = retMaxGold;
return retMaxGold;
}
int _tmain(int argc, _TCHAR* argv[])
{
//初始化資料 init();
//輸出給定peopleTotal個人和n個金礦能夠獲得的最大金子數,再次提醒編號從0開始,所以最後一個金礦編號為n-1 cout<<GetMaxGold(peopleTotal,n-1);
system("pause");
return0;
}
=========程式資訊========
對應題目:01揹包之金礦模型
使用語言:c++
使用編譯器:Visual Studio 2005.NET
使用演算法:動態規劃
演算法執行時間:O(people * n) [people是人數,n是金礦數]
作者:貴州大學05級 劉永輝
暱稱:SDJL
編寫時間:2008年8月
聯絡QQ:44561907
E-Mail:[email protected]
獲得更多文章請訪問我的部落格:www.cnblogs.com/sdjl
如果發現BUG或有寫得不好的地方請發郵件告訴我:)
轉載請保留此部分資訊:)
*/
#include
#include <iostream>
#include <fstream>usingnamespace std;
constint max_n =100;//程式支援的最多金礦數constint max_people =10000;//程式支援的最多人數int n;//金礦數int peopleTotal;//可以用於挖金子的人數int peopleNeed[max_n];//每座金礦需要的人數int gold[max_n];//每座金礦能夠挖出來的金子數int maxGold[max_people][max_n];//maxGold[i][j]儲存了i個人挖前j個金礦能夠得到的最大金子數,等於-1時表示未知
{
ifstream inputFile("beibao.in");
inputFile>>peopleTotal>>n;
for(int i=0; i<n; i++)
inputFile>>peopleNeed[i]>>gold[i];
inputFile.close();
for(int i=0; i<=peopleTotal; i++)
for(int j=0; j<n; j++
maxGold[i][j] =-1;//等於-1時表示未知 [對應動態規劃中的“做備忘錄”]
}
//獲得在僅有people個人和前mineNum個金礦時能夠得到的最大金子數,注意“前多少個”也是從0開始編號的int GetMaxGold(int people, int mineNum)
{
//申明返回的最大金子數int retMaxGold;
//如果這個問題曾經計算過 [對應動態規劃中的“做備忘錄”]if(maxGold[people][mineNum] !=-1)
{
//獲得儲存起來的值 retMaxGold = maxGold[people][mineNum];
}
elseif(mineNum ==0)//如果僅有一個金礦時 [對應動態規劃中的“邊界”] {
//當給出的人數足夠開採這座金礦if(people >= peopleNeed[mineNum])
{
//得到的最大值就是這座金礦的金子數 retMaxGold = gold[mineNum];
}
else//否則這唯一的一座金礦也不能開採 {
//得到的最大值為0個金子 retMaxGold =0;
}
}
elseif(people >= peopleNeed[mineNum])//如果給出的人夠開採這座金礦 [對應動態規劃中的“最優子結構”] {
//考慮開採與不開採兩種情況,取最大值 retMaxGold = max(GetMaxGold(people - peopleNeed[mineNum],mineNum -1) + gold[mineNum],
GetMaxGold(people,mineNum -1));
}
else//否則給出的人不夠開採這座金礦 [對應動態規劃中的“最優子結構”] {
//僅考慮不開採的情況 retMaxGold = GetMaxGold(people,mineNum -1);
}
//做備忘錄 maxGold[people][mineNum] = retMaxGold;
return retMaxGold;
}
int _tmain(int argc, _TCHAR* argv[])
{
//初始化資料 init();
//輸出給定peopleTotal個人和n個金礦能夠獲得的最大金子數,再次提醒編號從0開始,所以最後一個金礦編號為n-1 cout<<GetMaxGold(peopleTotal,n-1);
system("pause");
return0;
}