WHUgirls
Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2068 Accepted Submission(s): 785
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.
Constrains
0 < T <= 20
0 <= N <= 10; 0 < X, Y <= 1000
0 < xi <= X; 0 < yi <= Y; 0 <= ci <= 1000
1 2 4 4 2 2 2 3 3 9
9
这个题开始做的时候,一直分析,感觉应该是要用动态规划来做,其他做法应该会要超时,然后一直往动态规划那方面想,结果越想越复杂,感觉情况太多了,考虑不周全,后来看了一下别人的思路,直接可以转化为二维的完全背包问题;一大块完整的布就相当于一个背包,剪布料就相当于往里面放东西,因为剪矩形有长和宽,所以就是二维来做,每剪一块的价值就相当于背包的价值,最关键的是每一种可以剪多次,完全背包里面的一种物品可以放多次;
看了这一篇博客的分析: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;
}