第一问:经典最长上升子序列问题
第二问:贪心(正确性证明:调整法)
从前往后依次遍历每一个序列中的元素,会有两种选择,如果现有子序列的结尾都小于当前数,则创建一个新序列;要么就把当前数放在结尾小于且最接近当前数的子序列的后面。
#include<bits/stdc++.h>
using namespace std;
const int N = 1010;
int a[N];
int dp[N];
vector<int> arr;
int main(){
int n=0;
while(cin>>a[n]){
n++;
}
int res=0;
for(int i=n-1;i>=0;i--){
dp[i]=1;
for(int j=n-1;j>i;j--){
if(a[i]>=a[j]){
dp[i]=max(dp[i],dp[j]+1);
}
}
res=max(res,dp[i]);
}
cout<<res<<endl;
for(int i=0;i<n;i++){
if(arr.size()==0){
arr.push_back(a[i]);
continue;
}
vector<int>::iterator iter=lower_bound(arr.begin(),arr.end(),a[i]);
if(iter==arr.end()){
arr.push_back(a[i]);
}
else{
*iter=a[i];
}
}
cout<<arr.size();
return 0;
}