cf831D(dp)
生活随笔
收集整理的這篇文章主要介紹了
cf831D(dp)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接: http://codeforces.com/contest/831/problem/D
?
題意: 有 n 個人和 k 把鑰匙, 數組 a 為 n 個人的初始位置, 數組 b 為 k 把鑰匙的初始位置, n 個人都要先拿到一把鑰匙然后在到 p 位置去, 問所有人都到 p 位置所需要的最少時間是多少.
?
思路: 這題即可以 dp 也可以直接二分答案.
dp 思路為: dp[i][j]存儲前i個人在前j把鑰匙中每個人得到鑰匙的最小花費.
那么動態轉移方程式為:
if(i == j) dp[i][j] = max(dp[i - 1][j - 1], abs(a[i] - b[j]) + abs(p - b[j]))
else if(j > i) dp[i][j] = min(dp[i][j - 1], max(dp[i - 1][j - 1], abs(a[i] - b[j]) + abs(p - b[j])))
?
代碼:
1 #include <iostream> 2 #include <algorithm> 3 #include <stdio.h> 4 using namespace std; 5 6 const int MAXN = 1e3 + 10; 7 int a[MAXN], b[MAXN << 1], dp[MAXN][MAXN << 1];//dp[i][j]存儲前i個人在前j把鑰匙中每個人得到鑰匙的最小花費 8 9 int main(void){ 10 int n, k, p; 11 scanf("%d%d%d", &n, &k, &p); 12 for(int i = 1; i <= n; i++){ 13 scanf("%d", &a[i]); 14 } 15 for(int i = 1; i <= k; i++){ 16 scanf("%d", &b[i]); 17 } 18 sort(a + 1, a + n + 1); 19 sort(b + 1, b + k + 1); 20 for(int i = 1; i <= n; i++){ 21 for(int j = i; j <= k; j++){ 22 if(i == j) dp[i][j] = max(dp[i - 1][j - 1], abs(b[j] - a[i]) + abs(p - b[j])); 23 else dp[i][j] = min(dp[i][j - 1], max(dp[i - 1][j - 1], abs(b[j] - a[i]) + abs(p - b[j]))); 24 } 25 } 26 int sol = 2e9 + 10; 27 for(int i = n; i <= k; i++){ 28 sol = min(sol, dp[n][i]); 29 } 30 printf("%d\n", sol); 31 return 0; 32 } View Code?
轉載于:https://www.cnblogs.com/geloutingyu/p/7181935.html
總結
以上是生活随笔為你收集整理的cf831D(dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32 PWM输出(映射)
- 下一篇: mongodb带认证的副本集搭建