【練習】砝碼稱重
阿新 • • 發佈:2018-11-01
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 }