1 solutions
-
0
Guest MOD
-
0
每次运行代码时会停在某个有bug的行。设 表示调试前 行所需的最小时间,转移方程为:
$dp_i = \min_{1 \leq j \leq i} \left( dp_j + a_i + (i-j)^4 \right) $ 直接计算的时间复杂度为 ,无法通过,需优化。四次方代价 增长极快,因此对于较大的 ,拆分调试更优。例如,若一次调试 个bug的代价为 ,拆分为两次调试 个bug的代价为 ,当 较大时拆分更优。
设,求解不等式 ,得 。因此,只需向前枚举 满足 (即 范围),无需遍历所有 。
每次转移的枚举次数为 ,总时间复杂度为 ,可通过题目限制。
转移方程:$ dp_i = \min_{j \in [i - x, i]} (dp_j + a_i + (i-j)^4) $,其中 。
时间复杂度:,利用四次方代价的“稀疏性”减少枚举量。
#include <iostream> #include <vector> #include <climits> #include <cmath> using namespace std; int minimal_debug_time(int n, const vector<int>& bugs) { if (bugs.empty()) return 0; int m = bugs.size(); vector<int> dp(m + 1, INT_MAX); dp[0] = 0; for (int i = 1; i <= m; ++i) { int current_bug_pos = bugs[i - 1]; dp[i] = INT_MAX; // 优化:向前遍历O(n^{1/4})个bug int max_step = pow(current_bug_pos, 0.25) + 1; for (int j = max(0, i - max_step); j < i; ++j) { int x = i - j; int time = dp[j] + current_bug_pos + pow(x, 4); if (time < dp[i]) { dp[i] = time; } } } return dp[m]; } int main() { int n, m; cin >> n >> m; vector<int> bugs(m); for (int i = 0; i < m; ++i) { cin >> bugs[i]; } int result = minimal_debug_time(n, bugs); cout << result << endl; return 0; }
- 1
Information
- ID
- 1496
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 9
- Tags
- (None)
- # Submissions
- 71
- Accepted
- 8
- Uploaded By