http://acm.hdu.edu.cn/showproblem.php?pid=3480
Given a set of numbers S, size n, which requires that the set be divided into m subsets, each sub-subset of the cost is a subgroup (Max-min) ^2, to find the minimum cost.
The beginning of DP transfer is easy to imagine.
First, the collection is ordered from small to large, and dp[i][j] represents the minimum cost of the first I element being divided into J subsets. Then enumerate the last subset.
DP[I][J] = Min{dp[k-1][j-1] + cost (k, i)};
This transfer is obviously difficult, n<10000 m<5000. But I did it on purpose. And then use the new pose you see today. Optimization of quadrilateral inequalities.
This optimization looked at the day, roughly understand that it is based on satisfying quadrilateral inequalities, the decision array is monotonic, and then can be obtained through this monotonicity of the current decision-making interval. This greatly reduces the time of class enumeration K, thus reducing the complexity of O (n^3) to O (n^2);
We can prove that cost (I, j) satisfies the quadrilateral inequalities. Then introduced DP[I][J] is also satisfied. Then the decision array satisfies s[i][j-1] <= s[i][j] <= s[i+1][j];
Thus we will first calculate dp[i][j-1] and dp[i+1][j]. So the DP array is enumerated from the lower left corner. That is, first enumerate J (1~m) and then reverse enumeration I (n~1). Then make a decision in each step. And the cycle of k can be narrowed.
The initialization of the DP array and the decision array should be noted.
/*********************************************** * * Problem ID:hdu_3480.cpp * * Create Time:sat 08 15:44:32 20 * * * auther name:xuelanghu * * Auther blog:blog.csdn.net/xuelanghu407 **********************************************/ #include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace STD;Const intMAXINT =999999999;intN, M;inta[10010];intdp[10010][ the];ints[10010][ the];intCost (int_a,int_b) {return(A[_b]-a[_a]) * (A[_b]-a[_a]); }intMain () {intTscanf("%d", &t); for(intI_case =1; i_case<=t; i_case++) {scanf("%d%d", &n, &m); for(intI=1; i<=n; i++) {scanf("%d", &a[i]); } sort (A +1, a+n+1); for(intI=0; i<n; i++) {s[i][0] =1; } for(intI=1; i<=n; i++) {s[n+1][i] = n; }memset(DP,0,sizeof(DP)); for(intI=1; i<=n; i++) {dp[i][1] = Cost (1, i); } for(intj=2; j<=m; J + +) { for(intI=n; i>=1; i--) {Dp[i][j] = MAXINT; for(intk=s[i][j-1]; k<=s[i+1][J]; k++) {if(Dp[i][j] > dp[k-1][j-1] + cost (k, i)) {Dp[i][j] = dp[k-1][j-1] + cost (k, i); S[I][J] = k; } } } }printf("Case%d:%d\n", I_case, dp[n][m]); }return 0;}
This optimization I also do not understand, the specific content and so I understand in carefully write a blog (//Maybe I forget it is not necessary to write =. =
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Optimization of HDU 3480 DP quadrilateral Inequalities