题意:
给一群大象,求重量递增,智商递减的最多的大象的个数。
分析:
类似于最长上升子序列,f [ i ] 表示让第 i 个大象做最后一个大象的满足条件的序列长度,
则 f [ i ] = max( f [ i ] , f [ j ] + 1 )( 0 < j < i , 第 i 个大象比第 j 个重,智商低 )。
关于路径,我们记录最长序列的最后一个大象的编号,然后从他开始递归打印即可。
代码:
#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
const int maxn = 1e6;
int dp[maxn], road[maxn], Max;
struct Ele
{
int w, s, id;
bool operator < (const Ele& a) const
{
if(w != a.w) //先按重量升序排列
return w < a.w;
return s > a.w; //重量相等则按智商降序排列
}
} E[maxn];
void print(int x) //递归打印路径
{
if(Max--)
{
print(road[x]);
printf("%d\n", E[x].id + 1);
}
}
int main()
{
int sum = 0;
while(~scanf("%d%d", &E[sum].w, &E[sum].s))
{
E[sum].id = sum;
sum++;
}
sort(E, E + sum);
int End = 0;
for(int i = 0; i < sum; i++)
{
dp[i] = 1;
for(int j = 0; j < i; j++)
{
if(E[i].w > E[j].w && E[i].s < E[j].s && dp[j] + 1 > dp[i])
{
dp[i] = dp[j] + 1;
road[i] = j; //记录路径,第 i 个由第 j 个转移而来
}
}
if(dp[i] > Max)
{
Max = dp[i];
End = i;
}
}
cout << Max << endl;
print(End);
return 0;
}