题目:
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: n, T (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;
}
最后附上一个大佬的详细讲解: