1. 程式人生 > >COGS 384. 筷子

COGS 384. 筷子

log stream pre color print algo cout using turn

★☆ 輸入文件:chop.in 輸出文件:chop.out 簡單對比
時間限制:1 s 內存限制:128 MB

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

思路:一個筷子有3種狀態,就是什麽都不選,選前面的,選後面的

於是 選前面的筷子可以看做前面的筷子選後面的筷子

於是就剩下2中狀態了

f[i][j]表示第i個筷子,前面已經選了j對,的最小的差的平方和

#include<algorithm>
#include
<iostream> #include<cstring> #include<cstdio> #include<cmath> #define maxn 1000010 #define maxm 1010 using namespace std; int n,k,l[maxn],minn,f[maxm][maxm],jud; bool vis[maxn]; int main() { //freopen("chop.in","r",stdin); //freopen("chop.out","w",stdout); memset(f,0x7f
,sizeof(f)); f[0][0]=0; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) scanf("%d",&l[i]),jud++; if(jud<2*k+6) { cout<<"-1"<<endl; return 0; } else { sort(l+1,l+n+1); for(int i=2;i<=n;i++) for(int j=1;j<=k+3;j++) f[i][j]=min(f[i-1][j],f[i-2][j-1]+(int)pow((l[i]-l[i-1]),2)); printf("%d",f[n][k+3]); } return 0; }

COGS 384. 筷子