hdoj 3127 WHUgirls 【好题 DP】
来源:互联网 发布:小公司网络布线 编辑:程序博客网 时间:2024/04/29 12:47
WHUgirls
Time Limit: 3000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2286 Accepted Submission(s): 865
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
12 4 42 2 23 3 9
9
题意:
现在有一块X*Y的矩形布条, 然后有n种规格的x[i]*y[i]的小布条, 每种布条可以卖出val[i]的价值. 问你原始的X*Y布条最多能卖多少价值? 其中每次切割布条只能水平或垂直的切, 且一刀到底.
分析:
本题看起来比较麻烦, 但是搞懂原理后还是很简单的. 把当前还剩余的矩形布条看成容量, 那么我们就是再这有限的容量里面要找出最大价值的布条总和来.
令dp[i][j]==x 表示当前长i和宽j的布条能切割出的最大价值为x.
这里有个结论要注意: 我们每次从大矩形中切割出一个小矩形, 总是沿着大矩形的顶角边缘切割将不会丢失最优解.
比如一个i*j的大矩形, 我们如果要从中切割出一个x*y的小矩形, 有下面4种方式(大矩形可以选择先下垂直那刀或先下水平那刀,小矩形能旋转):
(仔细体会上面这个图.)
有了上面的图, 下面我们的递推公式就出来了:
if(i>=r[k].x&& j>=r[k].y)
dp[i][j]=max(dp[i][j] , max( dp[i-r[k].x][j]+dp[r[k].x][j-r[k].y] ,dp[i-r[k].x][r[k].y]+dp[i][j-r[k].y] )+r[k].val );
if(i>=r[k].y && j>=r[k].x)
dp[i][j]=max(dp[i][j] , max( dp[r[k].y][j-r[k].x]+dp[i-r[k].y][j] ,dp[i-r[k].y][r[k].x]+dp[i][j-r[k].x] )+r[k].val );
上面两个公式好像看起来很复杂, 其实理解上面的图之后就很简单了. 本质就是:
原始矩形能获得的最大价值 == max(小矩形价值 + 被水平一刀和竖直一刀切割后剩下的两个矩形能获得的最大价值和 )
也就是求切割后的3个矩形的价值和, 看看哪种方式切割剩下的矩形价值和最大.(两刀之后,原始矩形必然变成3个新矩形)
初始化: dp为全0.
最终所求: dp[X][Y].
注意:完全背包问题限制条件的维度j和物品编号的维度i的循环先后顺序是可以互换的. 但是此题必须先循环X和Y的维度,然后才是物品编号的维度. 因为一般的完全背包问题的最优解对于物品的选取顺序没有要求, 可以先区任何物品. 但是此题对于原始矩形来说, 你在它的顶角边缘先切割那个小矩形是明显不同的,有可能你先切割1号矩形就得不到最优解, 但是你先切割3号矩形才能得到最优解。
#include<stdio.h>#include<string.h>int max(int x,int y){ return x>y?x:y;}int dp[1010][1010];int x[15],y[15],value[15];int main(){ int t,n,X,Y; int k,i,j; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&X,&Y); for(i=0;i<n;i++) scanf("%d%d%d",&x[i],&y[i],&value[i]); memset(dp,0,sizeof(dp)); for(i=0;i<=X;i++) { for(j=0;j<=Y;j++) { for(k=0;k<n;k++) { if(i>=x[k]&&j>=y[k]) dp[i][j]=max(dp[i][j],max(dp[i-x[k]][y[k]]+dp[i][j-y[k]],dp[i-x[k]][j]+dp[x[k]][j-y[k]])+value[k]); if(i>=y[k]&&j>=x[k]) dp[i][j]=max(dp[i][j],max(dp[i-y[k]][x[k]]+dp[i][j-x[k]],dp[y[k]][j-x[k]]+dp[i-y[k]][j])+value[k]); } } } printf("%d\n",dp[X][Y]); } return 0;}
- hdoj 3127 WHUgirls 【好题 DP】
- hdu 3127 WHUgirls【dp】好题~
- HDOJ 题目3127 WHUgirls(完全背包)
- HDU OJ 3127 WHUgirls【DP之背包】
- HDU 3127 WHUgirls dp背包问题
- HDU OJ 3127 WHUgirls【DP之背包】
- 【DP】HDU 3127 WHUgirls 完全背包
- HDU 3127 WHUgirls (线性dp 完全背包)
- hdoj 1176 免费馅饼 【DP 好题】
- HDU 3127. WHUgirls【dp】
- hdoj 龟兔赛跑 2059 (DP) 好题
- hdoj Happy Matt Friends 5119 (DP) 好题
- hdoj Dire Wolf 5115 (区间DP) 好题
- hdoj Robberies 2955 (概率Dp&&01背包) 好题
- hdoj ZZY’s Dilemma 4152 (DP) 好题
- hdoj The Romantic Hero 4901 (DP 位运算) 好题
- hdu 3127 WHUgirls
- hdu 3127 WHUgirls
- android:TableLayout表格布局详解
- oc的MRC
- [OC学习笔记]NSSet、NSMutableSet、NSIndexSet常用方法
- eclipse中提示设置
- Idea 安装与配置
- hdoj 3127 WHUgirls 【好题 DP】
- 5.18作业
- 二叉树中和为某一值的路径
- bzoj 1091 裸半面交
- 解决HaxeUI中文显示问题--FontCreator合并字体文件
- Java复习笔记13【Date类的简单使用】
- Android控件系列之RadioButton&RadioGroup
- Cocos2d-2.x_跑马灯效果
- Openfire服务端安装和配置