百練2755 神奇的口袋(動態規劃)

2021-08-22 16:30:08 字數 1213 閱讀 5216

描述

有乙個神奇的口袋,總的容積是40,用這個口袋可以變出一些物品,這些物品的總體積必須是40。john現在有n個想要得到的物品,每個物品的體積分別是a1,a2……an。john可以從這些物品中選擇一些,如果選出的物體的總體積是40,那麼利用這個神奇的口袋,john就可以得到這些物品。現在的問題是,john有多少種不同的選擇物品的方式。

輸入輸入的第一行是正整數n (1 <= n <= 20),表示不同的物品的數目。接下來的n行,每行有乙個1到40之間的正整數,分別給出a1,a2……an的值。

輸出輸出不同的選擇物品的方式的數目。

樣例輸入

3

2020

20

樣例輸出

3
每個物品只有兩種可能,選擇和未選擇。

way(w,n)是指在n個物品裡選中重量為w的物品的方式數

先走一步,假設有k個物品,其各個的體積為a[i],i=1,2....k

1)最後乙個物品被選擇,那就轉化成求前k-1個物品裡選w-a[k]重量的物品的方式數,即way(w,k)=way(w-a[k],k-1)

2)最後乙個物品未被選擇,就轉化成在前k-1個物品中找w重量的物品的方式數,即way(w,k)=way(w,k-1)

總方式就是改兩種情況之和。。

1.遞迴:

#include#include#include#includeusing namespace std;

int n;

int a[25];

int way(int w,int n)

int main()

printf("%d\n",way(40,n));

}

2)遞推

由上遞迴式可知,求way[w][k],先求way[w][k-1],加way[w-a[k]][k-1]

#include#include#include#includeusing namespace std;

int main()

way[0][0]=1;

for(int w=1;w<=40;w++)}}

printf("%d\n",way[40][n]);

}

注意way[w][k]=way[w][k-1];的位置,需要先求的在不選擇k物品的情況下的方式數,若k物品可以選,再加上選擇了k物品後有幾種選擇方式。

百練 2755 神奇的口袋

描述 有乙個神奇的口袋,總的容積是40,用這個口袋可以變出一些物品,這些物品的總體積必須是40。john現在有n個想要得到的物品,每個物品的體積分別是a 1,a2 a n。john可以從這些物品中選擇一些,如果選出的物體的總體積是40,那麼利用這個神奇的口袋,john就可以得到這些物品。現在的問題是...

百練 2755 神奇的口袋

遞迴 include include include includeusing namespace std const int maxn 30 int n,d maxn int dp int w,int n int main 人人為我動歸 狀態定義 揹包容量為i時,選完前j件物品後,能達到該容量的最...

百練 2755 神奇的口袋

第一種解法是很經典的動態規劃,對於值域較小的題目,還可以採用第二種方法,考慮對值域空間 即對容積的可達性進行動態規劃。這道題裡面採用第二種解法還會有空間上的優化。有時把值域作為一種狀態不單單是一種解法,還有可能是唯一的解法。如hdu 1574 rp問題 描述有乙個神奇的口袋,總的容積是40,用這個口...