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.


HDU 6076 Security Check DP递推优化
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] 时的最少时间

  HDU 6076 Security Check DP递推优化

 

#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;
}

 

相关文章: