WHUgirls
Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2068 Accepted Submission(s): 785
Problem Description
There are many pretty girls in Wuhan University, and as we know, every girl loves pretty clothes, so do they. One day some of them got a huge rectangular cloth and they want to cut it into small rectangular pieces to make scarves. But different girls like different style, and they voted each style a price wrote down on a list. They have a machine which can cut one cloth into exactly two smaller rectangular pieces horizontally or vertically, and ask you to use this machine to cut the original huge cloth into pieces appeared in the list. Girls wish to get the highest profit from the small pieces after cutting, so you need to find out a best cutting strategy. You are free to make as many scarves of a given style as you wish, or none if desired. Of course, the girls do not require you to use all the cloth.
Input
The first line of input consists of an integer T, indicating the number of test cases.
The first line of each case consists of three integers N, X, Y, N indicating there are N kinds of rectangular that you can cut in and made to scarves; X, Y indicating the dimension of the original cloth. The next N lines, each line consists of two integers, xi, yi, ci, indicating the dimension and the price of the ith rectangular piece cloth you can cut in.
Output
Output the maximum sum of prices that you can get on a single line for each case.
Constrains
0 < T <= 20
0 <= N <= 10; 0 < X, Y <= 1000
0 < xi <= X; 0 < yi <= Y; 0 <= ci <= 1000
Sample Input
Sample Output
Source
2009 Asia Wuhan Regional Contest Online
这个题开始做的时候,一直分析,感觉应该是要用动态规划来做,其他做法应该会要超时,然后一直往动态规划那方面想,结果越想越复杂,感觉情况太多了,考虑不周全,后来看了一下别人的思路,直接可以转化为二维的完全背包问题;一大块完整的布就相当于一个背包,剪布料就相当于往里面放东西,因为剪矩形有长和宽,所以就是二维来做,每剪一块的价值就相当于背包的价值,最关键的是每一种可以剪多次,完全背包里面的一种物品可以放多次;
看了这一篇博客的分析:http://blog.csdn.net/lulipeng_cpp/article/details/7587465
题目的意思就是要我们可以剪的最大价值,所以设立 dp[i][j]:长为i宽为j的矩形布的最大价值;
因为剪成矩形有两种情况可以剪,(可以参看上面的博客),一种直接是按照长来剪,还可以按照宽来剪;剪了之后,一块矩形的布可能就不是一个矩形了,我们就把它分成三块来算,分成3个小矩形,我们要求的就是这三个小矩形的面积之和;设立 要剪去的矩形的长为x,宽为y;(图片直接是上面的博客里面的)
![hdu oj 3127 WHUgirls(2009 Asia Wuhan Regional Contest Online)_第1张图片](http://img.e-com-net.com/image/info8/9e73170f74a84a51b3c72b13c7da2068.jpg)
我们就有两种剪法:
第一种:
![hdu oj 3127 WHUgirls(2009 Asia Wuhan Regional Contest Online)_第2张图片](http://img.e-com-net.com/image/info8/d06fa9b1d1284a518ad84a1fec1cc9ac.jpg)
这里我们就可以得到方法一的状态方程式;w为剪去的小矩形的价值;
dp[i][j]=max(dp[i][j],max(dp[i-x][j]+dp[x][j-y],dp[i][j-y]+dp[i-x][y])+w);
第二种:
![hdu oj 3127 WHUgirls(2009 Asia Wuhan Regional Contest Online)_第3张图片](http://img.e-com-net.com/image/info8/086dacef13944f11ac279e60fef70fa2.jpg)
dp[i][j]=max(dp[i][j],max(dp[i-y][j]+dp[y][j-x],dp[i][j-x]+dp[i-y][x])+w);
下面的ac的代码;
#include
#include
#include
using namespace std;
struct bag
{
int x,y,value;
};
bag bag[10];
int dp[1001][1001];
int main()
{
int t,n,x,y,i,j,k;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&n,&x,&y);
for(i=0;i=bag[k].x && j>=bag[k].y)//第一种剪法;
dp[i][j]=max(dp[i][j],max((dp[i-bag[k].x][j]+dp[bag[k].x][j-bag[k].y]),(dp[i][j-bag[k].y]+dp[i-bag[k].x][bag[k].y]))+bag[k].value);
if(i>=bag[k].y && j>=bag[k].x)//第二种剪法;
dp[i][j]=max(dp[i][j],max((dp[i-bag[k].y][j]+dp[bag[k].y][j-bag[k].x]),(dp[i][j-bag[k].x]+dp[i-bag[k].y][bag[k].x]))+bag[k].value);
}
printf("%d\n",dp[x][y]);
}
return 0;
}