【HDU】1069 Monkey and Banana

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

很好的DP题目!

初看到的时候没有感觉,除了蒙……

经过merlininice师父的分析,醍醐灌顶啊!!! 同时也更清晰的明白了将问题转化的重要性。(千万不要做个直脑筋的人那,肯定会被坑死的!)

分析:

依题目要求,砖块的任意一个面都能作为底面,垫在下方的底面的长和宽都必须严格大于上面的底面的长和宽。要求求出最高的高度。

如果没有红色字体的要求,这个问题可能就会比较容易处理:很明显,只要先将所有的砖块按其长(或者宽)进行升序排序,接着处理宽值,那么问题就转化为LISLongest Increasing Subsequence)最长上升子序列或者 最长不下降子序列的问题了。

但是增加了红色字体的要求,困难点在于究竟要如何选择一块砖的3条边作为长、宽、高呢?(我最初的疑惑点)… … …

merlininice师父只是淡淡说了一句:那你就把一块砖当3块砖来用,3块砖固定长、宽、高,然后按照刚才的思路处理问题。

 

于是于是,继2次wa(小问题、大问题不断啊!求1Y啊~~)

又要用我的 “ 自我牺牲 ” 来警戒大家了:

qsort(q,cur,sizeof(q[0]),cmp);
memset(dp,0,sizeof(dp));   --->错误点!dp的初始值不能等于零!展开分析:最优解有可能不是以dp[0]为首展开的!所以所有的dp[i]都应该初始化为相应的q[i].h~~ 在LIS问题中dp[]数组的初始化往往都是对应的值,而不是0!

dp[0] = q[0].h;
int max = 0;
for(i=0; i<cur; ++i){
// cout<<q[i].x<<" "<<q[i].y<<endl;
for(j=0; j<i; ++j){
if(q[i].y<q[j].y) dp[i] = dp[i] > dp[j]+q[i].h ? dp[i] : dp[j]+q[i].h;

}
max = max > dp[i] ? max : dp[i];
}

 

恩,2次wa提交的居然是一样的代码…… = =

 

接下来就看代码吧~

在输入的时候将砖块拆分成3个固定长、宽、高的砖块。

Input
 1 int cur = 0;
 2             for(i=0; i<n; ++i) {
 3                 scanf("%d %d %d",&a,&b,&c);
 4                 q[cur].x = a>b ? a: b;
 5                 q[cur].y = a>b ? b: a;
 6                 q[cur].h = c;
 7                 cur ++;
 8                 q[cur].x = c>b ? c: b;
 9                 q[cur].y = c>b ? b: c;
10                 q[cur].h = a;
11                 cur ++;
12                 q[cur].x = a>c ? a: c;
13                 q[cur].y = a>c ? c: a;
14                 q[cur].h = b;
15                 cur ++;
16             }

处理好上面的问题后就是先对x、y的某个进行升序排序后,进行O(n^n)的LIS的处理。

View Code
 1             qsort(q,cur,sizeof(q[0]),cmp);
 2 
 3             int max = 0;
 4             for(i=0; i<cur; ++i){
 5                 dp[i]=q[i].h;
 6                   for(j=0; j<i; ++j){
 7                         if(q[i].y<q[j].y && q[i].x<q[j].x) dp[i] = dp[i] > dp[j]+q[i].h ? dp[i] : dp[j]+q[i].h;
 8                   }
 9                   max = max > dp[i] ? max : dp[i];
10             }
11             printf("Case %d: maximum height = %d\n",++k, max);
posted on 2012-07-21 19:35  Yuna_  阅读(123)  评论(0)    收藏  举报