2044 Problem C 神奇的口袋
阿新 • • 發佈:2018-12-12
問題 C: 神奇的口袋
時間限制: 1 Sec 記憶體限制: 32 MB 提交: 427 解決: 196 [提交][狀態][討論版][命題人:外部匯入]
題目描述
有一個神奇的口袋,總的容積是40,用這個口袋可以變出一些物品,這些物品的總體積必須是40。John現在有n個想要得到的物品,每個物品的體積分別是a1,a2……an。John可以從這些物品中選擇一些,如果選出的物體的總體積是40,那麼利用這個神奇的口袋,John就可以得到這些物品。現在的問題是,John有多少種不同的選擇物品的方式。
輸入
輸入的第一行是正整數n (1 <= n <= 20),表示不同的物品的數目。接下來的n行,每行有一個1到40之間的正整數,分別給出a1,a2……an的值。
輸出
輸出不同的選擇物品的方式的數目。
樣例輸入
2
12
28
3
21
10
5
樣例輸出
1
0
#include<iostream> using namespace std; int a[30], n; int sele(int w, int x) { if (w == 0) return 1; if (x <= 0) return 0; return sele(w - a[x], x - 1) + sele(w, x - 1); } int main() { while (cin >> n) { for (int i = 1; i <= n; i++) { cin >> a[i]; } cout << sele(40, n) << endl; } return 0; } /*最初寫的遞迴 #include<iostream> using namespace std; int a[25], n, num = 0; void sele(int sum, int x) { sum += a[x]; if (sum == 40)num++; else if (sum < 40) { for (int i = x + 1; i < n; i++) { sele(sum, i); } } } int main() { while (cin >> n) { for (int i = 0; i < n; i++) { cin >> a[i]; } num = 0; for (int i = 0; i < n; i++) { sele(0, i); } cout << num << endl; } return 0; } dfs深搜: #include<iostream> using namespace std; int ans,dep; int a[1005]; void dfs(int i,int sum) { if(sum==40) { ans++; return; } if(sum>40||i>dep) return ; dfs(i+1,sum+a[i]); dfs(i+1,sum); } int main() { int j,k,l,m,n; while(cin>>dep) { for(j=1;j<=dep;j++) cin>>a[j]; ans=0; dfs(1,0); cout<<ans<<endl; } } dp動規: #include <iostream> #include <cstdio> #include "stdlib.h" using namespace std; int main() { int n; int buf[21]; int dp[21][41]; while(cin>>n) { for(int i=1;i<=n;i++) cin>>buf[i]; for(int i=0;i<=n;++i) for(int j=0;j<=40;j++) dp[i][j]=0; for(int i=1;i<=n;++i)//注意初始條件,對應沒有的情況 dp[i][0]=1; dp[1][buf[1]]=1; for(int i=2;i<=n;i++) for(int j=1;j<=40;j++) { if(j>=buf[i]) dp[i][j]=dp[i-1][j]+dp[i-1][j-buf[i]]; else dp[i][j]=dp[i-1][j]; } cout<<dp[n][40]<<endl; } } */