CF Round #424 Div.2 D

时间:2022-10-08 21:59:37

n个人拿K个钥匙中的n个然后到办公室(点p) 问最少需要的时间是多少

先排序

如果j<=i 则必须拿这个钥匙 

dp[i][j]=max(dp[i-1][j-1],abs(p-b[j])+abs(a[i]-b[j]));

反之 则可以选择拿或者不拿

dp[i][j]=min(dp[i][j-1],max(dp[i-1][j-1],abs(p-b[j])+abs(a[i]-b[j])));
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<climits>
using namespace std;
int a[150000];
int b[150000];
int dp[1005][1005];
int main()
{
    int n,k,p;
    while(~scanf("%d%d%d",&n,&k,&p))
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        for(int i=1;i<=k;i++)scanf("%d",&b[i]);
        sort(a+1,a+1+n);
        sort(b+1,b+1+k);
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=k;j++)
            {
                if(i>=j)
                {
                    dp[i][j]=max(dp[i-1][j-1],abs(p-b[j])+abs(a[i]-b[j]));
                    continue;
                }
                dp[i][j]=min(dp[i][j-1],max(dp[i-1][j-1],abs(p-b[j])+abs(a[i]-b[j])));
            }
        }
        int output=INT_MAX;
        for(int i=n;i<=k;i++)
        {
            output=min(output,dp[n][i]);
        }
        printf("%d\n",output);
    }
}