HDU-1069.MonkeyandBanana(LIS)
本题大意:给出n个长方体,每种长方体不限量,让你求出如何摆放长方体使得最后得到的总高最大,摆设要求为,底层的长严格大于下层的长,底层的宽严格大于下层的宽。
本题思路:一开始没有啥思路...首先应该想到如果数组内的长宽等都是乱序的话会很影响计算的效率,所以我们先进行排序,对于每种长方体,我们将其三种摆放方式存入数组,然后利用sort排序,
我们会得到一个按照长度递增,长度相等则按照宽度递增的顺序摆放,最后很明显就可以得出状态转移方程:dp[ i ] = max(dp[ j ]) + a[ i ]. h;
参考代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //2019.3.28 2 //用dp[i]表示前i个长方体的最优解 dp[i] = max(dp[j] + a[j].h)(j < i); 3 //无序就手动构造有序,呜呜呜~~~ 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = (30 + 5) * 3; 9 int n, Case = 0, num, max_h; 10 struct node { 11 int l, c, h; 12 } a[maxn]; 13 int dp[maxn]; 14 15 bool cmp(const node a, const node b) { 16 if(a.l == b.l) return a.c < b.c; 17 return a.l < b.l; 18 } 19 20 int main () { 21 int z1, z2, z3; 22 while(cin >> n && n) { 23 num = 0;//记录可变换长方体的总个数 24 for(int i = 0; i < n; i ++) { 25 cin >> z1 >> z2 >> z3; 26 a[num].h = z1, a[num]. l = z2 > z3 ? z2 : z3, a[num ++].c = z2 < z3 ? z2 : z3; 27 a[num].h = z2, a[num]. l = z1 > z3 ? z1 : z3, a[num ++].c = z1 < z3 ? z1 : z3; 28 a[num].h = z3, a[num]. l = z1 > z2 ? z1 : z2, a[num ++].c = z1 < z2 ? z1 : z2; 29 } 30 sort(a, a + num, cmp); 31 dp[0] = a[0].h; 32 for(int i = 1; i < num; i ++) { 33 max_h = 0; 34 for(int j = 0; j < i; j ++) { 35 if(a[j].l < a[i].l && a[j].c < a[i].c) 36 max_h = max_h > dp[j] ? max_h : dp[j]; 37 } 38 dp[i] = a[i].h + max_h; 39 } 40 cout << "Case " << ++ Case << ": maximum height = " << *max_element(dp, dp + num) << endl; 41 } 42 return 0; 43 }
这里本弱用到了一个经常不用的函数*max_element,大家可以遍历一遍数组找最大值也可以。
时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面……
没有谁生来就是神牛,而千里之行,始于足下!