1 条题解
-
0
#include <bits/stdc++.h> #define int long long using namespace std; int n, k; int a[305]; int sum[305]; // 前i个位置、放j个出口、第i个位置放/不放出口的最小逃生时间 int f[305][305][2]; int fLast[305][305][2]; // f[i][j][k] 对应的 last int tLast[305][305][2]; // f[i][j][k] 对应的 last 位置是 0 还是 1 vector<int> ans; signed main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> k; for (int i = 1; i <= n; i++) { cin >> a[i]; sum[i] = sum[i - 1] + a[i]; } memset(f, 0x3f, sizeof(f)); f[1][1][1] = 0; fLast[1][1][1] = -1; tLast[1][1][1] = -1; // 前面所有点到 i int sum = a[1]; int cnt = a[1]; for (int i = 2; i <= n; i++) { for (int j = 1; j <= min(i, k); j++) { // f[i][j][0] if (j < i) { int nowCnt = a[i]; int nowSum = a[i]; // a[last+1]~a[i] 都去 last 这个出口避难 for (int last = i - 1; last >= j; last--) { if (f[last][j][1] + nowSum <= f[i][j][0]) { f[i][j][0] = f[last][j][1] + nowSum; fLast[i][j][0] = last; tLast[i][j][0] = 1; } nowCnt += a[last]; nowSum = nowSum + nowCnt; } } // f[i][j][1] if (j == 1) { f[i][j][1] = sum; } else { int nowSum = 0; // a[last+1]~a[i] 由 i 作为出口 for (int last = i - 1; last >= j - 1; last--) { if (f[last][j - 1][1] + nowSum <= f[i][j][1]) { f[i][j][1] = f[last][j - 1][1] + nowSum; fLast[i][j][1] = last; tLast[i][j][1] = 1; } if (f[last][j - 1][0] + nowSum <= f[i][j][1]) { f[i][j][1] = f[last][j - 1][0] + nowSum; fLast[i][j][1] = last; tLast[i][j][1] = 0; } nowSum += a[last] * (i - last); } } } cnt += a[i]; sum += cnt; } int ii, jj, kk; ii = n, jj = k, kk = 1; if (f[n][k][0] <= f[n][k][1]) kk = 0; while (jj != 0) { int ni, nj, nk; if (kk == 1) { ni = fLast[ii][jj][kk]; nj = jj - 1; nk = tLast[ii][jj][kk]; ans.push_back(ii); } else { ni = fLast[ii][jj][kk]; nj = jj; nk = tLast[ii][jj][kk]; } ii = ni, jj = nj, kk = nk; } cout << min(f[n][k][1], f[n][k][0]) << "\n"; for (int i = ans.size() - 1; i >= 0; i--) cout << ans[i] << " "; cout << "\n"; return 0; }
- 1
信息
- ID
- 1826
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 7
- 标签
- (无)
- 递交数
- 33
- 已通过
- 9
- 上传者