当青训营遇上码上掘金
寻友之旅
小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)
请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)
动态规划解法:
-
小青在小码前面———— 步行回退 return N-K
-
小青就在小码位置—— return 0
-
小青在小码后面——动态规划
-
状态定义
int* dp = new int[100000] {}; //dp[i]:从N到i需要花费最短时间 复制代码 -
初始状态
dp[N] = 0; // 从N到N需要花费0分钟 res = INT_MAX; // 最短时间初始化为INT_MAX 复制代码 -
结果:最短时间
/* res = min(从N到K的最短时间,从N到K+j再回退j的最短时间) = min (dp[K], dp[k+j]+j); */ 复制代码 -
状态转移
/* 0=<i<N——dp[i] = dp[i+1]+1; 步行回退 i>N————dp[i] = min(步行到i,总公交到i)+1 = min(dp[i-1], dp[i/2])+1; i-1>=0且i/2为偶数 = min(dp[i-1], dp[(i-1)/2]+1, dp[(i+1)/2]+1)+1; i-1>=0且i/2为奇数 */ for (int i = N - 1; i >= 0; i--) { dp[i] = dp[i + 1] + 1; } for (int i = N + 1; i <= 100000; i++) { int walk = dp[i - 1] + 1; int bus = dp[i / 2] + 1; if (i % 2 != 0) { bus = min(dp[(i + 1) / 2], dp[(i - 1) / 2]) + 2; } dp[i] = min(walk, bus); if (i >= K) { res = min(res, dp[i] + i - K); } }
-
动态规划(Dynamic Programming,DP)是运筹学的一个分支,是求解决策过程最优化的过程。20世纪50年代初,美国数学家贝尔曼(R.Bellman)等人在研究多阶段决策过程的优化问题时,提出了著名的最优化原理,从而创立了动态规划。动态规划的应用极其广泛,包括工程技术、经济、工业生产、军事以及自动化控制等领域,并在背包问题、生产经营问题、资金管理问题、资源分配问题、最短路径问题和复杂系统可靠性问题等中取得了显著的效果。