Time Limit:1000MS Memory Limit:262144KB 64bit IO Format:%lld & %llu
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*x和2*y的矩形,求m的最小值。
- 其实我也不知道用什么方法啦,但是感觉会和背包有一点点关系,就试着用了一下。可能题练少了题感太弱了吧┭┮
- 01背包,一次只拿一个,套模板转换方程。要注意的是,如果a是2的话就只能平铺依次相加。但如果a是1的话,就要横着放,那么两个矩形就可以放两行,这里用01背包进行转换。所以容量sum=sum/2;sum一开始是a为1的时候b的值累加,之后就拿此sum除以2就好
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
int c[maxn];//各个长方形的长度------各个背包的重量
int dp[10005];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,a,b,ans=0,sum=0,end=0;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
if(a==2)ans+=b;
else {
c[end++]=b;
sum+=b;//cout<<"sum="<<sum<<endl;
}
}
memset(dp,0,sizeof(dp));
for(int i=0;i<end;i++)
for(int j=sum/2;j>=c[i];j--)
dp[j]=max(dp[j],dp[j-c[i]]+c[i]);
ans+=sum-dp[sum/2];
cout<<ans<<endl;
}
}