最长不下降子序列 (upper_bound)

题目:

You are given an array of positive integers a1, a2, ..., an × T of length n × T. We know that for any i > n it is true that ai = ai - n. Find the length of the longest non-decreasing sequence of the given array.

Input

The first line contains two space-separated integers: nT (1 ≤ n ≤ 100, 1 ≤ T ≤ 107). The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 300).

Output

Print a single number — the length of a sought sequence.

Examples

Input

4 3
3 1 4 2

Output

5

Note

The array given in the sample looks like that: 3, 1, 4, 2, 3, 1, 4, 2, 3, 1, 4, 2. The elements in bold form the largest non-decreasing subsequence.

分析:

刚开始做这题的时候,因为t太多,所以我一开始觉得暴力过不了。后来想想,数组里的数最大才100个。也就是这个最优长度应该不会超多100*(t-1)。另外学习到可以用upper_bound求最长不下降子序列。

upper_bound每次在数列中找它最该放置的位置,若这个位置可以接在当前最优的队伍后面则长度++,有点类似于贪心模拟的思想。主要是代码简洁了许多,get。(#^.^#)

代码:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<map>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1e4 + 10;
int a[120],num[maxn],b[310]={0};
int maxcnt=0,cnt=0;
int dp[maxn];
int main() {
    int n,k;
    while(scanf("%d %d",&n,&k)!=EOF)
    {
          int i,j;maxcnt=0,cnt=0;
          memset(b,0,sizeof(b));
          for(i=1;i<=n;i++)
          {
                  scanf("%d",&a[i]);
                  b[a[i]]++;
                  if( maxcnt<b[a[i]])
                  {
                          
                          maxcnt=b[a[i]];
                  }
          }
          for(i=1;i<=min(n,k);i++)
                for(j=1;j<=n;j++)
          {
                  num[++cnt]=a[j];
          }
          int val=0;
          for(i=1;i<=cnt;i++)
          {
                  int pos=upper_bound(dp,dp+val,num[i])-dp;
                  if(pos==val) dp[val++]=num[i];
                  else
                        dp[pos]=num[i];
          }
          if(k>n)
                val+=(k-n)*maxcnt;
          printf("%d\n",val);
    }

    return 0;
}

另附上lower_bound求最长上升子序列的用法

#include<iostream>
#include<stdio.h>
#include<queue>
#include<map>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 1e4 + 10;
int num[maxn];
int dp[maxn];
int main() {
    int n;
    while(scanf("%d",&n)!=EOF)
    {
          int i,j;
          for(i=1;i<=n;i++)
          {
                  scanf("%d",&num[i]);

          }

          int len=1;dp[1]=num[1];
          for(i=2;i<=n;i++)
          {
                  if(num[i]>dp[len]) dp[++len]=num[i];
                  else
                  {
                      j=lower_bound(dp+1,dp+len+1,num[i])-dp;
                      dp[j]=num[i];
                  }

          }

          printf("%d\n",len);
    }

    return 0;
}

最后附上一个大佬的详细讲解:

https://www.cnblogs.com/itlqs/p/5743114.html

猜你喜欢

转载自blog.csdn.net/intelligentgirl/article/details/81503648
今日推荐