1547: Rectangle
Time Limit: 1 Sec Memory Limit: 256 Mb Submitted: 1281 Solved: 366
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*这2种长方形,将这些长方形都放在一个2*的长方形,让我们找出最小的长方形,2*的我们就直接将长度加起来,主要的是如何处理1*的长方形,我们自己去画图的时候我们会发现我们把1*的尽量是1*的总和的一半,尽量是一半,这样肯定是最短的,具体处理就是用01背包处理,背包的容量是sum/2,vo和va都是b,然后找最大的就好,在最后输出答案的时候还要ans[sum/2]和sum-ans[sum/2]中选最大的,具体的自己画图理解理解
#include<bits/stdc++.h>
using namespace std;
int va[102],vo[102],ans1[10002];//ans1这个数组一开始开小了,出现了段错误
int main(void)
{
int t,n,a,b,sum;
scanf("%d",&t);
while(t--)
{
int k=0,ans=0,sum=0;
scanf("%d",&n);
memset(ans1,0,sizeof ans1);
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
if(a==2) ans+=b;
else
{
sum+=b;
va[k]=b;
vo[k]=b;
k++;
}
}
int v=sum/2;
for(int i=0;i<k;i++)
{
for(int j=v;j>=vo[i];j--)
{
ans1[j]=max(ans1[j],ans1[j-vo[i]]+va[i]);
}
}
printf("%d\n",ans+max(ans1[v],sum-ans1[v]));
}
return 0;
}