题目意思是有多种物品,每种物品的价值不确定,数量也不确定,很明显就是背包问题,…………
//深搜加剪枝
1 //深搜代码: 2 #include <iostream> 3 #include <cstdio> 4 using namespace std; 5 int v[55], m[55], h[53], N, B, res; 6 bool flag; 7 void dfs(int n, int sum){ 8 if(flag) return; 9 if(sum > res) res = sum; 10 if(res == B){ 11 flag = true; 12 return; 13 } 14 if(n == N) return; 15 //后缀数组优化,剪枝 16 if(sum + h[n] <= res) return; 17 else if(sum + h[n] <= B){ 18 res = sum + h[n]; 19 if(res == B) flag = true; 20 return ; 21 } 22 for(int i = 0; sum + v[n] * i <= B && i <= m[n]; ++i){ 23 dfs(n + 1, sum + v[n] * i); 24 } 25 } 26 27 int main() 28 { 29 int i, k, s; 30 while(scanf("%d", &N) != EOF){ 31 if(N <= 0) break; 32 s = 0; 33 for(i = 0; i < N; ++i){ 34 scanf("%d%d", &v[i], &m[i]); 35 h[i] = v[i] * m[i]; 36 s += h[i]; 37 } 38 for(k = N - 2; k >= 0; --k) h[k] += h[k+1]; 39 B = s / 2; res = 0; flag = false; 40 dfs(0, 0); 41 printf("%d %d ", s - res, res); 42 } 43 return 0; 44 }
//DP代码(一定的物品可以达到价值的标记为true,然后从中间值搜索)
1 //DP代码: 2 #include<stdio.h> 3 #include<string.h> 4 #define N 2500000 5 bool a[N], b[N]; 6 int main(){ 7 int n, sum, V[53], M[53]; 8 while(scanf("%d", &n) != EOF){ 9 if(n < 0) break; 10 sum = 0; 11 for(int i = 1; i <= n; ++i){ 12 scanf("%d%d", &V[i], &M[i]); 13 sum += V[i] * M[i]; 14 } 15 memset(a, false, sizeof(a)); 16 memset(b, false, sizeof(b)); 17 for(int i = 0; i <= V[1]*M[1]; i += V[1]) a[i] = true; 18 int value = V[1] * M[1]; 19 for(int i = 2; i <= n; ++i){ 20 for(int j = 0; j <= value; ++j) 21 for(int k = 0; k <= V[i] * M[i]; k += V[i]) 22 b[j + k] += a[j]; 23 value += V[i] * M[i]; 24 for(int j = 0; j <= value; ++j){ 25 a[j] = b[j]; b[j] = 0; 26 } 27 } 28 for(value = sum / 2; a[value] == 0; --value) ; 29 printf("%d %d ", sum - value, value); 30 } 31 return 0; 32 }