动规,求非连续的单调递增的最长子序列的长度。
状态转移方程:d[i]=d[a]+1,如果num[a]<num[i]&&0<=a<=i,否则d[i]=1。一开始以为否则d[i]=d[i-1],这样在输出时是错误的,比如
6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200这组数据,输出结果少了一个数。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define MAXN 1010
using namespace std;
typedef struct elephant
{
int w,q,order;
} elephant;
int d[MAXN];
int cmp(const void *_a,const void *_b)
{
elephant *a=(elephant *)_a;
elephant *b=(elephant *)_b;
if(a->w==b->w)
return b->q-a->q;
else return b->w-a->w;
}
elephant ele[MAXN];
int find(int x,int y,int cur)
{
int flag=0,max=0,index=0;
for(int i=y; i>=x; i--)
{
if(ele[i].q<cur)
{
flag=1;
if(d[i]>max)
{
max=d[i];
index=i;
}
}
}
if(!flag) return -1;
else return index;
}
int main()
{
freopen("in.txt","r",stdin);
int n=0,m,index,max;
while(cin>>ele[n].w>>ele[n].q)
{
n++;
ele[n-1].order=n;
}
if(n==1)
{
cout<<"1"<<endl<<"1"<<endl;
return 0;
}
qsort(ele,n,sizeof(ele[0]),cmp);
memset(d,0,sizeof(d));
max=ele[0].q;
d[0]=1;
m=-0x7fffffff;
for(int i=1; i<n; i++)
{
int a=find(0,i-1,ele[i].q);
if(a<0)
//d[i]=d[i-1];
d[i]=1;
else
d[i]=d[a]+1;
if(d[i]>m)
{
m=d[i];
index=i;
}
}
cout<<m<<endl;
cout<<ele[index].order<<endl;
int num=m;
m=ele[index].q;
for(int j=index-1; j>=0; j--)
{
if(ele[j].q<m&&d[j]==num-1)
{
num--;
m=ele[j].q;
cout<<ele[j].order<<endl;
}
}
return 0;
}