Time Limit: 2 sec / Memory Limit: 1024 MB
Score : 300 points
Problem Statement
You are given two sequences, each of length N, consisting of integers: A=(A 1 ,…,AN) and B=(B1,…,BN).
Determine whether there is a sequence of length N, X=(X1 ,…,X N), satisfying all of the conditions below.
Xi=Aior Xi =Bi, for every i(1≤i≤N).
∣Xi−Xi+1∣≤K, for every i(1≤i≤N−1).
Constraints
1≤N≤2×10^5
0≤K≤10^9
1≤Ai,Bi≤10^9
All values in input are integers.
Input
Input is given from Standard Input in the following format:
N K
A 1… AN
B 1… BN
Output
If there is an X that satisfies all of the conditions, print Yes; otherwise, print No.
Sample Input 1
5 4
9 8 3 7 2
1 6 2 9 5
Sample Output 1
Yes
X=(9,6,3,7,5) satisfies all conditions.
Sample Input 2
4 90
1 1 1 100
1 2 3 100
Sample Output 2
No
No X satisfies all conditions.
思路:
问题转化:让我们求一个序列,使得这个序列是的每一个元素是从A或B中产生,并且当前元素与下一个元素的差值绝对值小于K。
做法:自然可以暴力枚举每一种情况,DFS一遍应该也是可以的。这里我选择dp.dp[n][0]:表示第n个位置是可以填数的,并且这个数是由A序列产生的,dp[n][1]则表示是由B序列产生的,那么对于dp[n + 1][X],我们做一下思考:n+1这个位置能填数的前提是dp[n][1]或dp[n][0]成立,而不同的转移状态又会影响下一次的转移。
直接上代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int a[N], b[N];
int n, k;
bool f[N][2];//2表示a/b两个数组
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i ++ ) cin >> a[i];
for (int i = 0; i < n; i ++ ) cin >> b[i];
f[0][0] = f[0][1] = true;//初始的话,第0个位置两个数都可以填,0表示填a,1表示填b
for (int i = 1; i < n; i ++ )
{
if(f[i - 1][0])//如果上一个状态用的是a的位置并且成功了
{
if(abs(b[i] - a[i - 1]) <= k) f[i][1] = true;
if(abs(a[i] - a[i - 1]) <= k) f[i][0] = true;
}
if(f[i - 1][1])//如果上一个状态用的是b的位置并且成功了
{
if(abs(b[i] - b[i - 1]) <= k) f[i][1] = true;
if(abs(a[i] - b[i - 1]) <= k) f[i][0] = true;
}
}
for (int i = 1; i < n; i ++ )
if (!f[i][0] && !f[i][1])
{
cout << "No" << endl;
return 0;
}
cout << "Yes" << endl;
return 0;
}