zoukankan      html  css  js  c++  java
  • HDU 6076 Security Check DP递推优化

    Security Check

    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 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.
     

    题解:

      设定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
    ",dfs(n,n));
        }
        return 0;
    }
  • 相关阅读:
    电子海图开发一百篇第五十五篇-电子江图传输规范 数据模型
    天气可视化,海浪,温度图层的绘制,温度热力图的可视化
    全球潮汐数据API使用方法,潮汐数据查询
    海洋气象数据可视化,以流场的方式显示风场图,海洋气象API使用
    g++ 编译module失败
    编译gcc error-*** LIBRARY_PATH shouldn‘t contain the current directory when *** building gcc.
    windows两种自启动的区别
    windows多线程加锁
    windows server 2012不显示此电脑
    pthread_cond_wait
  • 原文地址:https://www.cnblogs.com/zxhl/p/7507469.html
Copyright © 2011-2022 走看看