HDU 3127 WHUgirls(二维背包)
2016-02-23 14:28
429 查看
题目链接:【HDU 3127】
有一块X*Y的布,可以裁剪成n种不同的小碎步布,剪成xi*yi的碎布可以获得wi元,问将这块布剪成小碎布最多能获得多少钱?只能横着剪或者竖着剪,不能从中间抠出一块
二维dp,dp[j][k]表示j*k的布剪成小碎布最多能得到多少钱,j*k可以由三个小长方形组成:(这里有切割方式)
1、xi*yi、 j*(k-xi)、 (j-xi)*yi
2、xi*yi、 xi*(k-yi)、 (j-xi)*k
3、xi*yi、 j*(k-xi)、 (j-yi)*xi
4、xi*yi、 yi*(k-xi)、 (j-yi)*k
所以转移方程式是:
dp[j][k] = max(dp[j][k], max(dp[j-xi][k]+dp[xi][k-yi], dp[j][k-yi]+dp[j-xi][yi])+wi);
dp[j][k] = max(dp[j][k], max(dp[j-yi][k]+dp[yi][k-xi], dp[j][k-xi]+dp[j-yi][xi])+wi);
重点来了!
网上的绝大多数博客式直接用以下代码得到的dp[X][Y]作为最终的值输出,我觉得这并不是最终的正确答案,下面的代码过不了hdu -discuss里面的一个数据:
1
4 8 26
1 5 1
3 7 10
3 19 500
5 10 1000
这个答案应该是2521
下面这两个代码都是ac的
有一块X*Y的布,可以裁剪成n种不同的小碎步布,剪成xi*yi的碎布可以获得wi元,问将这块布剪成小碎布最多能获得多少钱?只能横着剪或者竖着剪,不能从中间抠出一块
二维dp,dp[j][k]表示j*k的布剪成小碎布最多能得到多少钱,j*k可以由三个小长方形组成:(这里有切割方式)
1、xi*yi、 j*(k-xi)、 (j-xi)*yi
2、xi*yi、 xi*(k-yi)、 (j-xi)*k
3、xi*yi、 j*(k-xi)、 (j-yi)*xi
4、xi*yi、 yi*(k-xi)、 (j-yi)*k
所以转移方程式是:
dp[j][k] = max(dp[j][k], max(dp[j-xi][k]+dp[xi][k-yi], dp[j][k-yi]+dp[j-xi][yi])+wi);
dp[j][k] = max(dp[j][k], max(dp[j-yi][k]+dp[yi][k-xi], dp[j][k-xi]+dp[j-yi][xi])+wi);
重点来了!
网上的绝大多数博客式直接用以下代码得到的dp[X][Y]作为最终的值输出,我觉得这并不是最终的正确答案,下面的代码过不了hdu -discuss里面的一个数据:
1
4 8 26
1 5 1
3 7 10
3 19 500
5 10 1000
这个答案应该是2521
for(int j=0; j<=X; j++) { for(int k=0; k<=Y; k++) { for(int i=0; i<n; i++) { if(j>=x[i] && k>=y[i]) { int ans = max(dp[j-x[i]][k]+dp[x[i]][k-y[i]], dp[j][k-y[i]]+dp[j-x[i]][y[i]]); dp[j][k] = max(dp[j][k], ans+w[i]); } if(j>=y[i] && k>=x[i]) { int ans = max(dp[j-y[i]][k]+dp[y[i]][k-x[i]], dp[j][k-x[i]]+dp[j-y[i]][x[i]]); dp[j][k] = max(dp[j][k], ans+w[i]); } } } }布剪成小碎布之后还剩下一些没有价值的布,这有时会造成dp[X][Y]偏小(我觉得这也是为什么三个for位置换了之后,直接输出dp[X][Y]会wa的原因),需要再加上代码中的两句话
下面这两个代码都是ac的
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <string> using namespace std; int dp[1010][1010]; int main() { int t; scanf("%d", &t); while(t--) { memset(dp, 0, sizeof(dp)); int n, X, Y, xi, yi, wi; scanf("%d%d%d", &n, &X, &Y); for(int i=0; i<n; i++)//这个循环放在最前面还是对的 { scanf("%d%d%d", &xi, &yi, &wi); for(int j=0; j<=X; j++) { for(int k=0; k<=Y; k++) { if(j>=xi && k>=yi) { int ans = max(dp[j-xi][k]+dp[xi][k-yi], dp[j][k-yi]+dp[j-xi][yi]); dp[j][k] = max(dp[j][k], ans+wi); } if(j>=yi && k>=xi) { int ans = max(dp[j-yi][k]+dp[yi][k-xi], dp[j][k-xi]+dp[j-yi][xi]); dp[j][k] = max(dp[j][k], ans+wi); } } } } int ans = dp[X][Y];//以下两句是我认为要加上去的 for(int i=0; i<=X; i++) ans = max(ans, dp[i][Y]+dp[X-i][Y]); for(int i=0; i<=Y; i++) ans = max(ans, dp[X][i]+dp[X][Y-i]); printf("%d\n", ans); } return 0; }
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
int dp[1010][1010];
int x[15], y[15], w[15];
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
memset(dp, 0, sizeof(dp));
int n, X, Y;
scanf("%d%d%d", &n, &X, &Y);
for(int i=0; i<n; i++)
{
scanf("%d%d%d", &x[i], &y[i], &w[i]);
}
for(int j=0; j<=X; j++) { for(int k=0; k<=Y; k++) { for(int i=0; i<n; i++) { if(j>=x[i] && k>=y[i]) { int ans = max(dp[j-x[i]][k]+dp[x[i]][k-y[i]], dp[j][k-y[i]]+dp[j-x[i]][y[i]]); dp[j][k] = max(dp[j][k], ans+w[i]); } if(j>=y[i] && k>=x[i]) { int ans = max(dp[j-y[i]][k]+dp[y[i]][k-x[i]], dp[j][k-x[i]]+dp[j-y[i]][x[i]]); dp[j][k] = max(dp[j][k], ans+w[i]); } } } }
int ans = dp[X][Y];
for(int i=0; i<=X; i++) ans = max(ans, dp[i][Y]+dp[X-i][Y]);
for(int i=0; i<=Y; i++) ans = max(ans, dp[X][i]+dp[X][Y-i]);
printf("%d\n", ans);
}
return 0;
}
相关文章推荐
- iOS 5.0 后UIViewController新增:willMoveToParentViewController和didMoveToParentViewController
- Struts2面试题1
- ecshop的数据库getRow、getAll、getOne区别
- ECshop 数据库表结构以及创建语句
- Redis和Memcache的区别分析
- LeetCode: 318. Maximum Product of Word Lengths
- select (SYSDATE - 10) into datevar from dual
- java实现不规则窗体
- Android java.lang.NoClassDefFoundError的一种解决方法
- Spark 资源池简介
- Apache Mina(一)
- Win7旗舰版IIS配置
- Ubuntu安装MongoDB和PHP扩展
- 解决Web部署 svg/woff/woff2字体 404错误(转)
- eclipse中DDMS的LOGcat只有一列level
- [备忘]Sublime Text 3 Python编辑环境搭建
- auto_cmdb--01之models.py建表
- easyUI 中datagrid控件demo,包括选中一行能读取到数据
- Android中为何获取系统时间的方法多次执行后时间仍不变,解决方法
- 数据库迁移之从oracle 到 MySQL