hdu1500 选n个3组合数,时两小差平方总和最小
先按从大到小排序。。没想到。
这样动态方程比较好想了
dp[i][j]=min(dp[i][j-1],dp[i-1][j-2]+(a[j]-a[j-1])*(a[j]-a[j-1])); j>=3i+1
当j=3i时只能选后一个。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int a[5005],dp[1024][5005]; 6 int cmp(int n1,int n2) 7 { 8 return n1>n2; 9 } 10 int main() 11 { 12 int T,n,i,j,k; 13 scanf("%d",&T); 14 while (T--) 15 { 16 scanf("%d%d",&n,&k); 17 n+=8; 18 for (i=1;i<=k;i++) scanf("%d",&a[i]); 19 sort(a+1,a+k+1,cmp); 20 for (i=0;i<=n;i++) 21 for (j=0;j<=k;j++) { 22 if (i==0) dp[i][j]=0; 23 else dp[i][j]=0x3f3f3f3f; 24 } 25 for (i=1;i<=n;i++) 26 for (j=3*i;j<=k;j++) 27 { 28 dp[i][j]=dp[i-1][j-2]+(a[j]-a[j-1])*(a[j]-a[j-1]); 29 if (j!=3*i&&dp[i][j-1]<dp[i][j]) dp[i][j]=dp[i][j-1]; 30 } 31 printf("%d\n",dp[n][k]); 32 } 33 }