标题
d[0][i]表示第i个人没和前面的人一起买票 前i个人的最小时间
d[1][i]表示第i个人和前面的人一起买票 前i个人的最小时间
第i个人如果选择和前面的人一起则只能通过d[i - 1][0]转移过来
如果不和前面的人一起可以选择d[i - 1][0]和d[i - 1][1]取min转移过来
AC代码
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 2e3 + 10;
int a[MAXN], b[MAXN];
int d[2][MAXN]; //是否两人 前i人的最小花费
int main()
{
#ifdef LOCAL
freopen("C:/input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--)
{
int h = 8, m = 0, s = 0;
memset(d, 0x3f, sizeof(d));
int n;
cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
for (int i = 2; i <= n; i++)
scanf("%d", &b[i]);
d[1][0] = 0;
for (int i = 1; i <= n; i++)
{
d[0][i] = min(d[0][i - 1], d[1][i - 1]) + a[i];
d[1][i] = d[0][i - 1] - a[i - 1] + b[i];
}
int ans = min(d[0][n], d[1][n]);
s += ans % 60, ans /= 60;
m += ans % 60, ans /= 60;
h += ans % 12, ans /= 12;
if (ans && !h)
printf("12:%02d:%02d pm\n", m, s);
else
printf("%02d:%02d:%02d %s\n", h, m, s, ans ? "pm" : "am");
}
return 0;
}