Modified LCS(详解)

LCS stands for longest common subsequence, and it is a well known problem. A sequence in this problemmeans a list of integers, and a sequence X is considered a subsequence of another sequence Y, when thesequence X can be obtained by deleting zero or more elements from the sequence Y without changing theorder of the remaining elements.

In this problem you are given two sequences and your task is to find the length of the longest sequencewhich is a subsequence of both the given sequences. 

You are not given the sequences themselves. For each sequence you are given three integers N , F and D,where N is the length of the sequence, F is the first element in the sequence. Each element except thefirst element is greater than the element before it by D.

For example N = 5, F = 3 and D = 4 represents the following sequence: [3, 7, 11, 15, 19].

There will be at least one integer which belongs to both sequences and it is not greater than 1,000,000. 

Input

Your program will be tested on one or more test cases. The first line of the input will be a single integerT, the number of test cases (1 ≤ T ≤ 100). Followed by the test cases, each test case is described inone line which contains 6 integers separated by a single space N1 F1 D1 N2 F2 D2 (1 ≤ N1,N2 ≤10^18) and (1 ≤ F1,D1,F2,D2 ≤ 10^9) representing the length of the first sequence, the first element inthe first sequence, the incremental value of the first sequence, the length of the second sequence, the firstelement in the second sequence and the incremental value of the second sequence, respectively.

Output

For each test case, print a single line which contains a single integer representing the length of the longestcommon subsequence between the given two sequences.

输出时每行末尾的多余空格,不影响答案正确性

样例输入复制

3
5 3 4 15 3 1
10 2 2 7 3 3
100 1 1 100 1 2

样例输出复制

4
3
50

 

题意:

就是给定俩个等差序列的首相,公差,还有序列的个数,让你求共有的数字的个数

思路

按照等差数列的公式 f1+d1x=f2+d2y 其中x属于[0,n1-1] y的范围是[0,n2-1] 即为 f2-f1=d1x-d2y 问题就可以转化为满足条件的解 的个数,是不是可以想到扩展欧几里得这个算法,其实这个题就是扩展欧几里得的模板题,建议看下相关的知识点,不然这个题是没法解决的

推荐个博客:https://blog.csdn.net/qq_44797733/article/details/107533622

 

code:

#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;

typedef long long ll;
ll n1,f1,d1,n2,f2,d2;
ll x,y;
ll exgcd(ll a,ll b){//这个就是板子,在上面的连接处给予了相关的证明 
	if(b==0){
		x=1;
		y=0;
		return a;
	}
	ll r=exgcd(b,a%b);
	ll temp=x;
	x=y;
	y=temp-(a/b)*y;
	return r;
}
int main()
{
	int t;
	scanf("%d",&t);
	while(t--){
		ll ans;
		scanf("%lld%lld%lld%lld%lld%lld",&n1,&f1,&d1,&n2,&f2,&d2);
		ll f=f2-f1;
		ll GCD=exgcd(d1,-d2);
		if(f%GCD){//不为0就没有解 
			cout<<0<<endl;
		}
		else{
			x=x*f/GCD;//求解ax+by=m的一个特解 
			y=y*f/GCD;
			GCD=abs(GCD);
			int a=d2/GCD,b=d1/GCD;//最小公倍数就是最小的间隔 
			while(x<0||y<0) x+=a,y+=b;
			while(x>=0&&y>=0) x-=a,y-=b;
			if(x<0||y<0) x+=a,y+=b;
			ans=min((n1-1-x)/a+1,(n2-1-y)/b+1);//给的x,y的范围内有多少个间隔,取最小的即可 
			cout<<ans<<endl;
		}
	}
	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值