题目卡了好久,题目大概意思是给你未知数量的老鼠的体重和速度,让我们找出最长的序列,序列满足老鼠体重增加,速度减小,其实就是先对体重排序 ,然就问题就成了最大递增子串
对于输入有一个小技巧, 也不能说是技巧, 就是告诉你未知数量的数据 用Ctrl➕z结束输入 以前是知道的,好就没敲就忘记了,
可以把这题的DP时候的代码看做是最大递增子串的模版了
平常的最大递增子串是只要能够输出一个最大或者最小的值就行了,但是这道题还要输出满足符合条件的按顺序的老鼠,这边我自己是用了一个front数组 存这只老鼠的上一只老鼠是哪一只。然后递归找到最上面的老鼠,回溯打印。
最大递增自串的意思就是,给你一个序列,这个序列是乱序的例如{1,7,4,5,7,9,2,3} 要你从中找出如增的子序列,
{1,7(第一个)}就是一个递增子序列,{1,4,5}(中间可以略过数字,这个序列略过了7) 也是一个子序列,
这个序列最大的子序列是{1,4,5,9}共4个数字。
解这种题的思路是用一个dp数组, dp[i]表示第i个元素的最长子序列,然后第i+1个元素就是要去判断是否大于第i个元素,是的话就可以让dp[i+1]==dp[i]+1,但是不一定只要dp第i+1个元素大于第i个就一定是在第i个元素时的最大子序列,可以是0~i中的任意一个,取最大值,用两层循环来实现,具体可以看下面代码
#include <set>
#include <queue>
#include<algorithm>
#include <iostream>
#include<string.h>
#include<map>
#include<stack>
#include<string>
#include <stdio.h>
#include<math.h>
#include <cstring>
using namespace std;
struct node {
int weight;
int speed;
int num;
};
int front[10010];
node s[10010];
bool cmp(node a,node b){
return a.weight<b.weight;
}
void print(int n){
if(front[n]!=-1)
print(front[n]);
cout<<s[n].num+1<<endl;
}
int main()
{ int k=0;
memset(front,-1,sizeof(front));
while(scanf("%d%d",&s[k].weight,&s[k].speed)!=EOF)
{
s[k].num=k;
k+=1;
}
sort(s,s+k,cmp);
/* for(int i=0;i<k;i++){
cout<<s[i].weight<<" "<<s[i].speed<<" "<<s[i].num+1<<endl;
}*/
int max=1;
int max_num=0;
int dp[10010]={0};
for(int i=0;i<k;i++){
dp[i]=1;//每只老鼠开始都要先包括自己在内。
for(int j=0;j<i;j++){
if(s[i].weight>s[j].weight&&s[i].speed<s[j].speed){
if(dp[i]<dp[j]+1){
dp[i]=dp[j]+1;
front[i]=j;//记录一下这只老鼠的上一只是谁。
if(max<dp[i]){
max=dp[i];
max_num=i;
}
}
}
}
}
/* for(int i=0;i<k;i++){
cout<<s[i].weight<<" "<<s[i].speed<<" "<<s[i].num+1<<" ";
cout<<dp[i]<<" "<< s[front[i]].num+1<<" ";
cout<<front[i]<<endl;
}
*/
cout<<max<<endl;
//cout<<max_num<<endl;
print(max_num);
return 0;
}