HDU1421
//dp 给定n个数字和k,求找出k对数字使得所有对数字差的平方和最小
//先给其从小到大进行排序,可知选取规则必须是选取相邻的两个数
//状态 dp[i][j]表示从前i个数选j组差的平方和最小
//当j*2==i时即i个数必须选完dp[i][j]=dp[i-2][j-1]+(a[i-1]-a[i])*(a[i-1]-a[i])
//否则dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i-1]-a[i])*(a[i-1]-a[i]))
#include <iostream> #include <algorithm> #include <string.h> using namespace std; int a[2005]; long long dp[2005][1005]; int main() { int n,k; while(cin>>n>>k) { for(int i=1;i<=n;i++) { cin>>a[i]; } sort(a+1,a+n+1); for(int i=1;i<=2002;i++) for(int j=1;j<=1002;j++) dp[i][j]=0; for(int i=2;i<=n;i++) { for(int j=1;j<=k&&2*j<=i;j++) { if(j*2==i) dp[i][j]=dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]); else dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1])); } } cout<<dp[n][k]<<endl; } return 0; }