最长上升子序列
思路:
题目要求找到最长上升的子序列,那么这个时候,我们可以假以第i个为结尾,那么此时以i为结尾的最大上升子序列是多少。但是这个时候,会发现,从第i个为结尾往前面找的话,是一个一个遍历的,也就是说时间复杂度是n*n,如果数据范围很大,那么就不能用了,不过好在这题n只到1000
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<stack>
#include<string>
#include<algorithm>
#include<unordered_map>
#include<map>
#include<cstring>
#include <unordered_set>
//#include<priority_queue>
#include<queue>
#include<set>
#include<stdlib.h>
#define dbug cout<<"hear!"<<endl;
#define rep(a,b,c) for(ll a=b;a<=c;a++)
#define per(a,b,c) for(ll a=b;a>=c;a--)
#define no cout<<"NO"<<endl;
#define yes cout<<"YES"<<endl;
#define endl "\n"
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//priority_queue<int,vector<int>,greater<int> >q;
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> PII;
typedef pair<long double,long double> PDD;
ll INF = 0x3f3f3f3f;
//const ll LINF=LLONG_MAX;
// int get_len(int x1,int y1,int x2,int y2)
// {
// return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
// }
const ll N = 2e6+ 10;
const ll mod =1000000007;
ll t,n,m,x,y,ca;
ll arr[N],brr[N],crr[N];
// int h[N],ne[N],e[N],w[N],idx;
ll dp[1500];
void solve()
{
cin >> n;
rep(i,1,n)cin>> arr[i];
rep(i,1,n)
{
dp[i] = 1;
rep(j,1,i-1)
{
if(arr[i] > arr[j])
{
dp[i] = max( dp[i], dp[j] + 1);
}
}
}
ll ans = -1;
rep(i,1,n)ans = max( ans, dp[i]);
cout<<ans<<endl;
}
int main()
{
IOS;
t=1;
//scanf("%d",&t);
//cin>>t;
ca=1;
while(t--)
{
solve();
ca++;
}
return 0;
}
最长上升子序列 II
思路:
显而易见,与上面不同也就是n的范围了,那么这个时候1e5 * 1e5 肯定超1s秒,所以我们得换方法做
想一想,原来的方法是,以i结尾的时候当前最长上升子序列是多长。然后i在挨个往后遍历。
假设,如果一个数字 放在3 和 1 后面 ,都是可以构成上升序列的,那么这个时候,我们应该选1,因为这样区间会更大,万一来个2,3必须得放前面了,而1还是可以往后塞(大概就这个意思,就是区间更大)而此时的dp数组存的就是当前len长度下的最后一个数字是多少了,这样子而分的就是找到第一个小于等于这个数字对应的长度,然后给这个数字塞进去
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<stack>
#include<string>
#include<algorithm>
#include<unordered_map>
#include<map>
#include<cstring>
#include <unordered_set>
//#include<priority_queue>
#include<queue>
#include<set>
#include<stdlib.h>
#define dbug cout<<"hear!"<<endl;
#define rep(a,b,c) for(ll a=b;a<=c;a++)
#define per(a,b,c) for(ll a=b;a>=c;a--)
#define no cout<<"NO"<<endl;
#define yes cout<<"YES"<<endl;
#define endl "\n"
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//priority_queue<int,vector<int>,greater<int> >q;
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> PII;
typedef pair<long double,long double> PDD;
ll INF = 0x3f3f3f3f;
//const ll LINF=LLONG_MAX;
// int get_len(int x1,int y1,int x2,int y2)
// {
// return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);
// }
const ll N = 2e6+ 10;
const ll mod =1000000007;
ll t,n,m,x,y,ca;
ll arr[N],brr[N],crr[N];
// int h[N],ne[N],e[N],w[N],idx;
ll dp[N];
void solve()
{
scanf("%lld",&n);
rep(i,1,n)scanf("%lld",&arr[i]);
ll ans = 0;
dp[0] = -2e9;
rep(i,1,n)
{
ll l = 0 ,r = ans;
while(l < r)
{
ll mid = l + r + 1 >> 1;
if(dp[mid] < arr[i]) l = mid;
else r = mid - 1;
}
ans = max( ans, r + 1);
dp[r + 1] = arr[i];
}
printf("%lld",ans);
}
int main()
{
IOS;
t=1;
//scanf("%d",&t);
//cin>>t;
ca=1;
while(t--)
{
solve();
ca++;
}
return 0;
}