B. Once Again...
time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

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.

  其实想了好久都不明白网上有人说是插空是怎么回事,现在也不明白。先记下,看以后会不会懂。。。只能泛泛的理解长度为n的序列重复n次应该会出现比较特殊的情况,比如‘循环’什么的。在怎么循环这个重复的序列也只有n个不同的数。t比n大很多,t<=n时直接做不会超时,t很大时,只求到重复n次的lis。之后加上后面原来数列里面出现次数最多的数的次数*(t-n)。可以想象,一个数在原序列里面出现次数越多,最长不下降数列里面它出现的几率和次数应该也是最多的。

实现过程中用到upper_bound()函数,它是求一个数的上界位置,就是比要求的数大的第一个位置,注意这里是大于不是大于等于。比如a[5]={1,2,2,2,5},upper_bound(a,a+5,2)-a=4.(严格来说返回的是数组编号地址)就是比2大的第一个位置下标为4。所以当数组里所有元素都小于等于给定的key的话,它会返回数组最后一个元素的下一个位置的下标,即upper_bound(a,a+5,5)-a=5。而lower_bound()函数是求大于等于当前值的第一个位置,所以lower_bound(a,a+5,2)-a=1,即第一次出现大于等于2的位置下标为1。

非下降子序列和递增有一点的不同就是允许重复。所以用upper_bound()求当前元素的下一个位置,再更新。知道upper_bound()的作用代码就好理解了:

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1e4 + ;
int dp[MAXN];
int num[MAXN], a[];
int re[]; int main()
{
int n, t;
int maxncnt = ;
memset(re, , sizeof(re));
memset(dp, , sizeof(dp));
scanf("%d%d", &n, &t);
for (int i = ; i < n; i++) {
scanf("%d", &a[i]);
re[a[i]]++;
if (re[a[i]] > maxncnt) maxncnt = re[a[i]];
}
int cnt = ;
for (int i = ; i < min(n, t); i++) {
for (int j = ; j < n; j++)
num[cnt++] = a[j];
}
int val = ;
for (int i = ; 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 (t > n) val += (t - n)*maxncnt;
printf("%d\n", val);
return ;
}

求非减lis处代码还可以仿照lis求法做下小改动。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1e4 + ;
int dp[MAXN];
int num[MAXN], a[];
int re[],val; int main()
{
int n, t;
int maxncnt = ;
memset(re, , sizeof(re));
memset(dp, , sizeof(dp));
scanf("%d%d", &n, &t);
for (int i = ; i < n; i++) {
scanf("%d", &a[i]);
re[a[i]]++;
if (re[a[i]] > maxncnt) maxncnt = re[a[i]];
}
int cnt = ;
for (int i = ; i < min(n, t); i++) {
for (int j = ; j < n; j++) {
num[cnt++] = a[j];
}
}
int val = ;
dp[] = num[];
for (int i = ; i < cnt; i++) {
if (num[i] >= dp[val - ]) dp[val++] = num[i];
else
{
int pos = upper_bound(dp, dp + val, num[i]) - dp;
dp[pos] = num[i];
}
}
if (t > n) val += (t - n)*maxncnt;
printf("%d\n", val);
return ;
}

我非作死想要自己实现类似upper_bounder()的作用自己写二分,怎么写都不对,但还是有人会写。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN = 1e4 + ;
int dp[MAXN],num[MAXN];
int a[];
int re[], val; int binary_search(int i)
{
int left, right, mid;
left = , right = val;
while (left<right)
{
mid = (left + right) >> ;
if (dp[mid] > num[i]) right = mid;
else left = mid + ;
}
return left;
} int main()
{
int n, t;
int maxncnt = ;
memset(re, , sizeof(re));
memset(dp, , sizeof(dp));
scanf("%d%d", &n, &t);
for (int i = ; i <= n; i++) {
scanf("%d", &a[i]);
re[a[i]]++;
if (re[a[i]] > maxncnt) maxncnt = re[a[i]];
}
int cnt = ;
for (int i = ; i <= min(n, t); i++) {
for (int j = ; j <= n; j++)
num[cnt++] = a[j];
}
val = ;
dp[] = num[];
for (int i = ; i <= cnt; i++) {
if (num[i] >= dp[val])
dp[++val] = num[i];
else {
int pos = binary_search(i);
dp[pos] = num[i];
}
}
printf("%d\n", val + maxncnt*(t - min(n, t)));
return ;
}

另一种二分写法:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
int a[];
int s[];
int m[]; int main()
{
int n,T;
scanf("%d%d",&n,&T);
memset(m,,sizeof(m));
int ansm=;
for(int i=;i<n;i++){
scanf("%d",a+i);
m[a[i]]++;
ansm=max(m[a[i]],ansm);
}
int top=;
for(int i=;i<min(n,T);i++){
for(int j=;j<n;j++){
if(top==||a[j]>=s[top-]){
s[top]=a[j];
top++;
}else{
int l=,r=top-;
int ans=r;
while(l<=r){
int mid=(l+r)>>;
if(s[mid]>a[j]){
ans=mid;
r=mid-;
}else{
l=mid+;
}
}
s[ans]=a[j];
}
}
}
printf("%d\n",top+ansm*(T-min(n,T)));
return ;
}

Codeforces Round #323 (Div. 2) Once Again... CodeForces - 582B 最长非下降子序列【dp】(不明白)的更多相关文章

  1. Codeforces Round #323 (Div. 2) D. Once Again... 暴力+最长非递减子序列

                                                                                  D. Once Again... You a ...

  2. Educational Codeforces Round 97 (Rated for Div. 2) E. Make It Increasing(最长非下降子序列)

    题目链接:https://codeforces.com/contest/1437/problem/E 题意 给出一个大小为 \(n\) 的数组 \(a\) 和一个下标数组 \(b\),每次操作可以选择 ...

  3. Codeforces Round #323 (Div. 2) D. Once Again... 乱搞+LIS

    D. Once Again... time limit per test 1 second memory limit per test 256 megabytes input standard inp ...

  4. Codeforces Round #205 (Div. 2)C 选取数列可以选择的数使总数最大——dp

    http://codeforces.com/contest/353/problem/C Codeforces Round #205 (Div. 2)C #include<stdio.h> ...

  5. Codeforces Round #323 (Div. 1) B. Once Again... 暴力

    B. Once Again... Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/582/probl ...

  6. Codeforces Round #323 (Div. 2) C. GCD Table 暴力

    C. GCD Table Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/583/problem/C ...

  7. 重复T次的LIS的dp Codeforces Round #323 (Div. 2) D

    http://codeforces.com/contest/583/problem/D 原题:You are given an array of positive integers a1, a2, . ...

  8. Codeforces Round #323 (Div. 2) C. GCD Table map

    题目链接:http://codeforces.com/contest/583/problem/C C. GCD Table time limit per test 2 seconds memory l ...

  9. Codeforces Round #323 (Div. 2) C.GCD Table

    C. GCD Table The GCD table G of size n × n for an array of positive integers a of length n is define ...

随机推荐

  1. Luogu P1730 最小密度路径(最短路径+dp)

    P1730 最小密度路径 题面 题目描述 给出一张有 \(N\) 个点 \(M\) 条边的加权有向无环图,接下来有 \(Q\) 个询问,每个询问包括 \(2\) 个节点 \(X\) 和 \(Y\) , ...

  2. 7 个令人兴奋的 JavaScript 新特性

    前言 一个ECMAScript标准的制作过程,包含了Stage 0到Stage 4五个阶段,每个阶段提交至下一阶段都需要TC39审批通过.本文介绍这些新特性处于Stage 3或者Stage 4阶段,这 ...

  3. Linux ifconfig 查看网络接口状态

    Linux ifconfig 如果不接任何参数,就会输出当前网络接口的情况: [root@localhost ~]# Linux ifconfig eth0      Link encap:Ether ...

  4. Mybatis错误:Result Maps collection already contains value for ***

    [转载]原文链接:https://blog.csdn.net/maoyuanming0806/article/details/77870345 使用mybatis时,服务器启动时出错 严重: Exce ...

  5. Django项目:CRM(客户关系管理系统)--11--04PerfectCRM实现King_admin注册功能03

    #base_admin.py #Django admin 注册功能的形式 # sites = { # 'crm':{ # 'customers':CustomerAdmin, # 'customerf ...

  6. leetcode 60-80 easy

    66.Plus One Given a non-empty array of digits representing a non-negative integer, plus one to the i ...

  7. PHPStrom直接在编辑器打开php文件

    以下是自己配置PHP+Apache的开发环境,集成环境的话要换第二种方法(看个人配置):PHPStrom 如果希望直接在编辑器打开php文件,要做以下这几步配置. 第一种:非集成环境 1 2 3 第二 ...

  8. Ajax.dll使用方法和步骤(比较方便的实现ajax)

    转载自   博客频道 - CSDN.NET http://blog.csdn.net/houhanxin1/article/details/6671470 1. 有直接用框架的:Ajaxpro和Aja ...

  9. phpExcel 操作示例

    片段 1 片段 2 phpExcel 操作示例 <?php //写excel //Include class require_once('Classes/PHPExcel.php'); requ ...

  10. 前端与编译原理——用JS写一个JS解释器

    说起编译原理,印象往往只停留在本科时那些枯燥的课程和晦涩的概念.作为前端开发者,编译原理似乎离我们很远,对它的理解很可能仅仅局限于"抽象语法树(AST)".但这仅仅是个开头而已.编 ...