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 }
原文地址:https://www.cnblogs.com/Hwjia/p/9887212.html
时间: 2024-11-09 16:38:30