问题:
马戏团表演跌人塔,要求上上面的人比下面的人矮且轻,给定所有人的身高体重,求塔的最大高度
示例:
输入(身高, 体重): (65, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68, 110)
输出: 最大高度:6
对于人塔为(从顶部到底部):(56, 90) (60,95) (65,100) (68,110) (70,150) (75,190)
解答:
类似于ACM HDOJ 1051
1. 对所有的人排序,先身高后体重
如:
Before sorting: (60, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68,110)
After sorting: (56, 90), (60, 95), (60,100), (68, 110), (70,150), (75,190)
2. Find the longest sequence which contains increasing heights and increasing weights
找到重量和身高递增的人并标记,有可能存在多组,求每组的长度并求最大值。
struct Person
{
int H,W; //表示Weight,Height;
Person():H(0),W(0){}
Person(int h, int w):H(h),W(w){}
};
bool operator<(const Person& lhs, const Person& rhs)
{
if(lhs.H == rhs.H) return lhs.W < rhs.W;
return lhs.H < rhs.H;
}
istream& operator>>(istream& in, Person& P)
{
in>>P.H>>P.W;
return in;
}
ostream& operator<<(ostream& out, const Person& P)
{
out<<'('<<P.H<<','<<P.W<<')';
return out;
}
int TowerHeight(Person* P, const int N, vector<Person>& ans)
{
sort(P, P+N);
int Height = 0,Count = 0;
bool used[N];
memset(used, 0, sizeof(used));
for(int i=0; i<N; ++i)
{
if(!used[i])//某人没使用
{
++Count;//Count用来表示递增组的数目
int h = 1;
vector<Person> tmp;
tmp.push_back(P[i]);
for(int j=i+1; j<N; ++j)
{
if(!used[j] && P[i]<P[j])
{
used[j] = true;
++h;
tmp.push_back(P[j]);
}
}
if(h>Height)
{
Height = h;
swap(ans, tmp);
}
}
}
return Height;
}
void TestTowerHeight()
{
int N = 6;
Person P[N];//{{65,100},{70,150},{56,90},{75,190},{70,95},{68,110}};
P[0].H = 65,P[0].W = 100;
P[1].H = 70,P[1].W = 150;
P[2].H = 56,P[2].W = 90;
P[3].H = 75,P[3].W = 190;
P[4].H = 60,P[4].W = 95;
P[5].H = 68,P[5].W = 110;
vector<Person> result;
int Height = TowerHeight(P, N, result);
cout<<"Max Height : "<<Height<<endl;
cout<<"Tower Routine(top -> bottom): "<<endl;
copy(result.begin(), result.end(), ostream_iterator<Person>(cout," "));
cout<<endl;
}