WHUgirls----HDU_3127----二维的完全背包

来源:互联网 发布:打淘宝电话怎么转人工 编辑:程序博客网 时间:2024/06/08 02:46

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=3127


WHUgirls

Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1111    Accepted Submission(s): 451


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
12 4 42 2 23 3 9
 

Sample Output
9
 

Source
2009 Asia Wuhan Regional Contest Online




题目的意思是有一块大布,你要在上面裁剪小块布料,每一种布料都有相应的权重。而且在大布上裁剪相同的多次(完全背包)。要你给出在有限大布内裁剪之后的最大权重。反过来想,这一整块布就像一个二维的背包,而小布就是物品。我们要尽量的往里面装东西,使得里面装下的物品的权重之和最大。而且每种物品都是可以重复使用的,那么这就转换成了一个背包问题。但是怎样装呢?我们就从左下往右上方装。经孟成博同学点拨,主有如下两种方案。


如图就是所说的两种方案。红色的就是要装的小布块。而且还要注意的小布块是可以横着放,即x,y值交换位置。我们以f[m][n]来表示以m,n为长宽的布料所能取得的最大权重。则

if(m>=r[i].x && n>=r[i].y) //正着放 
dp[m][n] = max3(dp[m-r[i].x][n] + dp[r[i].x][n-r[i].y]+ r[i].pro,dp[m][n-r[i].y] + dp[m-r[i].x][r[i].y]+r[i].pro,dp[m][n]);
if(m>=r[i].y && n>=r[i].x) //倒着放 
dp[m][n] = max3(dp[m-r[i].y][n] + dp[r[i].y][n-r[i].x]+ r[i].pro,dp[m][n-r[i].x] + dp[m-r[i].y][r[i].x]+r[i].pro,dp[m][n]);

在后面的代码中你还会发现,小布块的种数循环放在里面去了。为什么呢?经薛智文同学的点拨,我们是这样理解的。因为二维的不像一维的,即使你要放下也是要有讲究的,如果你随意乱放的话有可能就装不下最大的,这个大家应该有生活体验。所以如果放在外面,一个一个装的话就失去了调整的机会。但是如果把物品种数放在里面的话,你就有一个调整的过程,这样就可以找到最合适的方法从而使得你放下的是最大权重的方法。在此感谢孟成博和薛智文同学的点拨,让我更好的理解了这个题目,对二维完全背包的解法也有了更深的体会。下面上代码。

#include<iostream>using namespace std;#define MAX 1002struct rect{int x,y;int pro; }r[12]; int dp[MAX][MAX];int max3(int a,int b,int c){int temp = a>b?a:b;return temp>c?temp:c;} int main(){int t;cin>>t;while(t--){int num,x,y;scanf("%d%d%d",&num,&x,&y);for(int i=1;i<=num;i++)cin>>r[i].x>>r[i].y>>r[i].pro;memset(dp,0,sizeof(dp));int m,n;//是完全背包啊,伤不起啊 for(m=0;m<=x;m++){for(n=0;n<=y;n++){for(int i=1;i<=num;i++){if(m>=r[i].x && n>=r[i].y) //正着放           dp[m][n] = max3(dp[m-r[i].x][n] + dp[r[i].x][n-r[i].y]+ r[i].pro,dp[m][n-r[i].y] + dp[m-r[i].x][r[i].y]+r[i].pro,dp[m][n]);if(m>=r[i].y && n>=r[i].x) //倒着放 dp[m][n] = max3(dp[m-r[i].y][n] + dp[r[i].y][n-r[i].x]+ r[i].pro,dp[m][n-r[i].x] + dp[m-r[i].y][r[i].x]+r[i].pro,dp[m][n]);} } }printf("%d\n",dp[x][y]); } system("pause"); return 0; } 







原创粉丝点击