HDU 6076 题解

题目:http://acm.hdu.edu.cn/showproblem.php?pid=6076

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.

Two teams A and B are going to travel by plane. Each team has n players, ranked from 1 to n according to their average performance. No two players in the same team share the same rank. Team A is waiting in queue 1 while team B is waiting in queue 2. Nobody else is waiting for security check.

Little Q is the policeman who manages two queues. Every time he can check one person from one queue, or check one each person from both queues at the same time. He can’t change the order of the queue, because that will make someone unhappy. Besides, if two players Ai and Bj are being checked at the same time, satisfying |AiBj|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 T(1T15) , denoting the number of test cases.

In each test case, there are 2 integers n,k(1n60000,1k10) in the first line, denoting the number of players in a team and the parameter k.

In the next line, there are n distinct integers A1,A2,...,An(1Ain) , denoting the queue 1 from front to rear.

Then in the next line, there are n distinct integers B1,B2,...,Bn(1Bin), denoting the queue 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.

代码:

/*
HDU 6076 - Security Check [ DP,二分 ]  |  2017 Multi-University Training Contest 4
题意:
    给出两个检票序列 A[N], B[N]
    规定 abs(A[i]-B[j]) <= k 的i,j不能同时检票
    求最少的检票时间
    限制  N<= 6e4, k <= 10
分析:
    f(i,j) 为检票至i,j的时间
    则 f(i,j) = f(i-1,j-1) + 1 ,  abs(A[i]-B[j]) > k
              = min(f(i-1,j), f(i,j-1)) + 1 , abs(A[i]-B[j]) <= k
    对于第二项,由于k小,可DP
    对于第一项,可以二分最大的 t 使得 f(i,j) = f(i-t,j-t) + t 成立
        那么 f(i-t,j-t) 就是第二项的了
*/ 
#include <bits/stdc++.h>
using namespace std;
const int N = 60005;
vector<int> G[N<<1];
int dp[N][25];
int a[N], b[N], pos[N];
int t, n, k;
int f(int n, int m)
{
    if (n == 0 || m == 0) return n+m;
    if (abs(a[n]-b[m]) > k)
    {
        int t = lower_bound(G[m-n+N].begin(), G[m-n+N].end(), n) - G[m-n+N].begin();
        if (t == 0) return max(n, m);
        t = G[m-n+N][t-1];
        return f(t, m-n+t) + n-t;
    }
    else
    {
        int t = b[m]-a[n]+k;
        if (dp[m][t] == -1)
            dp[m][t] = min(f(n-1, m), f(n, m-1)) + 1;
        return dp[m][t];
    }
}
int main()
{
    scanf("%d", &t);
    while (t--)
    {
        for (int i = 0; i < N<<1; i++) G[i].clear();
        memset(dp, -1, sizeof(dp));
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++)
        {
            scanf("%d", &a[i]);
            pos[a[i]] = i;
        }
        for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
        for (int i = 1; i <= n; i++)
            for (int j = max(1, b[i]-k); j <= min(n, b[i]+k); j++)
            {
                G[i-pos[j]+N].push_back(pos[j]);// 记录当a、b保持当前相对位置(i-pos[j]+N)时,a的哪些位置是不能同时检查的
            }
        for (int i = 0; i < N<<1; i++) sort(G[i].begin(), G[i].end());
        int ans = f(n, n);
        printf("%d\n", ans);
    }
}


转载文章:HDU 6076 - Security Check | 2017 Multi-University Training Contest 4

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值