mthoutai

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

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
1 2 4 4 2 2 2 3 3 9
 

Sample Output
9
 

Source

 这个题開始做的时候。一直分析。感觉应该是要用动态规划来做。其它做法应该会要超时,然后一直往动态规划那方面想。结果越想越复杂,感觉情况太多了。考虑不周全,后来看了一下别人的思路,直接能够转化为二维的全然背包问题。一大块完整的布就相当于一个背包,剪布料就相当于往里面放东西,由于剪矩形有长和宽。所以就是二维来做,每剪一块的价值就相当于背包的价值,最关键的是每一种能够剪多次,全然背包里面的一种物品能够放多次;

看了这一篇博客的分析:http://blog.csdn.net/lulipeng_cpp/article/details/7587465

题目的意思就是要我们能够剪的最大价值,所以设立 dp[i][j]:长为i宽为j的矩形布的最大价值;

由于剪成矩形有两种情况能够剪,(能够參看上面的博客),一种直接是依照长来剪,还能够依照宽来剪。剪了之后,一块矩形的布可能就不是一个矩形了,我们就把它分成三块来算,分成3个小矩形。我们要求的就是这三个小矩形的面积之和;设立 要剪去的矩形的长为x,宽为y。(图片直接是上面的博客里面的)


我们就有两种剪法:

第一种:


这里我们就能够得到方法一的状态方程式;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);

另外一种:


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 <cstdio>
#include <cstring>
#include <algorithm>
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<n;i++)
            scanf("%d%d%d",&bag[i].x,&bag[i].y,&bag[i].value);
        for(i=0;i<=x;i++)
            for(j=0;j<=y;j++)
            for(k=0;k<n;k++)
        {
            if(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;
}



posted on 2017-07-10 18:23  mthoutai  阅读(318)  评论(0编辑  收藏  举报