csu 1547(01背包)

1547: Rectangle

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 996  Solved: 277
[Submit][Status][Web Board]

Description

Now ,there are some rectangles. The area of these rectangles is 1* x or 2 * x ,and now you need find a big enough rectangle( 2 * m) so that you can put all rectangles into it(these rectangles can't rotate). please calculate the minimum m satisfy the condition.

Input

There are some tests ,the first line give you the test number.
Each test will give you a number n (1<=n<=100)show the rectangles number .The following n rows , each row will give you tow number a and b. (a = 1 or 2 , 1<=b<=100).

Output

Each test you will output the minimum number m to fill all these rectangles.

Sample Input

2
3
1 2
2 2
2 3
3
1 2
1 2
1 3

Sample Output

7
4

题意:在 2*m 的矩形里面放若干宽度为1和2的矩形,问 m 最小要多大?
题解:首先,对于宽度为2的矩形,我们直接加上就好了,这是它所需要的容积,对于宽度为 1 的矩形,我们长度先对其排序,这样就保证了选的矩形尽可能的可以并排放下,对sum/2做01背包,得到容量为sum/2的
背包能够放的最大容量m,用sum-dp[sum/2]即为所需最小容量。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
int x[105],y[105],v[105];
int dp[10005];
int main()
{
    int tcase,n;
    scanf("%d",&tcase);
    while(tcase--){
        scanf("%d",&n);
        int ans = 0,cnt=0,sum = 0;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&x[i],&y[i]);
            if(x[i]==2){
                ans+=y[i];
            }else{
                v[++cnt] = y[i];
                sum+=v[cnt];
            }
        }
        memset(dp,0,sizeof(dp));
        sort(v+1,v+cnt+1);
        for(int i=1;i<=cnt;i++){
            for(int j=sum/2;j>=v[i];j--){
                dp[j] = max(dp[j],dp[j-v[i]]+v[i]);
            }
        }
        int res = ans+sum-dp[sum/2];
        printf("%d\n",res);
    }

}

 




posted @ 2016-08-21 09:43  樱花庄的龙之介大人  阅读(182)  评论(0编辑  收藏  举报