1. 程式人生 > 實用技巧 >B. Minimization(DP)

B. 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; }