链接http://acm.hdu.edu.cn/showproblem.php?pid=1160
感觉也是最长上升子序列的变形。。。
这回独立1Y!开心~ 不过在保存路径的时候调了一段时间orzzzzz还是太弱
思路:每个老鼠进行排序,将体重从小到大,若相等再将速度从大到小,保证找出最多的。
定义dp[i]表示以i为末尾的满足条件的最长的序列长度。运用最长上升子序列的那种方法就可以做了,还有要注意的是因为需要将其进行排序,排序后的序号是乱的,所以需要在结构体中加入一个记录原本路径的元素num。要保存路径,还要有一个记录上一个点的元素ls,并赋初值为-1。这样在dp[i]被更新的时候将ls 也更新。。最后记录以哪一个结尾是最大的,从这个节点找上去,并将每个节点都压入栈中,最后将栈内元素一个个输出就可以了。当然用数组也可以的。
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <stack>
using namespace std;
#define M 1009
#define INF 0x3f3f3f3f
int dp[M];
struct node
{
int w,s,num,ls;
}a[M];
int cmp(node a,node b)
{
if(a.w!=b.w) return a.w < b.w;
return a.s > b.s;
}
int main()
{
int n = 0;
while(scanf("%d %d",&a[n].w,&a[n].s)==2) //while(scanf("%d %d",&a[n].w,&a[n++].s)==2) 不要写成这样 因为这没有顺序
{
a[n].num = n; // 保存原本的序号 ,因为要排序所以会破坏
a[n].ls = -1;
n++;
}
sort(a,a+n,cmp);
//for(int i = 0;i < n;i++)
//printf("debug-- %d %d\n",a[i].w,a[i].s);
int ss;
int maxn = -INF;
for(int i = 0;i < n;i++)
{
dp[i] = 1;
for(int j = 0;j < i;j++)
{
if(a[i].w>a[j].w && a[i].s<a[j].s)
if(dp[i] < dp[j]+1)
{
dp[i] = dp[j]+1;
//int temp = a[i].num; //不要这样写,直接先用排序后的序号,最后统一转化成排序前的,一开始就转换容易混乱。。我就调了好久orzzzzz
a[i].ls = j;
/*int temp = a[i].num;
a[temp].ls = a[j].num;*/ //保存路径还可以写成/**/里的这样。。
}
}
if(maxn < dp[i])
{
maxn = dp[i];
ss = i;
/*ss = a[i].num;*/
}
}
printf("%d\n",maxn);
stack<int> st;
while(maxn--)
{
/*st.push(ss);*/
st.push(a[ss].num); //将原本的就是排序之前的序号压入栈
ss = a[ss].ls;
}
while(!st.empty())
{
int temp = st.top();
st.pop();
printf("%d\n",temp+1);
}
return 0;
}