Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Problem Description
In airport of Bytetown, there are two long queues waiting for security check. Checking a person needs one minute, and two queues can be checked at the same time.

Picture from Wikimedia Commons
Two teams k, they will make a lot of noise because their rank are almost the same. Little Q should never let that happen.
Please write a program to help Little Q find the best way costing the minimum time.
Picture from Wikimedia Commons
Two teams k, they will make a lot of noise because their rank are almost the same. Little Q should never let that happen.
Please write a program to help Little Q find the best way costing the minimum time.
Input
The first line of the input contains an integer 2 from front to rear.
Output
For each test case, print a single line containing an integer, denoting the minimum time to check all people.
Sample Input
1
4 2
2 3 1 4
1 2 4 3
Sample Output
7
Hint
Time 1 : Check A_1.
Time 2 : Check A_2.
Time 3 : Check A_3.
Time 4 : Check A_4 and B_1.
Time 5 : Check B_2.
Time 6 : Check B_3.
Time 7 : Check B_4.
题解:
设定f[i][j] 表示 递推到 a[i], b[j] 时的最少时间
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 6e5 + 10, inf = 1e9; int n, a[N], b[N], k, fos[N], f[2][N][60]; vector<int > hav1[N],hav2[N]; int dfs(int i,int j) { if(!i || !j) return j+i; if(abs(a[i] - b[j]) <= k) { int& ret = f[i>j?0:1][i][a[i]-b[j] +k]; if(ret) return ret; return ret = min(dfs(i-1,j),dfs(i,j-1))+1; } int ok; if(i > j) ok = hav1[i-j][upper_bound(hav1[i-j].begin(),hav1[i-j].end(),i) - hav1[i-j].begin()-1]; else ok = hav2[j-i][upper_bound(hav2[j-i].begin(),hav2[j-i].end(),i) - hav2[j-i].begin()-1]; return ok?(dfs(ok,j - i + ok) + i - ok):max(i,j); } int main() { int T;cin>>T;while(T--) { scanf("%d%d",&n,&k); memset(f,0,sizeof(f)); memset(fos,0,sizeof(fos)); for(int i = 1; i <= n; ++i) scanf("%d",&a[i]); for(int i = 1; i <= n; ++i) scanf("%d",&b[i]),fos[b[i]] = i; for(int i = 0; i <= 2*n; ++i) hav1[i].clear(),hav2[i].clear(),hav1[i].push_back(0),hav2[i].push_back(0); for(int i = 1; i <= n; ++i) { for(int j = a[i] - k; j <= a[i] + k; ++j) { if(j < 1 || j > n) continue; if(i > fos[j]) hav1[i - fos[j]].push_back(i); else hav2[fos[j] - i].push_back(i); } } for(int i = 0; i <= 2*n; ++i) hav1[i].push_back(n+1),hav2[i].push_back(n+1); for(int i = 0; i <= 2*n; ++i) sort(hav1[i].begin(),hav1[i].end()); for(int i = 0; i <= 2*n; ++i) sort(hav2[i].begin(),hav2[i].end()); printf("%d\n",dfs(n,n)); } return 0; }