原题传送门
下午训练抽到的题目~~
题目大意:n个人,k个钥匙(n<=k),p表示这些人要到达的位置。给出n个人的位置以及钥匙的位置,每个人需要拿一把钥匙再去指定位置,问路程最多的那个人路程最少是多少?
注:
- 钥匙只有一把,一旦被一个人用了,这把钥匙就不能再用
- 钥匙数>=人数,钥匙不一定要全用完
本以为
O
(
n
2
)
O(n^2)
O(n2)过不了此题,后来发现
n
<
=
1000
,
m
<
=
2000
n<=1000,m<=2000
n<=1000,m<=2000
W
T
F
!
!
WTF!!
WTF!!
感觉自己被欺骗了,我好菜呀
- 对于人的位置和钥匙的位置排序(毋庸置疑)
- d p [ i ] [ j ] ( i ≤ j ) 表 示 前 i 个 人 用 到 前 j 把 钥 匙 的 答 案 ( 前 j 把 钥 匙 有 的 用 了 , 有 的 没 用 ) dp[i][j] (i≤j)表示前i个人用到前j把钥匙的答案(前j把钥匙有的用了,有的没用) dp[i][j](i≤j)表示前i个人用到前j把钥匙的答案(前j把钥匙有的用了,有的没用)
- 令 l e n ( i , j ) 表 示 第 i 个 人 拿 到 第 j 把 钥 匙 ( 排 序 后 的 ) 再 到 终 点 所 需 路 程 令len(i,j)表示第i个人拿到第j把钥匙(排序后的)再到终点所需路程 令len(i,j)表示第i个人拿到第j把钥匙(排序后的)再到终点所需路程
- 方 程 : d p [ i ] [ j ] = m i n ( d p [ i ] [ j − 1 ] , m a x ( d p [ i − 1 ] [ j − 1 ] , l e n ( i , j ) ) ) 方程:dp[i][j] = min(dp[i][j - 1],max(dp[i-1][j-1],len(i,j))) 方程:dp[i][j]=min(dp[i][j−1],max(dp[i−1][j−1],len(i,j)))
- 边 界 : d p [ 0 ] [ 0 ] = 0 , d p [ i ] [ i ] = m a x ( d p [ i − 1 ] [ i − 1 ] , l e n ( i , i ) ) 边界:dp[0][0]=0,dp[i][i]=max(dp[i-1][i-1],len(i,i)) 边界:dp[0][0]=0,dp[i][i]=max(dp[i−1][i−1],len(i,i))
保险起见,再开个longlong,搞定
Code:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cctype>
#define maxn 2010
#define inf 2147483647
#define LL long long
using namespace std;
LL dp[maxn][maxn];
int a[maxn], b[maxn], n, m, p;
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
LL len(int i, int j){ return abs(a[i] - b[j]) + abs(p - b[j]); }
int main(){
n = read(), m = read(), p = read();
for (int i = 1; i <= n; ++i) a[i] = read();
for (int i = 1; i <= m; ++i) b[i] = read();
sort(a + 1, a + 1 + n);
sort(b + 1, b + 1 + m);
dp[0][0] = 0;
for (int i = 1; i <= n; ++i){
dp[i][i] = max(dp[i - 1][i - 1], len(i, i));
for (int j = i + 1; j <= m - n + i; ++j) dp[i][j] = min(dp[i][j - 1], max(dp[i - 1][j - 1], len(i, j)));
}
printf("%lld\n", dp[n][m]);
return 0;
}

针对n个人使用k个钥匙去指定位置的问题,采用动态规划算法求解,通过排序和状态转移方程找到路程最多的那个人路程最少的方案。
3130

被折叠的 条评论
为什么被折叠?



