时间限制: 1 Sec 内存限制: 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+3双,输出-1,否则输出长度差平方和的最小值。
10 1
1 1 2 3 3 3 4 6 10 20
5
读入后先对筷子长短进行排序,然后相差最小的两根一定是相邻的两根
dp[i,j]表示从第1根筷子到第i根筷子中配出j对最小的平方差之和
var
t,n,s:longint;
i,j,k,l,m:longint;
x:array[0..100]of longint;
dp:array[0..100,0..53]of longint;
function min(a,b:longint):longint;
begin
if a>b
then exit(b)
else exit(a);
end;
procedure sort(l,r: longint);
var i,j,w,y: longint;
begin
i:=l; j:=r; w:=x[(l+r) div 2];
repeat
while x[i]do inc(i);
while wdo dec(j);
if not(i>j)
then
begin
y:=x[i]; x[i]:=x[j]; x[j]:=y;
inc(i); dec(j);
end;
until i>j;
if lthen sort(l,j);
if ithen sort(i,r);
end;
begin
readln(n,s); inc(s,3);
for i:=1 to n do
read(x[i]);
sort(1,n);
for i:=1 to n do
for j:=1 to s do
dp[i,j]:=maxlongint;
for i:=2 to n do
for j:=1 to s do
if j*2<=i
then dp[i,j]:=min(dp[i-2,j-1]+(x[i]-x[i-1])*(x[i]-x[i-1]),dp[i-1,j])
else break;
if dp[n,s]<>maxlongint
then writeln(dp[n,s])
else writeln(-1);
end.
时间限制: 1 Sec 内存限制: 128 MB
中国人吃饭必须要用筷子。C先生与常人不同,他的一副筷子有3只,一对再加上一根比较长的,用来穿比较大的食物。两只较短的筷子的长度应该尽可能接近,但是最长的那根的长度是无所谓的。如果一副筷子的长度分别是A,B,C(A<=B<=C),则用(A-B)2的值表示这副筷子的质量,显然这个值越小,质量越高。
C先生邀请了K个朋友去吃饭,而且他要为每个人准备一副这种特殊的筷子。C先生的家里有8个人,因此你总共必须准备K+8副筷子。不过C先生发现他的筷子有各种各样不同的长度,他必须找到一种办法搭配好K+8副筷子,使得这些筷子的质量值之和最小。
第一行有一个整数T,表示文件中共有T组测试数据。T的值不超过20。每一组测试数据的第一行是两个整数K和N,(0<=K<=1000, 3K+24<=N<=5000)。K是邀请朋友的人数,N是C先生家里储备的筷子总根数。接下来的一行有N个正整数,表示这N根筷子的长度;这N个数是从小到大给出的,并且每一根筷子的长度值不超过32000。
单独一行,表示最小的质量值之和。
1
1 40
1 8 10 16 19 22 27 33 36 40 47 52 56 61 63 71 72 75 81 81 84 88 96 98 103 110 113 118 124 128 129 134 134 139 148 157 157 160 162 164
23
由于要三个筷子,a,b,c要满足a<=b<=c,那么要从后(最大)向前(最小)走
从前向后走会有后效性,即不能满足一定有第三根筷子大于前两根的可能,所以从后向前走
状态转移方程也是倒过来就可以的,约束条件变成j*3<=n-i+1
var
t,n,s:longint;
i,j,k,l,m:longint;
x:array[0..5000]of longint;
dp:array[0..5001,0..1008]of longint;
function min(a,b:longint):longint;
begin
if a>b
then exit(b)
else exit(a);
end;
begin
readln(t);
for l:=1 to t do
begin
readln(s,n); inc(s,8);
for i:=1 to n do
read(x[i]);
for i:=1 to 5001 do
for j:=1 to 1008 do
dp[i,j]:=maxlongint;
for i:=n downto 1 do
for j:=1 to s do
if j*3<=n-i+1
then dp[i,j]:=min(dp[i+2,j-1]+(x[i]-x[i+1])*(x[i]-x[i+1]),dp[i+1,j])
else break;
writeln(dp[1,s]);
end;
end.