题目链接:The Heaviest Non-decreasing Subsequence Problem
思路:因为是找非递减子序列,所以如果数b的权值是a,可以当成a个数b连续排列在数组中。然后找最长非递减子序列的长度即可,下列代码LNDS()函数也可以作为最长非递减子序列的模板使用,时间复杂度nlog2(n)。
#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define Max(a,b) a>b?a:b
#define Min(a,b) a>b?b:a
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
int dir[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
const double eps = 1e-6;
const double Pi = acos(-1.0);
const int INF=0x3f3f3f3f;
const int maxn = 1e6+10;
int arr[maxn],dp[maxn];
int n,ans;
int Find(int tag){
int l = 1, r = ans, mid;
while(l <= r){
mid = (l + r) / 2;
if(tag >= dp[mid]) l = mid + 1;
else r = mid - 1;
}
return l;
}
void LNDS(){
int p;
mem(dp,INF);
ans = 0;
dp[0] = 0;
for(int i = 1; i < n; i++){
p = Find(arr[i]);
if(p > ans) ans++;
dp[p] = Min(dp[p],arr[i]);
}
}
int main(){
int x;
n = 1;
mem(arr,0);
while(scanf("%d",&x) != EOF){
if(x >= 0){
if(x >= 10000){
arr[n++] = x - 10000;
arr[n++] = x - 10000;
arr[n++] = x - 10000;
arr[n++] = x - 10000;
arr[n++] = x - 10000;
}else{
arr[n++] = x;
}
}
}
LNDS();
printf("%d\n",ans);
}