dp,这一题是没有后效性的,只要在保证了每个子问题时间最少的基础上在追求运送次数最少即可。是不会有运送次数减少了,而时间却增多了的情况的。所以时间最优是次数最优的前提。所以状态转移的时候,只要从自问题的时间最优的情况来,肯定没错。
f[i] = max(f[j], arrive_time[i]) + each_time * 2
View Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; #define maxn 1505 #define inf 0x3f3f3f3f int n, m, each_time; int arrive_time[maxn]; int f[maxn], times[maxn]; void input() { scanf("%d%d%d", &n, &each_time, &m); for (int i = 1; i <= m; i++) scanf("%d", &arrive_time[i]); } void work() { f[0] = 0; times[0] = 0; for (int i = 1; i <= m; i++) { f[i] = inf; times[i] = inf; for (int j = i - 1; j >= 0 && i - j <= n; j--) { int temp = max(f[j], arrive_time[i]) + each_time * 2; if (temp == f[i]) times[i] = min(times[i], times[j] + 1); else if (temp < f[i]) { f[i] = temp; times[i] = times[j] + 1; } } } printf("%d %d\n", f[m] - each_time, times[m]); } int main() { //freopen("t.txt", "r", stdin); int t; scanf("%d", &t); while (t--) { input(); work(); } return 0; }