//https://ac.nowcoder.com/acm/contest/1041/G
#include<bits/stdc++.h>
#include<unordered_map>
#include<array>
#define ll long long
#define ull unsigned long long
#define all(a) a.begin(),a.end()
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-8;
const ll mod = 1e9 + 9;
const int N = 1e5 + 5;
int n, m, pre[35];
int dp[35][5005];
int path[35][5005];
pair<int, int> g[35];
void solve()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> g[i].first, g[i].second = i;
sort(g + 1, g + 1 + n, greater<>());
for (int i = 1; i <= n; i++)
pre[i] = pre[i - 1] + g[i].first;
for (int i = 0; i <= n; i++)
for (int j = 0; j <= m; j++)
dp[i][j] = inf;
dp[0][0] = 0;
for (int i = 1; i <= n; i++)
{
for (int j = i; j <= m - (n - i); j++)
{
for (int p = 1; p <= i; p++)
{
if (p == i && j - (p - 1) > 1)
continue;
int now = dp[i - p][j - p] + (i - p) * (pre[i] - pre[i - p]);
if (now < dp[i][j])
{
dp[i][j] = now;
path[i][j] = 1;
}
}
if (i * 2 <= j)
{
int now = dp[i][j - i];
if (now < dp[i][j])
{
dp[i][j] = now;
path[i][j] = path[i][j - i] + 1;
}
}
//cout << "path " << i << ' ' << j << ' ' << path[i][j] << '\n';
//cout << "dp " << i << ' ' << j << ' ' << dp[i][j] << '\n';
}
}
cout << dp[n][m] << '\n';
int num = 0;
int ans[35];
int i = n, j = m, h = 0;
while (i)//回溯,不能用path[i][i]回溯,因为存在多个答案,转移方向也不唯一,会使得多个答案的路径混在一起
{
if (dp[i][j] == dp[i][j - i])
{
h++;
j -= i;
}
else
{
for (int k = 1; k <= i; k++)
{
if (dp[i][j] == dp[i - k][j - k] + (pre[i] - pre[i - k]) * (i - k))
{
for (int u = i - k + 1; u <= i; u++)
ans[g[u].second] = 1 + h;
i -= k;
j -= k;
break;
}
}
}
}
for (int i = 1; i <= n; i++)
cout << ans[i] << ' ';
}
signed main()
{
IOS;
int t = 1;
//cin >> t;
while (t--)
solve();
return 0;
}
Cookies(贪心dp), dp16
最新推荐文章于 2024-08-04 20:05:01 发布