题目链接:
https://www.luogu.org/problemnew/solution/P1020
基本思路:
首先第一问是一个求最长下降子序列的问题,但是不能用传统的方法,因为会超时。还有个比较蛋疼的地方就是输入的时候,没有指定输入数据的个数,这个我也不会 ,看了题解才知道那么输入的。首先,基本的思路还是和传统的求最长上升(下降)子序列一样的,都是求以i为结尾的最长上升(下降)子序列,但是第2重循环可就大大不一样的,传统的是依次枚举以(1~~i-1)上的数为结尾的最长上升(下降)子序列,如果满足a[i]<a[j]或者a[i]>a[j],就执行dp[i]=max(dp[i],dp[j]+1);最终找出dp数组中最大的一个,就是结果。这是传统的解法。但是此题的第二重循环是依次枚举前i-1个数中所求得的递增(递减)子序列的长度(注意:是从最长的到最短的这个顺序开始枚举的 这很关键)
最终找到dp数组中的最大值,输出即可
代码如下:
#include<bits/stdc++.h>
using namespace std;
int visited[150000];//动归用的数组
int a[150000];
int t=0;//t表示当前所得到的最长上升子序列或最长下降子序列的长度
int z=0;//数据大小
int d1[150000],d2[150000];//d1[i],d2[i]表示子序列长度为i时上升(下降)子序列的最后一个元素在数组中的下标
int main()
{
while(~scanf("%d",&a[++z]));//学到的新知识,对于不给定输入个数的数据的输入可以这样输入,也可以不等于EOF的那样输入
z--;
for(int i=1;i<=z;i++)//从这一行到25行是求的最长递减子序列(全新的方法,以前根本没用过,涨姿势了)
{