原題連結
題解
dp+多次優先佇列
設 \(dp[i]\) 為 \([1,i]\) 區間內,前 \(k\) 個最大值(有可能不足k個)(注意 \(dp[i]\) 是一個序列)
則 \(dp[i]=\{dp[j][t]+a[j+2][i],j\in[0,i-2],t\in[0,top_j]\} ,\sum t=k\)
code
#include <bits/stdc++.h>
#define ll long long
using namespace std;
int a[1005][1005];
struct Compare {
bool operator()(const array<int, 4>& a, const array<int, 4>& b) {
return a[3] < b[3];
}
};
void solve()
{
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++) cin >> a[i][j];
vector<vector<int>> dp(n + 5);
dp[0].push_back(0);
for (int i = 1; i <= n; i++)
{
priority_queue<array<int, 4>, vector<array<int, 4>>, Compare> q;
q.push({i+1, i - 1, 0, dp[i - 1][0]});
for (int j = i; j >= 1; j--) q.push({j, max(0,j - 2), 0, a[j][i] + dp[max(0,j-2)][0]});
while (!q.empty() && dp[i].size() < k)
{
auto [l, it, cnt, val] = q.top();
q.pop();
dp[i].push_back(val);
if (cnt +1< dp[it].size()) q.push({l, it, cnt + 1, dp[it][cnt+1] + a[l][i]});
}
}
for(auto it:dp[n]) cout<<it<<' ';cout<<'\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t = 1;
cin >> t;
while (t--) solve();
return 0;
}