http://acm.hdu.edu.cn/showproblem.php?pid=1421
因为考虑到差的平方最小,所以先把物品按重量排序(这样可以使相邻的两个数更加接近从而取得更优的结果)。
dp[i][j]表示i件物品拿j对时最低的疲劳度
i等于2*j时,dp[i][j]=dp[i-2][j-1]+(w[i]-w[i-1])^2
其他情况时(即i大于2*j), dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(w[i]-w[i-1])^2)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <algorithm> using namespace std ; int dp[2001][1001],w[2001] ; bool cmp(int a,int b) { return a<b ; } int main() { int n,k ; while(~scanf("%d%d",&n,&k)) { for(int i=1;i<=n;i++) scanf("%d",&w[i]) ; sort(w+1,w+n+1,cmp) ; memset(dp,0,sizeof(dp)) ; for(int i=2;i<=n;i++) for(int j=1;(j<<1)<=i;j++) { if(i==(j<<1)) dp[i][j]=dp[i-2][j-1]+(w[i]-w[i-1])*(w[i]-w[i-1]) ; else dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(w[i]-w[i-1])*(w[i]-w[i-1])) ; } printf("%d\n",dp[n][k]) ; } return 0 ; }