csu 1547: Rectangle (01背包)

来源:互联网 发布:上海大数据交易中心 编辑:程序博客网 时间:2024/06/05 02:35

1547: Rectangle

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 716  Solved: 197
[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

231 22 22 331 21 21 3

Sample Output

74

HINT

给你一个n个1*x和2*x的矩形,这些矩阵不能翻转,只能横着摆放。 
现在要你用这些矩形拼成 2*m的矩形,问m最短是多少。



题解:宽为2的直接加,宽为1的把所有的长加起来sum,算容量为sum/2的背包最大放多少。

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#include<cmath>#define Mod 1000000007#define ll long long#define N 111#define INF 1010010010using namespace std;struct node {    int x;    int y;} a[N];int n;int cmp(node a,node b) {    if(a.x==b.x)return a.y>b.y;    return a.x>b.x;}int dp[N*N];int main() {    //freopen("in.txt","r",stdin);    int t;    cin>>t;    while(t--) {        scanf("%d",&n);        for(int ii=0; ii<n; ii++) {            scanf("%d%d",&a[ii].x,&a[ii].y);        }        sort(a,a+n,cmp);        a[n].y=0;        int ans=0;        int i=0;        while(i<n&&a[i].x==2) {            ans+=a[i].y;            i++;        }        int sum=0;        for(int ii=i; ii<n; ii++)sum+=a[ii].y;        int s=sum/2;        memset(dp,0,sizeof dp);        for(int ii=i;ii<n;ii++)        {             for(int j=s;j>=a[ii].y;j--)             {                  dp[j]=max(dp[j],dp[j-a[ii].y]+a[ii].y);             }        }        int ss=sum-dp[s];        printf("%d\n",ans+max(ss,dp[s]));    }    return 0;}


0 0
原创粉丝点击