HDU 1160
FatMouse's Speed
这是最长上升子序列问题向二维的一个扩展变形
设Mice[i].W表示第i只老鼠的重量,Mice[i].S表示第i只老鼠的速度。我们先对Mice进行排序,以W为第一关键字,从小到大,S为第二关键字,从大到小设f[i]为Mice[i]至Mice[n]最长的序列长度。考虑某一个f[i],则有: f[i] = max(f[i], f[j]+1) (1<=j<i,且Mice[i].W> Mice[j].W,Mice[i].S < Mice[j].S) 其中,初始条件为f[i]=1 (i=1, 2, ..., n)。
#include<iostream>
using namespace std;
typedef struct p
{
int weight;
int speed;
int num; //num是原来的次序
int pre;
}Mouse;
void sort(Mouse m[],int n) //升序
{
int i,j,k;
Mouse temp;
for(i=1;i<=n;i++)
{
k=i;
for(j=i+1;j<=n;j++)
{
if(m[j].weight<m[k].weight)
k=j;
else if(m[j].weight==m[k].weight&&m[j].speed>m[k].speed)
k=j;
}
if(k!=i)
{
temp=m[k];
m[k]=m[i];
m[i]=temp;
}
}
}
int main()
{
int i=1,j,n=1,data[1001],a,b;
int f[1001];
Mouse m[1001];
while(cin>>a>>b)
{
m[n].num = n; //原来的次序
m[n].weight = a;
m[n].speed = b;
n++;
}
sort(m,n-1);
f[1]=1; a=1; b=1; m[1].pre=1;
for(i = 2; i < n; i++)
{
f[i]=1; m[i].pre=i; //最开始时每个的前面都是自己,序列个数都为1
for(j=1; j<i;j++)
if(m[i].weight>m[j].weight&&m[i].speed<m[j].speed&&f[j] + 1 >f[i]) //满足条件的
{
f[i]=f[j]+1;
m[i].pre=j; //i的前者赋为j
}
if(f[i]>a) //找出最大的值赋给a,同时把最大值的下标i赋给b
{
a=f[i];
b=i;
}
}
cout<<a<<endl;
i=0;
while(f[b]+1) //当f[b]==1时,m[b].pre=b,f[b]--至-1跳出循环,data[i]已经达到a了,此后的值无意义,
{
data[i]=m[b].num;
b=m[b].pre; //把m[b]的前者赋给b来循环
i++;
f[b]--;
}
for(i=a-1;i>=0;i--)
cout<<data[i]<<endl;
return 0;
}