挺有价值的一个dp,记录一下..

//先分配最大的,然后枚举几个1dp即可
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+5,M=35;
int f[M][N];//
int sum[N];

struct vv{
    int id,val;
}a[N];

bool cmp(vv x,vv y)
{
    if(x.val==y.val) return x.id<y.id;
    else             return x.val>y.val;
}

int ans[M];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i].val);
        a[i].id=i;
    }
    sort(a+1,a+1+n,cmp);
    for(int i=1;i<=n;i++)   sum[i]+=sum[i-1]+a[i].val;
    memset(f,0x3f,sizeof f);
    f[0][0]=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(j>=i) f[i][j]=f[i][j-i];
            for(int k=1;k<=i&&k<=j;k++)
            {
                f[i][j]=min(f[i][j],f[i-k][j-k]+(sum[i]-sum[i-k])*(i-k));
            }
        }
    }
    cout<<f[n][m]<<endl;
    int cnt=n;
    int h=0;
    while(n&&m)
    {
        if(m>=n&&f[n][m]==f[n][m-n])    m-=n,h++;
        else
        {
            for(int k=1;k<=n&&k<=m;k++)
            {
                if(f[n][m]==f[n-k][m-k]+(sum[n]-sum[n-k])*(n-k))
                {
                    for(int i=n;i>=n-k+1;i--)
                    ans[a[i].id]=h+1;
                    n-=k,m-=k;
                    break;
                }
            }
        }
    }
    for(int i=1;i<=cnt;i++)
    cout<<ans[i]<<' ';
    cout<<endl;
    return 0;
}