题意:给出一个长为a,宽为b的布,再给出n个围巾的规格(长x,宽y,价值c),问怎样裁剪能够得到最大的价值。
----第一次做的时候不会---然后放到今天做--发现还是不会---于是又--看题解了----@_@===
因为相同规格的围巾可以重复剪多次,且围巾的长和宽相当于两个约束,所以可以转换为二维费用的完全背包问题。
然后就是围巾的裁剪
第一种 横着减
裁切线分为两种
对于左上的第一个图,当减去长为x,宽有长为y的一个矩形之后,剩余的面积之和分别由长为i-x,宽为y;长为i,宽为j-y的两个矩形组成。
对于左上的第二个图,当减去长为x,宽有长为y的一个矩形之后,剩余的面积之和分别由长为i-x,宽为j;长为x,宽为j-y的两个矩形组成。
第二种 竖着减 和第一种的方法类似--
然后就可以写出状态转移方程----
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1005
using namespace std;
struct node
{
int x,y,c;
} a[maxn];
int dp[maxn][maxn];
int main()
{
int ncase,n,c,d,i,j,k;
scanf("%d",&ncase);
while(ncase--)
{
scanf("%d %d %d",&n,&c,&d);
for(i=;i<n;i++)
scanf("%d %d %d",&a[i].x,&a[i].y,&a[i].c);
memset(dp,,sizeof(dp)); for(i=;i<=c;i++)
{
for(j=;j<=d;j++)
{
for(k=;k<n;k++)
{
if(i>=a[k].x&&j>=a[k].y)
dp[i][j]=max(dp[i][j],max(dp[i-a[k].x][a[k].y]+dp[i][j-a[k].y]+a[k].c,dp[i-a[k].x][j]+dp[a[k].x][j-a[k].y]+a[k].c));
if(i>=a[k].y&&j>=a[k].x)
dp[i][j]=max(dp[i][j],max(dp[i-a[k].y][j]+dp[a[k].y][j-a[k].x]+a[k].c,dp[i][j-a[k].x]+dp[i-a[k].y][a[k].x]+a[k].c)); }
}
}
printf("%d\n",dp[c][d]);
}
}