AC代码
/*
先排序,因为取连续的一段数作为一队,diff肯定是优于不连续的
当一段>=6时,一定能分成两队,diff4-diff3可以被优化掉
所以 就有了递推式 dp[i] = min ( dp[i] , dp[i-j] + a[i] - a[i-j+1] ), 3<=j<=5;
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pLL;
const int N=1e6+5;
#define ls (i<<1)
#define rs (i<<1|1)
#define fi first
#define se second
#define mk make_pair
#define mem(a,b) memset(a,b,sizeof(a))
LL read()
{
LL x=0,t=1;
char ch=getchar();
while(!isdigit(ch)){ if(ch=='-')t=-1; ch=getchar(); }
while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
return x*t;
}
pLL a[N];
LL dp[N],path[N];
int ans[N];
int main()
{
int n=read();
for(int i=1;i<=n;i++)
{
a[i].fi=read();
a[i].se=i;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++) path[i]=1;
mem(dp,0x3f); dp[0]=0;
for(int i=1;i<=n;i++)
{
for(int j=3;j<=5&&i-j>=0;j++)
{
int tmp=dp[i-j]+a[i].fi-a[i-j+1].fi;
//printf("i=%d dp=%d
",i,dp[i]);
if(tmp<dp[i])
{
dp[i]=tmp;
path[i]=i-j+1;
}
//else if(tmp==dp[i]&&)
}
}
int cnt=1,m=n;
while(m)
{
for(int i=m;i>=path[m];i--)
ans[a[i].se]=cnt;
m=path[m]-1;
cnt++;
}
printf("%lld %d
",dp[n],cnt-1);
for(int i=1;i<=n;i++)
printf("%d%c",ans[i],i==n?'
':' ');
return 0;
}