[kuangbin带你飞]专题十二 基础DP1 C - Monkey and Banana
2017-04-23 11:52
585 查看
第一次不看题解1A掉DP,虽然是简单的2333.
题意概要:
有n类箱子,每类可以无限使用,求最高用这些箱子堆成多高塔?箱子可以任意旋转和翻转
限制:
1. 塔中每个箱子的底面的长和宽都要比它下面的箱子的长和宽严格的小
思路:
1. 我首先想到的是箱子可以无限用诶,难道没有一个限制吗?然后灵光一动,一类箱子如果不旋转和翻转,就只能放一个进塔中(由限制1), 那么可以旋转和翻转就最多6个啦,如果输入的是x y z,那么这六个就是:
x y z,
y z x,
x z y,
z x y,
y z x,
z y x。
也就是x y z的排列组合啦(23333)
所以把输入按以上处理就可以把箱子的无限化为有限
2.那么如何表示状态,我想到的首先就是dp[i][j], 用了 i个箱子并且用了第j个箱子时能达到的最大高度。
状态如何转移呢?
如果第k个箱子的底面比第j个箱子大
dp[i][j] = max(dp[i][j], dp[i-1][k] + node[j].z);
node[j]表示第j个箱子,z是它的高
为了方便处理我们用x对箱子排序这样只用遍历之前的箱子,而不用遍历所有箱子。
初始化时node[0]代表地,所以x, y为INF, z 为0。
得到代码如下:
我们可以发现,每次只用了前一个状态,所以可以把dp降成一维
欢迎指正, 以上
题意概要:
有n类箱子,每类可以无限使用,求最高用这些箱子堆成多高塔?箱子可以任意旋转和翻转
限制:
1. 塔中每个箱子的底面的长和宽都要比它下面的箱子的长和宽严格的小
思路:
1. 我首先想到的是箱子可以无限用诶,难道没有一个限制吗?然后灵光一动,一类箱子如果不旋转和翻转,就只能放一个进塔中(由限制1), 那么可以旋转和翻转就最多6个啦,如果输入的是x y z,那么这六个就是:
x y z,
y z x,
x z y,
z x y,
y z x,
z y x。
也就是x y z的排列组合啦(23333)
所以把输入按以上处理就可以把箱子的无限化为有限
2.那么如何表示状态,我想到的首先就是dp[i][j], 用了 i个箱子并且用了第j个箱子时能达到的最大高度。
状态如何转移呢?
如果第k个箱子的底面比第j个箱子大
dp[i][j] = max(dp[i][j], dp[i-1][k] + node[j].z);
node[j]表示第j个箱子,z是它的高
为了方便处理我们用x对箱子排序这样只用遍历之前的箱子,而不用遍历所有箱子。
初始化时node[0]代表地,所以x, y为INF, z 为0。
得到代码如下:
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #define long long ll #define INF 0x7fffffff using namespace std; struct Node{ int x, y, z; }node[200]; int dp[200][200]; void assignTo(int i, int x, int y, int z){ node[i].x = x; node[i].y = y; node[i].z = z; } bool cmp(Node a, Node b){ return a.x > b.x; } int main(){ #ifdef _LOCAL_ freopen("C:\\Users\\Sorie\\Desktop\\debug\\in.txt","r",stdin); freopen("C:\\Users\\Sorie\\Desktop\\debug\\out.txt","w",stdout); #endif int n; int kase = 1; while(cin >> n && n){ int cnt = 0; int x, y, z; node[0].x = node[0].y = INF; node[0].z = 0; memset(dp, 0 , sizeof dp); for(int i = 1; i <=n ; i++){ scanf("%d %d %d", &x, &y, &z); assignTo(++cnt, x, y, z); assignTo(++cnt, y, x, z); assignTo(++cnt, x, z, y); assignTo(++cnt, z, x, y); assignTo(++cnt, y, z, x); assignTo(++cnt, z, y, x); } sort(node + 1, node + cnt + 1, cmp); int ans = 0; for(int i = 1; i <= cnt; i++){ for(int j = i; j <= cnt; j++){ for(int k = i - 1; k <= j; k++){ if(node[j].x < node[k].x && node[j].y < node[k].y){ dp[i][j] = max(dp[i-1][k]+node[j].z, dp[i][j]); ans = max(ans, dp[i][j]); } } } } cout << "Case " << kase++ << ": maximum height = "; cout << ans << endl; } return 0; }
我们可以发现,每次只用了前一个状态,所以可以把dp降成一维
#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<algorithm> #define long long ll #define INF 0x7fffffff using namespace std; struct Node{ int x, y, z; }node[200]; int dp[200]; void assignTo(int i, int x, int y, int z){ node[i].x = x; node[i].y = y; node[i].z = z; } bool cmp(Node a, Node b){ return a.x > b.x; } int main(){ #ifdef _LOCAL_ freopen("C:\\Users\\Sorie\\Desktop\\debug\\in.txt","r",stdin); freopen("C:\\Users\\Sorie\\Desktop\\debug\\out.txt","w",stdout); #endif int n; int kase = 1; while(cin >> n && n){ int cnt = 0; int x, y, z; node[0].x = node[0].y = INF; node[0].z = 0; memset(dp, 0 , sizeof dp); for(int i = 8eb9 1; i <=n ; i++){ scanf("%d %d %d", &x, &y, &z); assignTo(++cnt, x, y, z); assignTo(++cnt, y, x, z); assignTo(++cnt, x, z, y); assignTo(++cnt, z, x, y); assignTo(++cnt, y, z, x); assignTo(++cnt, z, y, x); } sort(node + 1, node + cnt + 1, cmp); int ans = 0; for(int i = 1; i <= cnt; i++){ for(int j = i; j <= cnt; j++){ for(int k = i - 1; k < j; k++){ if(node[j].x < node[k].x && node[j].y < node[k].y){ dp[j] = max(dp[k]+node[j].z, dp[j]); ans = max(ans, dp[j]); } } } } cout << "Case " << kase++ << ": maximum height = "; cout << ans << endl; } return 0; }
欢迎指正, 以上
相关文章推荐
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 C - Monkey and Banana
- [kuangbin带你飞]专题十二 基础DP1 B - Ignatius and the Princess IV
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 B - Ignatius and the Princess IV
- [kuangbin带你飞]专题十二 基础DP1 -B - Ignatius and the Princess IV
- [kuangbin带你飞]专题十二 基础DP1 I - 最少拦截系统
- [kuangbin带你飞]专题十二 基础DP1 C HDU 1069
- [kuangbin带你飞]专题十二 基础DP1 I HDU 1257
- [kuangbin带你飞]专题十二 基础DP1 G HDU 1176
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 F - Piggy-Bank 【完全背包问题】
- [kuangbin带你飞]专题十二 基础DP1 L POJ 1458
- [kuangbin带你飞]专题十二 基础DP1 S POJ 3666
- 【算法系列学习】状压dp [kuangbin带你飞]专题十二 基础DP1 D - Doing Homework
- [kuangbin带你飞]专题十二 基础DP1 G - 免费馅饼
- [kuangbin带你飞]专题十二 基础DP1 E HDU 1087
- 【算法系列学习】[kuangbin带你飞]专题十二 基础DP1 E - Super Jumping! Jumping! Jumping!
- kuangbin带你飞 专题十二 基础DP1
- [kuangbin带你飞]专题十二 基础DP1 J HDU 1160
- 【算法系列学习】DP和滚动数组 [kuangbin带你飞]专题十二 基础DP1 A - Max Sum Plus Plus
- [kuangbin带你飞]专题十二 基础DP1 N POJ 2533
- [kuangbin带你飞]专题十二 基础DP1 R POJ 3616