CF571B. Minimization(DP)
题意:
给定一个序列,重新排列这个序列使得最小。
题解:
/* *author: zlc *zucc_acm_lab *just do it */ #include<bits/stdc++.h> using namespace std; typedef long long ll; const double pi=acos(-1.0); const double eps=1e-6; const int mod=1e9+7; const ll inf=2e18; const int maxn=1e6+100; inline ll read () {ll x=0;ll f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;} //inline int read () {int x=0;int f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;} ll qpow (ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;} ll dp[5005][5005]; ll a[maxn]; ll n,k; int main () { n=read(); k=read(); for (int i=1;i<=n;i++) a[i]=read(); sort(a+1,a+n+1); ll t1=n%k; ll t2=k-n%k; ll x=n/k+1; ll y=n/k; for (int i=0;i<5005;i++) for (int j=0;j<5005;j++) dp[i][j]=inf; dp[0][0]=0; for (int i=0;i<=t1;i++) { for (int j=0;j<=t2;j++) { ll tt=i*x+j*y; if (i) dp[i][j]=min(dp[i][j],dp[i-1][j]+a[tt]-a[tt-x+1]); if (j) dp[i][j]=min(dp[i][j],dp[i][j-1]+a[tt]-a[tt-y+1]); } } printf("%lld\n",dp[t1][t2]); return 0; }