A - Rectangle(dp 01背包)

Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%lld & %llu

Submit Status

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

【分析】

  1. 大致题意是往一个2*m的矩形填1*x和2*y的矩形,求m的最小值。
  2. 其实我也不知道用什么方法啦,但是感觉会和背包有一点点关系,就试着用了一下。可能题练少了题感太弱了吧┭┮
  3. 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;	
		
		
	}
}

猜你喜欢

转载自blog.csdn.net/qq_38735931/article/details/81809774