题解 【打饭】

【题目描述】

\(n\) 个小朋友来食堂吃饭,他们排成长度为 \(n\) 的一个队伍。

小朋友看到别的小朋友比自己菜好会不高兴,两个小朋友i和j能互相看到对方的菜当且仅当 \(\operatorname{abs}(i-j)==k\),产生的不高兴值是 \(\operatorname{abs}(a_i-a_j)\)\(\operatorname{abs}\) 是取绝对值符号,\(a_i\) 表示第i位小朋友菜丰盛的程度,换言之,如果菜的丰盛值按顺序排列是序列 \(A\),那么产生的不高兴值为

\[\sum\limits_{i=1}^{n-k} abs(a[i]-a[i+k]) \]

如果小朋友产生的不高兴值和太大他们会哭,你现在有 \(n\) 盘菜,请你合理安排上菜顺序,使得产生不高兴值的和最小,输出这个值。

【输入格式】

第一行输入两个正整数 \(n\)\(k\)

第二行 \(n\) 个整数,表示第 \(i\) 盘菜的丰盛值 \(a_i\)

【输出格式】

一个数表示最小的不高兴值和

【样例输入输出】

【输入 #1】
3 2
1 2 4
【输出 #1】
1
【输入 #2】
5 2 
1 3 1 3 1
【输出 #2】
0
【输入 #3】
6 3 
4 3 4 3 2 5
【输出 #3】
3

【数据范围与提示】

对于 \(30\%\) 的数据,满足 $n \leq 10 $

对于 \(50\%\) 的数据,满足 $n,k \leq 5000 $

对于另外 \(30\%\) 的数据,满足 \(n\)\(k\) 的倍数

对于 \(100\%\) 的数据,满足 \(n \leq 300000,k \leq min(n-1,5000), -10^9 \leq a_i \leq 10^9\)

时间限制:\(1 \text {s}\)

空间限制:\(512 \text {MB}\)


题目可以转换为:在一个排好序的数列中,求几个区间相邻的每个数的差

因为每相邻 \(k\) 个求一次差,所以每个区间的长度只可能是 \(n/k\)\(n/k+1\)

\(f_{i,j}\) 表示取 \(i\) 个长度为 \(n/k\) 的区间和 \(j\) 个长度为 \(n/k+1\) 的区间的不高兴值的和最小值是多少

然后我们可以得到转移方程

\(f[i+1][j]=\min(f[i+1][j],f[i][j]+a[(i+1)*(n/k+1)+j*(n/k)]-a[i*(n/k+1)+j*(n/k)+1])\)

\(f[i][j+1]=\min(f[i][j+1],f[i][j]+a[i*(n/k+1)+(j+1)*(n/k)]-a[i*(n/k+1)+j*(n/k)+1])\)

然后就好了αωα

#include<bits/stdc++.h>
#define rint register long long
#define int long long
using namespace std;
inline int read(){
    int s=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=0;c=getchar();}
    while(c>='0'&&c<='9')s=(s<<1)+(s<<3)+c-48,c=getchar();
    return f?s:-s;
}
int n,k,a[300010],now,ans;
int f[5010][5010];
signed main(){
    freopen("rice.in","r",stdin);
    freopen("rice.out","w",stdout);
    n=read(); k=read();
    for(rint i=1;i<=n;++i) a[i]=read();
    sort(a+1,a+1+n);
    memset(f,0x3f,sizeof f);
    f[0][0]=0;
    int m_k1=n%k,m_k2=k-n%k;
    for(int i=0;i<=m_k1;++i)
        for(int j=0;j<=m_k2;++j){
        if(i!=m_k1) f[i+1][j]=min(f[i+1][j],f[i][j]+a[(i+1)*(n/k+1)+j*(n/k)]-a[i*(n/k+1)+j*(n/k)+1]);
        if(j!=m_k2) f[i][j+1]=min(f[i][j+1],f[i][j]+a[i*(n/k+1)+(j+1)*(n/k)]-a[i*(n/k+1)+j*(n/k)+1]);
    }
    printf("%lld",f[m_k1][m_k2]);
    return 0;
}
posted @ 2020-03-29 13:39  LCGUO  阅读(218)  评论(1编辑  收藏  举报