1. 程式人生 > >【洛谷習題】瘋狂的采藥

【洛谷習題】瘋狂的采藥

clu clas www href can 直接 play inline ++i

嗯,改編自那道經典的01背包問題——采藥。

題目鏈接:https://www.luogu.org/problemnew/show/P1616


與之間的采藥不同,這裏每種草藥有無限多個,通常把這類問題稱為完全背包問題。

每種草藥並不唯一,會有若幹個被放入背包,雖然看起來比01背包復雜很多,但實際上,他很容易轉化為01背包問題。具體方法此處不再贅述,直接放一種簡單有效的做法。在01背包代碼中,優化空間復雜度後,我們是從T枚舉到t[i],之所以要這樣做,是為了保證,dp[j]裏存放的是考慮i-1株草藥時的最大價值。假如我們從t[i]枚舉到T,會怎樣呢?就會導致,dp[j]裏存放的是考慮過無數株的第i株草藥後的最大價值,剛好符合完全背包的要求。

技術分享圖片
 1 #include<cstdio>
 2 inline int max(int a,int b) {
 3     return a>b?a:b;
 4 }
 5 const int maxt=1e5+5,maxm=1e4+5;
 6 int T,m,t[maxm],v[maxm],dp[maxt];
 7 int main() {
 8     scanf("%d%d",&T,&m);
 9     for(int i=1;i<=m;++i) scanf("%d%d",&t[i],&v[i]);
10     for
(int i=1;i<=m;++i) 11 for(int j=t[i];j<=T;++j) 12 dp[j]=max(dp[j],dp[j-t[i]]+v[i]); 13 printf("%d",dp[T]); 14 return 0; 15 }
AC代碼

【洛谷習題】瘋狂的采藥