题目大意样例
inputoutput解释 思路代码Hit
题目大意
传送门 输入数据:
int n;
int T;
int t[Train_Num];
int M1;
int d1[Train_Num];
int M2;
int d2[Train_Num];
间谍0时刻在站台1,要在T时刻到达站台n,间谍可以在车站内等车来,尽量让等的时间总和最少,求等的时间总和。
样例
4 55 5 10 15 4 0 5 10 20 4 0 5 10 15
4 18 1 2 3 5 0 3 6 10 12 6 0 3 5 7 12 15
2 30 20 1 20 7 1 3 5 7 11 13 17
0
output
Case Number 1: 5 Case Number 2: 0 Case Number 3: impossible
解释
用dp[i][j]表示i时刻在j站台要等的时间。 那么dp[55][4] = 0 dp[50][4] = 5 dp[35][3] = 5 dp[25][2] = 5 dp[15][3] = 5 dp[5][2] = 5 dp[0][1] = 5
思路
在一个站台一共有三种策略:
等一个时刻如果有开往左边的车,坐上开往左边的车 如果有开往右边的车,坐上开往右边的车
代码
#include <stdio.h>
#include <cstring>
#define Train_Num 55
#define Time_Num 205
#define INF 1000
#define max(a,b) (a>b)? a:b
#define min(a,b) (a>b)? b:a
int n;
int T;
int t[Train_Num];
int M1;
int d1[Train_Num];
int M2;
int d2[Train_Num];
int dp[Time_Num][Train_Num];
int has_train[Time_Num][Train_Num][
2];
int main(){
int kase =
1;
while (
scanf(
"%d", &n) && n !=
0){
scanf(
"%d", &T);
for (
int i =
1; i < n; i++)
scanf(
"%d", &t[i]);
scanf(
"%d", &M1);
for (
int i =
1; i <= M1; i++)
scanf(
"%d", &d1[i]);
scanf(
"%d", &M2);
for (
int i =
1; i <= M2; i++)
scanf(
"%d", &d2[i]);
dp[T][n] =
0;
memset(has_train,
0,
sizeof(has_train));
for (
int i =
1; i <= M1; i++)
{
int T_sum = d1[i];
for (
int j =
1; j < n; j++){
has_train[T_sum][j][
0] =
1;
T_sum += t[j];
}
}
for (
int i =
1; i <= M2; i++)
{
int T_sum = d2[i];
for (
int j = n; j >
1; j--){
has_train[T_sum][j][
1] =
1;
T_sum += t[j-
1];
}
}
for (
int i =
1; i < n; i++) dp[T][i] = INF;
for (
int i = T-
1; i >=
0; i--)
{
for (
int j =
1; j <= n; j++)
{
dp[i][j] = dp[i +
1][j] +
1;
if (j < n && has_train[i][j][
0] && i + t[j] <= T)
dp[i][j] = min(dp[i][j], dp[i + t[j]][j +
1]);
if (j >
1 && has_train[i][j][
1] && i + t[j-
1] <= T)
dp[i][j] = min(dp[i][j], dp[i + t[j-
1]][j -
1]);
}
}
printf(
"Case Number %d: ", kase++);
if (dp[
0][
1] >= INF)
printf(
"impossible\n");
else
printf(
"%d\n",dp[
0][
1]);
}
}
Hit
has_train数组记录的时候,计算向左和向右是不一样的,我的方法中向左的车,j要减一。