题目大意是说,有n跟筷子,分给k+3个人,每人一双,求这两双长度平方差的和的最小值(叙述是不是有问题QWQ)
这道题经过仔细读题不难发现,在针对排好序的筷子长度中对于每只筷子只有用或不用两种状态。
如果要用,显然加上的代价是(a[i]-a[i-1])^2,此时还有一个隐藏信息,此时第i-2根和第i-1显然不是一对。
如果不用,便是第i-1双时的最小代价。
因此得到状态转移方程:f[i][j]=min(f[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]),f[i-1][j]);
其中,f[i][j]表示有i个人,j个筷子的最小代价。
(和背包的思路大致相同,但作为蒟蒻并不知道怎么优化为一维DP)
直接上代码:
#include <bits/stdc++.h>
using namespace std;
const int INF=0x7F7F7F7F;
int a[105],f[105][105];
int main()
{
memset(f,INF,sizeof(f));
int k,i,j,n,t;
cin >> n >> k;
k+=3;
for (i=1;i<=n;i++)
cin >> a[i];
sort(a+1,a+n+1);
if (k*2>n){
cout << "-1" << endl;
return 0;
}
for(i=0;i<=n;i++)
f[i][0]=0;
for(i=2;i<=n;i++)
for(j=1;j<=k;j++)
f[i][j]=min(f[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]),f[i-1][j]);
cout << f[n][k] << endl;
return 0;
}
ps:由于作者是一名资深蒟蒻,有错误也是不可避免的事,所以欢迎大家指出错误,我也会改正的,谢谢。