題意:
n個人要去一個地方p,給出每個人的一維座標a[i],去這個地方需要一把鑰匙,總共有k把鑰匙,給出每把鑰匙的座標b[i],問n個人最後都到達了這個地方需要多少經過多少時間,每個人走一個單位距離需要一個單位時間。
解題思路:
看起來很複雜的題,有目的地座標還有鑰匙座標,其實仔細想想,取到鑰匙後,接下來還需要的時間也隨之確定下來了,所以只需要考慮人和鑰匙的關係即可。
可以定義dp[i][j]表示前i個人從前j把鑰匙中取走i把到達目的地的最大時間。
轉移就是dp[i][j]=min(dp[i][j-1], max(dp[i-1][j-1], abs(a[i]-b[i])+abs(b[i]-p));
別忘了排序,別忘了long long,就做完了。
代碼:
#include <bits/stdc++.h>#define LL long long using namespace std;const LL inf=1e16;LL dp[1005][2005];LL a[1005];LL b[2006];LL p;int main(){ int n, i, j, k; cin>>n>>k>>p; for(i=1; i<=n; i++)scanf("%lld", &a[i]); sort(a+1, a+n+1); for(i=1; i<=k; i++)scanf("%lld", &b[i]); sort(b+1, b+k+1); for(j=0; j<=k; j++)dp[0][j]=0; for(i=1; i<=n; i++) { for(j=i; j<=k; j++) { if(i==j) { dp[i][j]=max(dp[i-1][j-1],abs(a[i]-b[j])+abs(b[j]-p)); continue; } dp[i][j]=min(dp[i][j-1], max(dp[i-1][j-1],abs(a[i]-b[j])+abs(b[j]-p))); } } j=n; for(i=n; i<=k; i++) { if(dp[n][i]<dp[n][j])j=i; // cout<<dp[n][i]<<endl; } cout<<dp[n][j]<<endl;}