description
solution
可以发现三人桌不会超过3个,设f[i][j][s]表示到第i个人,用了j个3人桌,往前k+1个人选取状态为s。每个状态最前的位为1就一定要安排一桌,暴力枚举即可,到了最后i要枚举到n+k+1,n以后的不算贡献,但是要保证n-k到n的人都被选完。
code
using namespace std;
LL const mn=1000+13,inf=1e18+7;
LL n,K,a[mn],b[mn],f[mn][5][2050],g[mn][5][2050],h[mn][5][2050];
LL min(LL x,LL y){
return (x<y)?x:y;
}
int main(){
freopen("friends.in","r",stdin);
freopen("friends.out","w",stdout);
scanf("%lld%lld",&n,&K);K++;
fo(i,1,n)scanf("%lld",&a[i]);
LL tmp=((n-1)/4+1)*4-n,mx=(1<<K)-1;
fo(i,0,n+K)fo(j,0,tmp)fo(s,0,mx)f[i][j][s]=inf;
f[0][0][0]=0;
fo(i,1,n+K)fo(j,0,tmp)fo(s,0,mx)if(((i<=n)&&(s&1))||((i>n)&&(!(s&1)))){
f[i][j][s]=f[i-1][j][s>>1];
g[i][j][s]=s>>1;
h[i][j][s]=0;
if(i-K>0)fd(ii,K,2)if((i-ii+1<=n)&&(!(s&(1<<(ii-1))))&&(i-K<=n))
fd(jj,ii-1,2)if((!(s&(1<<(jj-1))))&&(i-jj+1<=n)){
if(j){
LL tm2=(a[i-K]+a[i-ii+1]+a[i-jj+1])*4,
tm3=pow(a[i-K]*12-tm2,2)+pow(a[i-ii+1]*12-tm2,2)+pow(a[i-jj+1]*12-tm2,2),
tm4=f[i][j][s];
f[i][j][s]=min(f[i][j][s],f[i-1][j-1][(s>>1)+(1<<(K-1))+(1<<(ii-2))+(1<<(jj-2))]+tm3);
if(f[i][j][s]!=tm4)g[i][j][s]=(s>>1)+(1<<(K-1))+(1<<(ii-2))+(1<<(jj-2)),h[i][j][s]=-1;
}
fd(kk,jj-1,2)if((!(s&(1<<(kk-1))))&&(i-kk+1<=n)){
LL tm2=(a[i-K]+a[i-ii+1]+a[i-jj+1]+a[i-kk+1])*3,
tm3=pow(a[i-K]*12-tm2,2)+pow(a[i-ii+1]*12-tm2,2)+pow(a[i-jj+1]*12-tm2,2)+pow(a[i-kk+1]*12-tm2,2),
tm4=f[i][j][s];
f[i][j][s]=min(f[i][j][s],f[i-1][j][(s>>1)+(1<<(K-1))+(1<<(ii-2))+(1<<(jj-2))+(1<<(kk-2))]+tm3);
if(f[i][j][s]!=tm4)g[i][j][s]=(s>>1)+(1<<(K-1))+(1<<(ii-2))+(1<<(jj-2))+(1<<(kk-2)),h[i][j][s]=0;
}
}
}
printf("%lld\n",f[n+K][tmp][0]);
LL j=tmp,s=0,tm2=1;
fd(i,n+K,1){
if(g[i][j][s]!=(s>>1)){
if(h[i][j][s]==-1){
b[i-K]=tm2;
fd(ii,K,2)if((!(s&(1<<(ii-1))))&&(g[i][j][s]&(1<<(ii-2))))
fd(jj,ii-1,2)if((!(s&(1<<(jj-1))))&&(g[i][j][s]&(1<<(jj-2))))b[i-ii+1]=b[i-jj+1]=tm2;
}else{
b[i-K]=tm2;
fd(ii,K,2)if((!(s&(1<<(ii-1))))&&(g[i][j][s]&(1<<(ii-2))))
fd(jj,ii-1,2)if((!(s&(1<<(jj-1))))&&(g[i][j][s]&(1<<(jj-2))))
fd(kk,jj-1,2)if((!(s&(1<<(kk-1))))&&(g[i][j][s]&(1<<(kk-2))))b[i-ii+1]=b[i-jj+1]=b[i-kk+1]=tm2;
}
tm2++;
}
LL tm3=j+h[i][j][s],tm4=g[i][j][s];
j=tm3;s=tm4;
}
fo(i,1,n)printf("%lld ",b[i]);
return 0;
}