思路:
动态规划。
large数据的时间范围很大,无法设计入状态中。转换思路为定义dp[i][j]为当前在景点i,并且已经游览了j个景点所花费的最小时间,这种思想与leetcode45类似。于是转移方程为dp[i][j] = min(cal(dp[i - 1][j], i), cal(dp[i - 1][j - 1] + ts, i))。其中cal(t, i)表示在时刻t出发,乘坐从景点i发出的车中尽可能早的一辆并且到达景点i+1所花费的总时间。
实现:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 const int MAXN = 2005, INF = 0x3f3f3f3f; 5 int n, ts, tf, s[MAXN], f[MAXN], d[MAXN], dp[MAXN][MAXN]; 6 7 int cal(int now, int i) 8 { 9 if (s[i] >= now) return s[i] + d[i]; 10 return now + (f[i] - (now - s[i]) % f[i]) % f[i] + d[i]; 11 } 12 13 int main() 14 { 15 int T; 16 cin >> T; 17 for (int t = 1; t <= T; t++) 18 { 19 cin >> n >> ts >> tf; 20 for (int i = 1; i <= n - 1; i++) 21 { 22 cin >> s[i] >> f[i] >> d[i]; 23 } 24 dp[0][0] = 0; 25 for (int i = 0; i <= n - 1; i++) 26 for (int j = i + 1; j <= n - 1; j++) 27 dp[i][j] = INF; 28 for (int i = 1; i <= n - 1; i++) 29 { 30 dp[i][0] = cal(dp[i - 1][0], i); 31 for (int j = 1; j <= i; j++) 32 dp[i][j] = min(cal(dp[i - 1][j], i), cal(dp[i - 1][j - 1] + ts, i)); 33 } 34 cout << "Case #" << t << ": "; 35 bool flg = false; 36 for (int i = n - 1; i >= 0; i--) 37 { 38 if (dp[n - 1][i] <= tf) 39 { 40 flg = true; 41 cout << i << endl; 42 break; 43 } 44 } 45 if (!flg) puts("IMPOSSIBLE"); 46 } 47 return 0; 48 }