1 条题解

  • 0
    @ 2025-3-13 20:23:35
    #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
    上传者