看了半天题才看懂...
题解:
设dp[i][j]表示FJ走到第i步,Bessie走到第j步时,的最小花费。
那么从dp[i][j]向dp[i + 1][j],dp[i][j + 1],dp[i + 1][j + 1]转移就完了。
复杂度:
时间复杂度O(nm),空间复杂度O(nm)
收获:
要留意到无后效性
/* Forgive me Not */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1005;
int n, m;
int dx[] = {0, 0, -1, 1}, dy[] = {1, -1, 0, 0};
char str[maxn];
LL dp[maxn][maxn];
struct _po {
int x, y;
} F[maxn], B[maxn];
inline int getid(char ch) {
if(ch == 'N') return 0;
if(ch == 'S') return 1;
if(ch == 'W') return 2;
if(ch == 'E') return 3;
}
inline LL dis(_po A, _po B) {
return (LL)(A.x - B.x) * (A.x - B.x) + (LL)(A.y - B.y) * (A.y - B.y);
}
int main() {
scanf("%d%d%d%d%d%d", &n, &m, &F[0].x, &F[0].y, &B[0].x, &B[0].y);
scanf("%s", str + 1); for(int i = 1, op; str[i]; i++) op = getid(str[i]), F[i] = (_po){F[i - 1].x + dx[op], F[i - 1].y + dy[op]};
scanf("%s", str + 1); for(int i = 1, op; str[i]; i++) op = getid(str[i]), B[i] = (_po){B[i - 1].x + dx[op], B[i - 1].y + dy[op]};
memset(dp, 0x3f, sizeof(dp));
dp[0][0] = 0;
for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) {
dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + dis(F[i + 1], B[j]));
dp[i][j + 1] = min(dp[i][j + 1], dp[i][j] + dis(F[i], B[j + 1]));
dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j] + dis(F[i + 1], B[j + 1]));
}
printf("%lld\n", dp[n][m]);
return 0;
}

本文介绍了一种使用动态规划求解FJ与Bessie行走路径上的最小花费问题的方法。通过定义状态dp[i][j]表示FJ和Bessie分别到达特定位置时的最小代价,并实现了状态间的转移,最终得到了整体最小代价。

695

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



