• [每日一题]: 最长上升子序列 AND 最长不上升子序列


    关于知识点的讲解:

    最长上升子序列讲解及二分优化

    例题:

    最长上升子序列题目链接:

    Bridging signals

    普通版本:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1005;
    
    int dp[maxn];
    
    int a[maxn];
    
    int n;
    
    int main(void) {
    	scanf("%d",&n);
    	for(int i = 1; i <= n; i ++) {
    		scanf("%d",&a[i]);
    	}
    	int ans = 0;
    	for(int i = 1;  i <= n; i ++) {
    		dp[i] = 1;
    		for(int j = 1; j < i; j ++) {
    			if(a[i] > a[j]) {
    				dp[i] = max(dp[j] + 1,dp[i]);
    			}
    		}
    	}
    	for(int i = 1; i <= n; i ++) {
    		ans = max(ans,dp[i]);
    	}
    	cout << ans << endl;
    	return 0;
    } 
    

    二分优化:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1e5 + 10;
    
    int dp[maxn],a[maxn];
    
    int low[maxn];
    
    int n,cnt = 1;
    
    int serch(int x) {
    	int l = 1, r = cnt;
    	while(l < r) {
    		int mid = l + r >> 1;
    		if(low[mid] >= x) r = mid;
    		else l = mid + 1;
    	}
    	return r;
    }
    
    int main(void) {
    	scanf("%d",&n);
    	for(int i = 1; i <= n; i ++) {
    		scanf("%d",&a[i]);
    	}
    	memset(low,0x3f,sizeof(low));
    	low[1] = a[1];
    	for(int i = 1; i <= n; i ++) {
    		if(a[i] > low[cnt]) low[ ++ cnt] = a[i];
    		else {
    			int pos = serch(a[i]);
    			low[pos] = a[i];
    		}
    	}
    	printf("%d
    ",cnt);
    	return 0;
    }
    

    最长不上升子序列例题:

    小明爱拦截

    侃侃:

      这个题是在最长上升子序列版本上的改动,如果最长上升子序列搞懂了,
      这个应该不难。
    

    普通版:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1e5 + 10;
    
    int dp[maxn],a[maxn];
    
    int n;
    
    int main(void) {
    	scanf("%d",&n);
    	for(int i = 1; i <= n; i ++) {
    		scanf("%d",&a[i]);
    	}	
    	for(int i = 1; i <= n; i ++) {
    		dp[i] = 1;
    		for(int j = 1; j < i; j ++) {
    			if(a[j] >= a[i]) {
    				dp[i] = max(dp[i],dp[j] + 1);
    			}
    		}
    	}
    	int res = 0;
    	for(int i = 1; i <= n; i ++) {
    		res = max(res,dp[i]);
    	}
    	cout << res << endl;
    	return 0;
    } 
    

    二分优化:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int maxn = 1e5 + 10;
    
    int dp[maxn],a[maxn];
    
    int low[maxn];
    
    int n,cnt = 1;
    
    int serch(int x) {
    	int l = 1,r = cnt;
    	while(l < r) {
    		int mid = (l + r )>> 1;
    		if(low[mid] < x) r = mid;
    		else l = mid + 1;
    	}
    	return r;
    }
    
    int main(void) {
    	scanf("%d",&n);
    	for(int i = 1; i <= n; i ++) {
    		scanf("%d",&a[i]);
    	}
    	memset(low,0x3f,sizeof(low));
    	low[1] = a[1];
    	for(int i = 2; i <= n; i ++) {
    		if(a[i] <= low[cnt]) {
    			low[++ cnt] = a[i];
    		} else {
    			int pos = serch(a[i]);
    			low[pos] = a[i];
    		}
    	}
    	printf("%d
    ",cnt);
    	return 0;
    }
    
  • 相关阅读:
    向企业一样的思考
    在CentOS上搭建WordPress的博客系统
    DirectoryEntry所有字段对应解释
    Oracle11gSGA调整方法
    Oracle之内存结构(SGA、PGA)
    C# 打开指定目录并定位到文件
    C# 客户端读取共享目录文件
    谈30岁后it人员职业发展规划
    常用HTTP contentType与后端处理方式
    C# worksheet设置Excel样式
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12838690.html
Copyright © 2020-2023  润新知