The TTT Taxi Service in Tehran is required to deliver some magazines to N locations in Tehran. The locations are labeled L1 to LN. TTT assigns 3 cars for this service. At time 0, all
the 3 cars and magazines are located at L1. There are plenty of magazines available in L1 and the cars can take as many as they want. Copies of the magazine should be delivered to all locations, observing the following rules:
1. For all i = 2 .. N, magazines should be delivered at Li only after magazines are delivered at Li-1.
2. At any time, only one of the three cars is driving, and the other two are resting in other locations.
The time to go from Li to Lj (or reverse) by any car is a positive integer denoted by D[i , j].
The goal is to organize the delivery schedule for the cars such that the time by which magazines are delivered to all N locations is minimum.
Write a program to compute the minimum delivery time.
Input
The input file contains M instances of this problem (1 <= M <= 10). The first line of the input file is M. The descriptions of the input data follows one after the other. Each instance starts with N in a single line (N <= 30). Each line i of the following N-1
lines contains D[i , j], for all i=1..N-1, and j=i+1..N.
Output
The output file contains M lines, each corresponding the solution to one of the input data. In each line, the minimum time it takes to deliver the magazines to all N locations is written.
Sample Input
1
5
10 20 3 4
5 10 20
8 18
19
Sample Output
22
题目大意:
有三辆车,送杂志,给出每个点到另一个点所需时间,要求按顺序派发杂志,求最短时间。
思路:
一开始以为变量只有点的数量一个,然而是我想的太简单了。比如有四个点,按照这个思路则是求出三个点时的最短时间+(三辆车)到达第四个点的最短时间。然而,实际情况有可能前面三个点的时间略长一点,走第四个点的时候短点,最后的和最短。也就是“前n个点的最短时间不一定等于前n-1个点的最短时间+车辆到达第n个点的最短时间”。
所以实际情况有四个变量,通过四重循环解决,最后输出最短的就好。
错误代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <limits.h>
using namespace std;
int dp[100], d[100][100];
int car[3];
int main()
{
int t, n;
cin >> t;
while (t--)
{
cin >> n;
memset(dp, 0, sizeof(dp));
memset(d, 0, sizeof(d));
int i, j;
for (i=1; i<=n-1; i++)
for (j=i+1; j<=n; j++)
cin >> d[i][j];
/*
for (i=1; i<=n-1; i++)
{
for (j=i+1; j<=n; j++)
cout << d[i][j] << ' ';
cout << endl;
}*/
dp[2] = d[1][2];
car[0] = 2; car[1] = 1; car[2] = 1;
int small = 1000000;
for (i=3; i<=n; i++)
{
small = INT_MAX;
for (j=0; j<3; j++)
{
if (d[car[j]][i]<small)
{
small = d[car[j]][i];
car[j] = i;
}
}
dp[i] = dp[i-1] + small;
}
cout << dp[n] << endl;
}
}
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[50][50][50][50], d[100][100];
int main()
{
int t, n;
cin >> t;
while (t--)
{
cin >> n;
memset(dp, 10000, sizeof(dp));
memset(d, 0, sizeof(d));
int i, j, k, m;
for (i=1; i<=n-1; i++)
for (j=i+1; j<=n; j++)
cin >> d[i][j];
dp[1][1][1][1] = 0;
for (i=2; i<=n; i++)
{
for (j=1; j<=n; j++)
for (k=1; k<=n; k++)
for (m=1; m<=n; m++)
{
dp[i][i][k][m] = min(dp[i-1][j][k][m]+d[j][i], dp[i][i][k][m]);
dp[i][j][i][m] = min(dp[i-1][j][k][m]+d[k][i], dp[i][j][i][m]);
dp[i][j][k][i] = min(dp[i-1][j][k][m]+d[m][i], dp[i][j][k][i]);
}
}
printf("%d\n", *min_element(&dp[n][0][0][0], &dp[n][n][n][n]));
}
}