1547: Rectangle
Submit Page Summary Time Limit: 1 Sec Memory Limit: 256 Mb Submitted: 1193 Solved: 344
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
Hint
Source
解题思路:
给你一些小块只有1*X,或者2*X,问使用一个2*M的大方块装下这些小方块,问M的最小值。因为题意中说矩形是不能旋转的,那么当遇到宽为2的矩形是直接加就行,难点在于如何平铺宽为1的矩形。
由画图可知,全部的宽为1的长方形我们所要做的就是将它们分成长度尽可能接近的2堆,需要用01背包来解决。
背包的容量为sum/2(sum为全部宽为1长方形的b的和),每一个长方形的价值为b,重量也为b,最终只需计算max(dp[sum/2],sum-dp[sum/2])即可。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+5;
int v[maxn],w[maxn],dp[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(v,0,sizeof(v));
memset(w,0,sizeof(w));
memset(dp,0,sizeof(dp));
int n,num=0,ans=0,sum=0,k=0,p=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
if(a==2)
ans+=b;
else
{
sum+=b;
v[num]=b;
w[num++]=b;
}
}
for(int i=0;i<num;i++)
{
for(int j=sum/2;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
ans+=max(dp[sum/2],sum-dp[sum/2]);
printf("%d\n",ans);
}
return 0;
}