和搬寝室类似,注意从大到小排序才能确定一个筷子是否能取,用滚动数组比较省内存
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[1010][6];
int m[5001];
int qqq(int a,int b)
{
return (a-b)*(a-b);
}
int min(int a,int b)
{
return a<b?a:b;
}
bool cmp(int a,int b)
{
return a>b;
}
int main()
{
int r;
cin>>r;
while (r--)
{
memset(dp,0,sizeof(dp));
int k,n;
cin>>k>>n;
k=k+8;
for (int i=1;i<=n;i++)
scanf("%d",&m[i]);
sort(m+1,m+n+1,cmp);
for (int i=1;i<=n;i++)
{
for (int t=min(i/3,k);t>=1;t--)
{
int i1=i%5+1;
int i2=(i+4)%5+1;
int i3=(i+3)%5+1;
dp[t][i1]=dp[t-1][i3]+qqq(m[i],m[i-1]);
if (i-3*t>0)
dp[t][i1]=min(dp[t][i2],dp[t-1][i3]+qqq(m[i],m[i-1]));
//cout<<t<<" "<<i<<" "<<dp[t][i1]<<" "<<dp[t][i2]<<endl;
}
}
cout<<dp[k][n%5+1]<<endl;
}
}