牛客-埃森哲杯第十六届上海大学程序设计联赛-L-K序列

标签: 算法
97人阅读 评论(2) 收藏 举报
分类:

链接:https://www.nowcoder.com/acm/contest/91/L
来源:牛客网

题目描述

给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称为“K 序列”。现在要你 对数组 a 求出最长的子序列的长度,满足这个序列是 K 序列。 

输入描述:
第一行为两个整数 n, K, 以空格分隔,第二行为 n 个整数,表示 a[1] ∼ a[n],1 ≤ n ≤ 105 , 1 ≤ a[i] ≤ 109 , 1 ≤ nK ≤ 107
输出描述:
输出一个整数表示最长子序列的长度 m
示例1
输入
7 5
10 3 4 2 2 9 8
输出
6

一:连续子序列
思路:对于求和为 K的倍数的子序列的最大长度,那么可以对其求前缀和,同时前缀和对K取模,只要两前缀和相同就说明他们之间为 K 的倍数,因此只要对取模前缀和保留下标排序(排序规则以前缀和为主,下标为辅),同时还要注意对前缀和为 0时进行特判。

Code:

#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;

struct node{
	int x;
	int id;
	bool operator<(const node &p)const{
		if(x==p.x)	return id<p.id;
		else	return x<p.x;
	}
};
const int MAX_N=100005;
int n,m;
node a[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;++i)
	{
		cin>>a[i].x;
		a[i].x=(a[i].x+a[i-1].x)%m;	a[i].id=i;
	}
	sort(a+1,a+n+1);
	int ans=0;
	for(int i=1,k=0;i<=n;++i)
		if(a[k].x==a[i].x){
			if(a[i].x==0)	ans=max(ans,max(a[i].id,a[k].id));
			else	ans=max(ans,abs(a[i].id-a[k].id));
		}else	k=i;
	cout<<ans<<endl;
	return 0;
}


二:不连续子序列

Code:

/*
不连续子序列 
思路:遍历子序列a[i]: 对于m=k,遍历 0->m-1: dp[j],temp[j]保留对m取模为 i 的最长子序列长度,
那么 dp[(j+a[i])%m]=temp[j]+1;	遍历完m后,更新temp[j]的值即可。 
注意当 temp[j]=0时 dp[(j+a[i])%m]=temp[j]+1是不成立的(取模为j的子序列都没有),但是 j=0时成立. 
*/
#include<iostream>
using namespace std;

const int MAX_N=100005;
const int MAX_M=10000005;
int n,m;
int a[MAX_N];
//dp[i],temp[i]: 对m取模为 i 的最长子序列长度 
int dp[MAX_M];
int temp[MAX_N];

int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	for(int i=1;i<=n;++i)
	{
		for(int j=0;j<m;++j)
			if(j==0||temp[j])	dp[(j+a[i])%m]=temp[j]+1;
		for(int j=0;j<m;++j)
			temp[j]=max(temp[j],dp[j]);
	}
	cout<<dp[0]<<endl;
	return 0;
}



查看评论

求数组元素和是K的倍数的子串的最大长度

序列中任意个连续的元素组成的子序列称为该序列的子串。 现在给你一个序列P和一个整数K,询问元素和是K的倍数的子串的最大长度。 比如序列【1,2,3,4,5】,给定的整数K为 5,其中满足条件的子串为{...
  • u010002184
  • u010002184
  • 2017-09-01 13:06:07
  • 1806

k的倍数(同模相减-美团笔试编程题)

问题描述: 序列中任意个连续的元素组成的子序列成为该序列的子串。现在给你一个序列p和一个整数k,询问元素和是k的倍数的子串的最大长度。比如序列[1,2,3,4,5],给定的k为5,其中满足条件的串子串...
  • carson0408
  • carson0408
  • 2017-08-31 23:03:10
  • 1578

20170831美团笔试:长度为n的数组中最长的和为K的倍数的连续子数组

看到这道题,第一个想法是遍历,从n个数求和,再到n-1个数求和(这里需要遍历)。再到1个数,没有k的倍数则输出0。但是一看数量级10^5,O(n^2)的复杂度肯定超了,于是想到了以前项目里用到的滑窗法...
  • qq_25147897
  • qq_25147897
  • 2017-08-31 21:49:21
  • 561

子序列和等于k__前缀和+hash

问题描述: 有一个长度为N的字符串,若一个连续子序列的和是K的倍数时,则被称之为幸运数列,求该字符串中幸运数列的个数。 问题解答: 对于此问题,首先求出序列的前缀和 s[i] ...
  • WDMing_
  • WDMing_
  • 2015-03-24 16:50:44
  • 1254

L-K序列

链接:https://www.nowcoder.com/acm/contest/91/L来源:牛客网题目描述给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称为“K 序列”...
  • qq_41037114
  • qq_41037114
  • 2018-04-15 14:41:27
  • 118

dp泛做1

这里的dp范做根据网上的动态归法分析和网上的有个100个dp方程做的,题解很多是原版,没怎么动,有些是别人的一些其他做法,还有一些自己的想法。如果看到题解很别人一样,那就是摘自别人的。且这里只是一半。...
  • luyuncheng
  • luyuncheng
  • 2013-05-20 20:02:39
  • 23811

K序列

链接:https://www.nowcoder.com/acm/contest/91/L来源:牛客网题目描述给一个数组 a,长度为 n,若某个子序列中的和为 K 的倍数,那么这个序列被称为“K 序列”...
  • qq_40615676
  • qq_40615676
  • 2018-04-16 20:17:12
  • 51

2017蓝桥杯:k倍区间(前缀和)

标题: k倍区间给定一个长度为N的数列,A1, A2, … AN,如果其中一段连续的子序列Ai, Ai+1, … Aj(i ...
  • za30312
  • za30312
  • 2017-04-08 17:19:31
  • 3396

【数据结构与算法】小于等于k的最大连续子序列和

使用Kadane算法可以在On内得到最大连续子序列和。如果要求得到和不超过k,那么该如何解决? 首先要看能不能继续使用Kadane算法。答案是不能。回顾Kadane,Kadane中使用dp[i]存最后...
  • u010900754
  • u010900754
  • 2017-03-05 05:53:48
  • 1032

hdu(杭电oj)第一页题目题解

第一页有几题没写,有机会补上(嗯,忘了就是另一回事了)。
  • a601025382s
  • a601025382s
  • 2014-08-16 13:13:07
  • 14427
    个人资料
    持之以恒
    等级:
    访问量: 2326
    积分: 732
    排名: 7万+
    文章存档
    最新评论