题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1233
题目就不说明了。
背包的二进制优化,比如10可以表示为1 2 4 3,而这些数能表示1 ~ 10的任意的数。然后类似01背包就好了。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <vector> 7 #include <ctime> 8 #include <queue> 9 #include <list> 10 #include <set> 11 #include <map> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 typedef long long LL; 15 const int N = 1e5 + 5; 16 int dp[N]; 17 int val[105], c[105]; 18 19 int main() 20 { 21 int t, n, m; 22 scanf("%d", &t); 23 for(int ca = 1; ca <= t; ++ca) { 24 scanf("%d %d", &n, &m); 25 for(int i = 1; i <= n; ++i) { 26 scanf("%d", val + i); 27 } 28 for(int i = 1; i <= n; ++i) { 29 scanf("%d", c + i); 30 } 31 memset(dp, 0, sizeof(dp)); 32 dp[0] = 1; 33 for(int i = 1; i <= n; ++i) { 34 for(int k = 1; k <= c[i]; k <<= 1) { 35 for(int j = m; j >= k*val[i]; --j) { 36 dp[j] |= dp[j - k*val[i]]; 37 } 38 c[i] -= k; 39 } 40 if(c[i]) { 41 for(int j = m; j >= c[i]*val[i]; --j) { 42 dp[j] |= dp[j - c[i]*val[i]]; 43 } 44 } 45 } 46 int ans = 0; 47 for(int i = 1; i <= m; ++i) { 48 ans += dp[i]; 49 } 50 printf("Case %d: %d\n", ca, ans); 51 } 52 return 0; 53 }
时间: 2024-10-03 13:45:01