HDU 3127 WHUgirls(DP 完全背包)

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

题目大意:将一块长x宽y的矩形布料,剪成小的矩形(每个给定的小矩形都对应一个价值),使得所有小矩形产生的价值最大。

Sample Input

1

2 4 4

2 2 2

3 3 9

Sample Output

9

分析:

这题可以可以看做完全背包问题来接。因为:1、每种矩形布可以剪任意多个;2、题目给出的矩形布可以看做背包容量;3、每个矩形布都有一个价值

关键在于找到状态转移方程:设dp[i][j]为长为i宽为j的矩形布的最大价值,下面的图一可以看做待剪的布,图二为小布的尺寸

HDU 3127 WHUgirls(DP 完全背包)HDU 3127 WHUgirls(DP 完全背包)
对于这个问题可以两种如下剪布方案:
HDU 3127 WHUgirls(DP 完全背包)
 
HDU 3127 WHUgirls(DP 完全背包)
易知剪布后的价值为每个图形中三块之和。
对于方法一:

dp[i][j] = max(dp[i][j],  dp[i-p[k].x][j]+dp[p[k].x][j-p[k].y]+p[k].value,  dp[i][j-p[k].y]+dp[i-p[k].x][p[k].y]+p[k].value);

对于方法二:

dp[i][j] = max(dp[i][j],  dp[i-p[k].y][j]+dp[p[k].y][j-p[k].x]+p[k].value,  dp[i][j-p[k].x]+dp[i-p[k].y][p[k].x]+p[k].value);

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
using namespace std;
struct node{
int x,y,value;
}p[];
int dp[][]; int max(int a,int b,int c){
int temp = a>b?a:b;
return temp>c?temp:c;
} int main(){
int T,n,x,y;
int i,j,k;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&x,&y);
for(i=;i<n;i++)
scanf("%d%d%d",&p[i].x,&p[i].y,&p[i].value);
memset(dp,,sizeof(dp));
for(i=;i<=x;i++){
for(j=;j<=y;j++){
for(k=;k<n;k++){
if(i>=p[k].x &&j>=p[k].y)
dp[i][j] = max(dp[i][j], dp[i-p[k].x][j]+dp[p[k].x][j-p[k].y]+p[k].value,
dp[i][j-p[k].y]+dp[i-p[k].x][p[k].y]+p[k].value);
if(i>=p[k].y &&j>=p[k].x)
dp[i][j] = max(dp[i][j], dp[i-p[k].y][j]+dp[p[k].y][j-p[k].x]+p[k].value,
dp[i][j-p[k].x]+dp[i-p[k].y][p[k].x]+p[k].value);
}
}
}
printf("%d\n",dp[x][y]);
}
return ;
}
上一篇:2-STM32物联网开发WIFI(ESP8266)+GPRS(Air202)系统方案升级篇(视频总揽)


下一篇:HDU 2159 FATE(二维全然背包)