http://www.51nod.com/onlineJudge/questionCode.html#problemId=1007¬iceId=15020
求出n个数的和sum,然后用sum/2作为背包容量,让n个数去放,求出一个最大价值,那么这就是其中一组的和,另外一组的和就是sum-dp[sum/2];
注意这里的体积和价值都是a[i];
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <vector> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 #include <string> 9 #include <set> 10 #include <functional> 11 #include <numeric> 12 #include <sstream> 13 #include <stack> 14 #include <map> 15 #include <queue> 16 #pragma comment(linker, "/STACK:102400000,102400000") 17 #define CL(arr, val) memset(arr, val, sizeof(arr)) 18 19 #define ll long long 20 #define inf 0x7f7f7f7f 21 #define lc l,m,rt<<1 22 #define rc m + 1,r,rt<<1|1 23 #define pi acos(-1.0) 24 25 #define L(x) (x) << 1 26 #define R(x) (x) << 1 | 1 27 #define MID(l, r) (l + r) >> 1 28 #define Min(x, y) (x) < (y) ? (x) : (y) 29 #define Max(x, y) (x) < (y) ? (y) : (x) 30 #define E(x) (1 << (x)) 31 #define iabs(x) (x) < 0 ? -(x) : (x) 32 #define OUT(x) printf("%I64d ", x) 33 #define lowbit(x) (x)&(-x) 34 #define Read() freopen("a.txt", "r", stdin) 35 #define Write() freopen("b.txt", "w", stdout); 36 #define maxn 1000000000 37 #define N 2510 38 #define mod 1000000000 39 using namespace std; 40 41 int a[10001],dp[10001]; 42 int main() 43 { 44 // freopen("a.txt","r",stdin); 45 int n,sum=0,n1=0; 46 scanf("%d",&n); 47 for(int i=0;i<n;i++) 48 { 49 scanf("%d",&a[i]); 50 sum+=a[i]; 51 } 52 n1=sum/2; 53 memset(dp,0,sizeof(dp)); 54 for(int i=n-1;i>=0;i--) 55 for(int j=n1;j>=0;j--) 56 { 57 if(j>=a[i]) 58 { 59 dp[j]=max(dp[j],dp[j-a[i]]+a[i]); 60 } 61 } 62 //printf("%d ",dp[n1]); 63 printf("%d ",abs(sum-dp[n1]-dp[n1])); 64 return 0; 65 }
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1547
上面这题的变形,把a==1的矩形长度累加起来,然后做一次01背包,就能得知放置这些宽度为1的矩形所需要的最小长度是多少,
但是要注意可能sum/2的背包可能放不下,那就需要取两个数的最大值,最后加上宽度为2的矩形长度即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <vector> 5 #include <cstring> 6 #include <string> 7 #include <algorithm> 8 #include <string> 9 #include <set> 10 #include <functional> 11 #include <numeric> 12 #include <sstream> 13 #include <stack> 14 #include <map> 15 #include <queue> 16 #pragma comment(linker, "/STACK:102400000,102400000") 17 #define CL(arr, val) memset(arr, val, sizeof(arr)) 18 19 #define ll long long 20 #define inf 0x7f7f7f7f 21 #define lc l,m,rt<<1 22 #define rc m + 1,r,rt<<1|1 23 #define pi acos(-1.0) 24 25 #define L(x) (x) << 1 26 #define R(x) (x) << 1 | 1 27 #define MID(l, r) (l + r) >> 1 28 #define Min(x, y) (x) < (y) ? (x) : (y) 29 #define Max(x, y) (x) < (y) ? (y) : (x) 30 #define E(x) (1 << (x)) 31 #define iabs(x) (x) < 0 ? -(x) : (x) 32 #define OUT(x) printf("%I64d ", x) 33 #define lowbit(x) (x)&(-x) 34 #define Read() freopen("a.txt", "r", stdin) 35 #define Write() freopen("b.txt", "w", stdout); 36 #define maxn 1000000000 37 #define N 2510 38 #define mod 1000000000 39 using namespace std; 40 int dp[10005]; 41 int main() 42 { 43 //freopen("a.txt","r",stdin); 44 int t,n,a,b,c[105],n1,n2; 45 scanf("%d",&t); 46 while(t--) 47 { 48 scanf("%d",&n); 49 n1=n2=0; 50 memset(dp,0,sizeof(dp)); 51 memset(c,0,sizeof(c)); 52 int k=0; 53 for(int i=0;i<n;i++) 54 { 55 scanf("%d%d",&a,&b); 56 if(a==1) {n1+=b;c[k++]=b;} 57 n2+=b; 58 } 59 // printf("%d ",k); 60 for(int i=0;i<k;i++) 61 for(int j=n1/2;j>=c[i];j--) 62 if(j>=c[i]) 63 dp[j]=max(dp[j],dp[j-c[i]]+c[i]); 64 // printf("%d ",dp[n1/2]); 65 printf("%d ",max(n1-dp[n1/2],dp[n1/2])+n2-n1); 66 } 67 return 0; 68 }