Problem Description
给你若干个,老鼠的数据,数据里面有两个,一个是体重,一个是速度,让你求出最长的子序列,按照体重不断的减少,速度不断的增加。
思路:
我们按照速度从大到小排序,就变成了求体重最长上升子序列了。状态转移方程dp[i] = max{dp[0]…..dp[i - 1]}(满足上升条件) + 1.
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
struct node
{
int w, v, num;
bool operator < (const node &b) const {
if(v == b.v) return w < b.w;
else return v > b.v;
}
};
node a[1505];
int dp[1505], Pre[1505];
void print(int u)
{
if(!u) return;
print(Pre[u]);
printf("%d\n", a[u].num);
}
int main()
{
memset(Pre, 0, sizeof(Pre));
int w, v, n = 1, jj;
while(~scanf("%d %d", &w, &v))
{
a[n].num = n;
a[n].w = w;
a[n++].v = v;
}
sort(a + 1, a + n + 1);//按照速度从大到小排序,如果速度相同体重从小到大排序
int Max, u, ans = 0;
for(int i = 1; i <= n; i++)//求最长上升子序列 && 记录路径
{
dp[i] = 1;
Max = 0;
for(int j = i - 1; j >= 1; j--)//1 - (i - 1)找最大的dp[]满足上升条件
{
if(a[i].w > a[j].w)//满足条件
{
if(Max < dp[j]){
u = j;
Max = dp[j];
}
}
}
if(Max)//找到了,更新,顺便记录路径
{
if(dp[u] + 1 > dp[i]){
dp[i] = dp[u] + 1;
Pre[i] = u;
}
}
ans = max(ans, dp[i]);
}
printf("%d\n", ans);
for(jj = 1; jj <= n; jj++)//输出路径
{
if(dp[jj] == ans)
{
print(jj);
break;
}
}
return 0;
}