题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1160
题意:给出n个老鼠的重量和速度值(先重量后速度),要求给出一个最长的排列,其中,前一只老鼠的重量严格小于后一只老鼠,而它的速度要严格大于后一只老鼠。排列可能有多种,只要求出一种就可以了。
思路:排序后转化为最长上升子列。
忽略了可能有多种正确排列,白白调试好久……
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
struct Point
{
int w,s,id;
bool operator < (const Point& _P) const //用于sort排序
{
if (w == _P.w)
return s>_P.s;
return w<_P.w;
};
bool operator > (const Point& _P) const //严格大于,用于dp
{
return w>_P.w && s<_P.s;
};
}temp;
int dp[1005],pre[1005];
vector <Point> v;
void Output (int x)
{
if (x==-1)
return;
Output (pre[x]);
printf ("%d\n",v[x-1].id);
}
int main ()
{
#ifdef ONLINE_JUDGE
#else
freopen("read.txt","r",stdin);
#endif
int w,s,id=1;
while (~scanf("%d%d",&w,&s))
{
temp.w=w;
temp.s=s;
temp.id=id++;
v.push_back (temp);
}
int n=v.size();
sort (v.begin(),v.end());
memset (pre,-1,sizeof(pre));
int i;
for (i=1;i<=n;i++)
{
dp[i]=1;
for (int j=1;j<i;j++)
if (v[i-1]>v[j-1] && dp[j]+1>dp[i])
{
dp[i]=dp[j]+1;
pre[i]=j;
}
}
int ans=0,k;
for (i=1;i<=n;i++)
if (ans<dp[i])
{
ans=dp[i];
k=i;
}
printf("%d\n",ans);
Output(k);
return 0;
}
/*
Sample Input
6008 1300
6000 2100
500 2000
1000 4000
1100 3000
6000 2000
8000 1400
6000 1200
2000 1900
Sample Output
4
4
5
9
7 我的算法这里输出的是8
*/