384. 筷子
A先生有很多双筷子。确切的说应该是很多根,因为筷子的长度不一,很难判断出哪两根是一双的。这天,A先生家里来了K个客人,A先生留下他们吃晚饭。加上A先生,A夫人和他们的孩子小A,共K+3个人。每人需要用一双筷子。A先生只好清理了一下筷子,共N根,长度为T1,T2,T3,……,TN.现在他想用这些筷子组合成K+3双,使每双的筷子长度差的平方和最小。(怎么不是和最小??这要去问A先生了,呵呵)
输入
输入文件共有两行,第一行为两个用空格隔开的整数,表示 N,K(1≤N≤100, 0<K<50),第二行共有N个用空格隔开的整数,为Ti.每个整数为1~50之间的数。
输出
输出文件仅一行。如果凑不齐 K+3双,输出-1,否则输出长度差平方和的最小值。
样例
chop.in
10 1
1 1 2 3 3 3 4 6 10 20
chop.out
5
说明
第一双 1 1
第二双 2 3
第三双 3 3
第四双 4 6
(1-1)^2+(2-3)^2+(3-3)^2+(4-6)^2=5
虽然是动规 但我一开始傻了吧唧的直接算相邻的筷子的平方最小和
1 /* 2 一道简单的动规 3 f[i][j] 表示前i根筷子选了j对 4 当前筷子不选 f[i-1][j] 5 当前筷子选 f[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]) 6 因为先sort一遍 所以相邻的筷子更优 7 */ 8 #include <cctype> 9 #include <cstdio> 10 #include <cstring> 11 #include <algorithm> 12 13 using namespace std; 14 15 const int MAXN=110; 16 17 int n,k,ans; 18 19 int a[MAXN],f[MAXN][MAXN]; 20 21 inline void read(int&x) { 22 int f=1;register char c=getchar(); 23 for(x=0;!isdigit(c);c==‘-‘&&(f=-1),c=getchar()); 24 for(;isdigit(c);x=x*10+c-48,c=getchar()); 25 x=x*f; 26 } 27 28 int hh() { 29 freopen("chop.in","r",stdin); 30 freopen("chop.out","w",stdout); 31 read(n);read(k);k+=3; 32 for(int i=1;i<=n;++i) read(a[i]); 33 if(k*2>n) { 34 printf("-1\n"); 35 return 0; 36 } 37 sort(a+1,a+1+n); 38 memset(f,0x3f3f,sizeof f); 39 f[0][0]=0; 40 for(int i=2;i<=n;++i) 41 for(int j=1;j<=k;++j) 42 f[i][j]=min(f[i-1][j],f[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1])); 43 printf("%d\n",f[n][k]); 44 return 0; 45 } 46 47 int sb=hh(); 48 int main(int argc,char**argv) {;}
代码
时间: 2024-10-06 07:12:43