HDOJ1069 猴子和香蕉【DP】
2013-08-02 00:27
513 查看
题目详见http://acm.hdu.edu.cn/showproblem.php?pid=1069 这个题目的大致意思就是香蕉挂在一定的一定的高度,不同的高度都有香蕉。给猴子很N个箱子,有长宽高,让猴子用这些箱子摞在一起爬到高处吃香蕉,看猴子的智商够不够高,吃到的香蕉多不多。箱子可以翻转,但是一个箱子要想摞在其他箱子上边,必须满足长和宽都要小于底下的箱子。箱子的数目是不限的,只是给出不同的箱子种类。每种箱子可以多次使用。 看到这里,想必对此题有了大致的了解了。箱子虽然无限,但是总类有限。所以每一种箱子,最多只能用3次。因为有长宽的限制,所以只能这样。 怎么做呢? 对于输入的箱子我们怎么保存,长宽高可以调换。虽然无限,每种箱子最多只用3次。而且这三次还有重复的。比如 5 5 6 ,那么翻转一下变成 5 5 6 ,5 6 5 ,5 6 5。5 5 5 变成3个 5 5 5 .可以进行重复的处理,可是我这里就没处理,觉得无伤大雅。不过这是不严谨的态度,要向好的复杂度看齐。如果所有的都是正方体,岂不是浪费了2/3的时间和内存啊。不过在这刷题呢就没在乎这么多,先不管了。。以后再实现。存入3N的数据,数据显然要用结构体来处理。
typedef struct Block { int width; int length; int height; }Block;
存入数据之后怎么办? 首先要排序,不排序是没法搞的。怎么排序?按面积?长度,高度?在这里我们以长度为主排序,如果长度相同,那么以高度为主。而且这里要处理长和宽,如果长小于宽,要调换的。因为这会影响排序的。比如 1 10 100,长度是1,肯定排到最后了,可是宽是10,高度是100啊。这就很坑里。所以要长宽符合,拍好序。有人说用面积,我觉得应该也可以,或许会更好,可是比较蛮烦一些。这里就用刚才说的处理,排序用的是从大到小,一点一点的往上堆。 排序之后呢?这个题要用动态规划,这个DP和之前的最长递增子序列有点类似。这个DP的每一项和之前的每一个都有关系,不是仅仅是和前一个有关系。定义Height[i]是前i个箱子可以堆成的最大高度。 我们得到的状态转移方程
Height[i]=MAX{block[i].height,block[i].block+Height[j]} block[i].block+Height[j]>Height[i] 0<=j<=i-1;。对底下的每一个都要判断一下是否可以放在上面,还有比较高度,更新高度。这样才可以可以解决问题。
上代码
#include <iostream>OK,很nice的AC了。继续刷题啦啦啦
#include<algorithm>
#include<vector>
using namespace std;
typedef struct Block { int width; int length; int height; }Block;
int MaxBlockHeight(vector<Block> block,int n); //求所有的的箱子堆的最大高度。
int MaxToMin(const Block& a ,const Block& b);//从大到小排序,以长为主,宽为辅
void Adjust(Block &a);//调整宽度和长度的位置
int main()
{
int n;
Block a,b,c; //没每一类处理3个箱子
vector<Block> block;
int i,j;
j=0;
while(cin>>n)
{
if(0==n)
break;
i=n;
block.clear(); //不忘记清零
while(i--)
{
cin>>b.width;
cin>>b.length;
cin>>b.height;
a.width=b.width;
a.length=b.height;
a.height=b.length;
c.width=b.length;
c.length=b.height;
c.height=b.width;
Adjust(a);
Adjust(b);
Adjust(c);
block.push_back(b);
block.push_back(a);
block.push_back(c);
}
//for_each(block.begin(),block.end(),show);
sort(block.begin(),block.end(),MaxToMin);//排序
// for_each(block.begin(),block.end(),show);
cout<<"Case "<<++j<<": maximum height = "<<MaxBlockHeight(block,n)<<endl
}
return 0;
}
//求所有的的箱子堆的最大高度。
int MaxBlockHeight(vector<Block> block,int n)
{
int Max=0; //初始化
int *height=new int[3*n];
int i,j;
for(i=0;i<3*n;i++)
{
height[i]=block[i].height;
for(j=i-1;j>=0;j--)
{
if((block[i].width<block[j].width)&&(block[i].length<block[j].length)&&(block[i].height+height[j]>height[i]))
{
height[i]=block[i].height+height[j];
//break;不可以这么做。
}
}
if(height[i]>Max)
Max=height[i];
}
return Max;
}
//从大到小排序,以长为主,宽为辅
int MaxToMin(const Block& a ,const Block& b)
{
if(a.length>b.length)
return true;
else if(a.length==b.length&&a.width>=b.width)
return true;
else
return false;
}
void Adjust(Block &a)//调整宽度和长度的位置
{
int temp;
if(a.width>a.length)
{
temp=a.width;
a.width=a.length;
a.length=temp;
}
}
转载请注明出处http://blog.csdn.net/liangbopirates/article/details/9709113
相关文章推荐
- HDOJ1069 猴子和香蕉——输出的格式很重要_耀晨SYW
- HDOJ 1069 Monkey and Banana 【DP】
- hdoj1069 Monkey and Banana(DP)
- HDOJ 1069(经典Dp)
- HDOJ 1069 Monkey and Banana(DP)
- HDOJ1069-Monkey and Banana(DP)
- 1134:猴子与香蕉 dp
- HDOJ1069 Monkey and Banana(DP,LIS)
- hdoj--1069 Monkey and Banana(dp)
- dp专题:猴子与香蕉
- DP水题练习——HDOJ 2391 HDOJ1069 HDOJ 2512
- hdoj 1069 Monkey and Banana 【DP】
- HDOJ 1069 DP
- 猴子放箱子吃香蕉题(Problem ID:1069)
- hdoj 1069 Monkey and Banana【dp】
- HDOJ1069 Monkey and Banana【dp】
- [HDOJ1069]Monkey and Banana(DP)
- hdoj1069_Monkey and Banana(dp)
- hdoj1069 //升序dp
- hdoj1024 Max Sum Plus Plus (DP)