原題鏈結
這是一道非常基礎的01揹包問題,揹包容量就是時間,物品價值就是草藥價值。
我們先來看二維的揹包。狀態很容易寫出來,dp[i][j]就是前i種草藥j時間內所能採到的最大價值。動態轉移方程也就很容易寫出,dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]],v[i]儲存的是第i種草藥的時間。第二種情況需要j>=v[i]。**如下(時間和體積陣列直接用對組儲存):
#include
#include
#include
#include
using
namespace std;
typedef pair<
int,
int> pii;
int t, m;
int dp[
110]
[1010];
pii h[
110]
;int
main()
} cout << dp[m]
[t];
return0;
}
當然,可以將其優化成一維陣列。這裡不同的是,第二層迴圈是從大到小。這裡我給出兩種不同的理解方式。我們先看二維的狀態轉移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]。如果將其改為一維,就是dp[j]=max(dp[j],dp[j-v[i]])。如果第二層迴圈是從小到大,dp[j-v[i]]用到的是第i層更新的結果,但是二維的時候所用到的是第i-1層的。
第二種理解方式是如果從大到小,一種草藥就可能被採摘多次。這就變成了完全揹包。
#include
#include
#include
#include
using
namespace std;
typedef pair<
int,
int> pii;
int t, m;
int dp[
1010];
pii h[
110]
;int
main()
} cout << dp[t]
;return0;
}
附搜尋**和記憶化搜尋**
搜尋**:
#include
#include
#include
#include
using
namespace std;
typedef pair<
int,
int> pii;
int ans;
pii h[
110]
;int t, m;
void
dfs(
int level,
int timeleft,
int val)
if(timeleft >= h[level]
.first)
dfs(level +
1, timeleft - h[level]
.first, val + h[level]
.second)
;dfs
(level +
1, timeleft, val);}
intmain()
記憶化搜尋:
#include
#include
#include
#include
using
namespace std;
typedef pair<
int,
int> pii;
int ans;
pii h[
110]
;int t, m;
int mem[
110]
[1010];
intdfs
(int level,
int timeleft)
int dfs1 =-1
, dfs2;
if(timeleft >= h[level]
.first)
dfs1 =
dfs(level +
1, timeleft - h[level]
.first)
+ h[level]
.second;
dfs2 =
dfs(level +
1, timeleft)
;return mem[level]
[timeleft]
=max
(dfs1, dfs2);}
intmain()
洛谷 P1048 採藥
題目描述 辰辰是個天資聰穎的孩子,他的夢想是成為世界上最偉大的醫師。為此,他想拜附近最有威望的醫師為師。醫師為了判斷他的資質,給他出了乙個難題。醫師把他帶到乙個到處都是草藥的山洞裡對他說 孩子,這個山洞裡有一些不同的草藥,採每一株都需要一些時間,每一株也有它自身的價值。我會給你一段時間,在這段時間裡...
洛谷 P1048 採藥
題目描述 辰辰是個天資聰穎的孩子,他的夢想是成為世界上最偉大的醫師。為此,他想拜附近最有威望的醫師為師。醫師為了判斷他的資質,給他出了乙個難題。醫師把他帶到乙個到處都是草藥的山洞裡對他說 孩子,這個山洞裡有一些不同的草藥,採每一株都需要一些時間,每一株也有它自身的價值。我會給你一段時間,在這段時間裡...
洛谷p1048採藥
辰辰是個天資聰穎的孩子,他的夢想是成為世界上最偉大的醫師。為此,他想拜附近最有威望的醫師為師。醫師為了判斷他的資質,給他出了乙個難題。醫師把他帶到乙個到處都是草藥的山洞裡對他說 孩子,這個山洞裡有一些不同的草藥,採每一株都需要一些時間,每一株也有它自身的價值。我會給你一段時間,在這段時間裡,你可以採...