1. 程式人生 > >【練習】砝碼稱重

【練習】砝碼稱重

 P1441 砝碼稱重

思路:dfs列舉去掉哪些砝碼, 01揹包求方案數, 各種情況取max記為ans輸出√

邊界情況處理不好交了三遍QAQ

dp[j] = dp[j] + dp[j - a[i]] 選上這個砝碼的情況+ 不選的情況

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 const int sz = 2020;
 6 int n, m, ans = 0, sum = 0;
 7 int dp[sz], a[sz];
8 bool book[sz]; 9 void work(int tot) { 10 memset(dp, 0, sizeof(dp)); 11 int cnt = 0; 12 dp[0] = 1; 13 for(int i = 1; i <= n; i++) { 14 if(book[i]) continue; 15 for(int j = tot; j >= 0; j--) { 16 if(j >= a[i]) dp[j] = dp[j] + dp[j - a[i]]; 17
} 18 } 19 for(int i = 1; i <= tot; i++) 20 if(dp[i]) cnt++; 21 ans = max(ans, cnt); 22 } 23 void dfs(int cur, int now) {//cur當前在第幾個砝碼前, now放棄了幾個砝碼 24 if(now > m) return; 25 if(cur == n+1) {//是n+1不是n 26 if(now == m) work(sum); 27 return
; 28 } 29 dfs(cur+1, now); 30 book[cur] = true;//放棄這個砝碼 31 sum -= a[cur]; 32 dfs(cur+1, now+1); 33 book[cur] = false; 34 sum += a[cur]; 35 } 36 int main() { 37 scanf("%d%d", &n, &m); 38 for(int i = 1; i <= n; i++) { 39 scanf("%d", &a[i]); 40 sum += a[i]; 41 } 42 dfs(1, 0); 43 printf("%d", ans); 44 return 0; 45 }