JSOI2010 快递服务 【动态规划】
最初始的状态:dp[i][j][k][l], 表示现在正在进行第i个需求,三个司机分别在j, k, l这三个城市
i可以省,因为j,k,l中必须有一个等于i
状态就变成了:dp[i][j][k],表现有一个司机在第i个需求的城市,其他两个司机分别在j城市和k城市
i这一维还可以滚掉
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define gi get_int()
const int MAXN = 300;
int get_int()
{
int x = 0, y = 1;
char ch = getchar();
while (!isdigit(ch) && ch != '-')
ch = getchar();
if (ch == '-')
y = -1, ch = getchar();
while (isdigit(ch))
x = x * 10 + ch - '0', ch = getchar();
return x * y;
}
int dis[MAXN][MAXN], num[1001], cnt;
int dp[2][MAXN][MAXN];
int main()
{
int n = gi;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++)
dis[i][j] = gi;
}
num[cnt++] = 2;
while (std::cin >> num[cnt])
cnt++;
for (int i = 1; i < cnt; i++)
num[i]--;
int status = 0;
memset(dp, 0x3f, sizeof(dp));
dp[status][1][0] = 0;
for (int i = 0; i < cnt - 1; i++) {
status ^= 1;
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++)
dp[status][j][k] = 0x3f3f3f3f;
for (int j = 0; j < n; j++)
for (int k = 0; k < n; k++) {
dp[status][j][k] = std::min(dp[status][j][k], dp[status ^ 1][j][k] + dis[num[i]][num[i + 1]]);
dp[status][num[i]][k] = std::min(dp[status][num[i]][k], dp[status ^ 1][j][k] + dis[j][num[i + 1]]);
dp[status][num[i]][j] = std::min(dp[status][num[i]][j], dp[status ^ 1][j][k] + dis[k][num[i + 1]]);
}
}
int ans = 0x3f3f3f3f;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
ans = std::min(ans, dp[status][i][j]);
std::cout << ans;
return 0;
}

浙公网安备 33010602011771号