http://acm.hdu.edu.cn/showproblem.php?pid=1421
刚开始想的时候,想转化成背包来做,但是不好表示,
然后考虑到dp中的有几个相关元素,这里有两,一个是物品个数,一个是选择的对数,那么有了状态
dp[i][j]表示前i件物品选择j对所付出的代价,那么对于第i件有选与不选两种,所以
dp[i][j]=min((dp[i-2][j-1]+charge(weight[i-1],weight[i])),dp[i-1][j]);
即这件物品要选的话那么前一件和他是一对的,则代价是他们两的代价加上dp[i-2][j-2],如果这件物品不选则dp[i-1][j],前i-1件选j对
初始化的时候要注意,dp【i】【0】=0;

#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #define maxn 2200 #define inf 100000 using namespace std; int weight[maxn]; int dp[maxn][1100]; int charge(int a,int b) { return (a-b)*(a-b); } int min(int a,int b) { return a<b?a:b; } int main() { int n,k; while(scanf("%d%d",&n,&k)!=EOF) { memset(dp,127,sizeof(dp)); /* for(int i=0;i<=10;i++) { for(int j=0;j<=10;j++) cout<<dp[i][j]<<" "; cout<<endl; }*/ memset(weight,0,sizeof(weight)); for(int i=1;i<=n;i++) scanf("%d",&weight[i]); sort(weight+1,weight+1+n);//要排序,因为相邻的差的最小 for(int i=0;i<=n;i++) dp[i][0]=0;//初始化 for(int i=2;i<=n;i++) { for(int j=1;j*2<=i;j++) { dp[i][j]=min((dp[i-2][j-1]+charge(weight[i-1],weight[i])),dp[i-1][j]); } } printf("%d\n",dp[n][k]); } return 0; }