题意:给你一堆数,让你组成m个集合,集合的价值是集合内元素的最大值与最小值的差的平方,求m个集合的价值总和最小
思路:
先给出TLE代码,斜率优化下次给出,转移方程dp[i][j]=min(dp[i][j],dp[i-1][k]+(a[j]-a[k+1])*(a[j]-a[k+1]));(ps:tzw竟然说买包烟十个人,九个人都会斜率优化过题,emmm)
#include <bits/stdc++.h> using namespace std; const int maxn=10005; const int inf=0x3f3f3f3f; int a[maxn],dp[maxn][maxn]; int que[maxn]; int n,m; int main() { int T; scanf("%d",&T); int cas=1; while(T--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } sort(a+1,a+1+n); for(int i=0;i<=m;i++){ for(int j=0;j<=n;j++){ if(j==0)dp[i][j]=0; else dp[i][j]=inf; } } for(int i=1;i<=m;i++){ for(int j=1;j<=n;j++){ for(int k=0;k<j;k++){ dp[i][j]=min(dp[i][j],dp[i-1][k]+(a[j]-a[k+1])*(a[j]-a[k+1])); // printf("test %d dp[%d][%d] == %d\n",k,i,j,dp[i][j]); } } } // for(int i=0;i<=m;i++){ // for(int j=0;j<=n;j++){ // printf("%d ",dp[i][j]); // } // puts(""); // } printf("Case %d: %d\n",cas++,dp[m][n]); } return 0; }