Codeforces Round #323 (Div. 2) Once Again... CodeForces - 582B 最长非下降子序列【dp】(不明白)
1 second
256 megabytes
standard input
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.
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).
Print a single number — the length of a sought sequence.
4 3
3 1 4 2
5
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】(不明白)的更多相关文章
- Codeforces Round #323 (Div. 2) D. Once Again... 暴力+最长非递减子序列
D. Once Again... You a ...
- Educational Codeforces Round 97 (Rated for Div. 2) E. Make It Increasing(最长非下降子序列)
题目链接:https://codeforces.com/contest/1437/problem/E 题意 给出一个大小为 \(n\) 的数组 \(a\) 和一个下标数组 \(b\),每次操作可以选择 ...
- 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 ...
- Codeforces Round #205 (Div. 2)C 选取数列可以选择的数使总数最大——dp
http://codeforces.com/contest/353/problem/C Codeforces Round #205 (Div. 2)C #include<stdio.h> ...
- 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 ...
- 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 ...
- 重复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, . ...
- 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 ...
- 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 ...
随机推荐
- Luogu P1730 最小密度路径(最短路径+dp)
P1730 最小密度路径 题面 题目描述 给出一张有 \(N\) 个点 \(M\) 条边的加权有向无环图,接下来有 \(Q\) 个询问,每个询问包括 \(2\) 个节点 \(X\) 和 \(Y\) , ...
- 7 个令人兴奋的 JavaScript 新特性
前言 一个ECMAScript标准的制作过程,包含了Stage 0到Stage 4五个阶段,每个阶段提交至下一阶段都需要TC39审批通过.本文介绍这些新特性处于Stage 3或者Stage 4阶段,这 ...
- Linux ifconfig 查看网络接口状态
Linux ifconfig 如果不接任何参数,就会输出当前网络接口的情况: [root@localhost ~]# Linux ifconfig eth0 Link encap:Ether ...
- Mybatis错误:Result Maps collection already contains value for ***
[转载]原文链接:https://blog.csdn.net/maoyuanming0806/article/details/77870345 使用mybatis时,服务器启动时出错 严重: Exce ...
- Django项目:CRM(客户关系管理系统)--11--04PerfectCRM实现King_admin注册功能03
#base_admin.py #Django admin 注册功能的形式 # sites = { # 'crm':{ # 'customers':CustomerAdmin, # 'customerf ...
- leetcode 60-80 easy
66.Plus One Given a non-empty array of digits representing a non-negative integer, plus one to the i ...
- PHPStrom直接在编辑器打开php文件
以下是自己配置PHP+Apache的开发环境,集成环境的话要换第二种方法(看个人配置):PHPStrom 如果希望直接在编辑器打开php文件,要做以下这几步配置. 第一种:非集成环境 1 2 3 第二 ...
- Ajax.dll使用方法和步骤(比较方便的实现ajax)
转载自 博客频道 - CSDN.NET http://blog.csdn.net/houhanxin1/article/details/6671470 1. 有直接用框架的:Ajaxpro和Aja ...
- phpExcel 操作示例
片段 1 片段 2 phpExcel 操作示例 <?php //写excel //Include class require_once('Classes/PHPExcel.php'); requ ...
- 前端与编译原理——用JS写一个JS解释器
说起编译原理,印象往往只停留在本科时那些枯燥的课程和晦涩的概念.作为前端开发者,编译原理似乎离我们很远,对它的理解很可能仅仅局限于"抽象语法树(AST)".但这仅仅是个开头而已.编 ...