Advertisement
flash_7

Knuth Optimization

Mar 30th, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.85 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int inf = 1e30;
  4. #define Size 1005
  5.  
  6. int N,M;
  7. int A[Size];
  8. int mid[Size][Size];
  9. int DP[Size][Size];
  10. /// DP[i][k] = Minimum total cost to divide first i positions into k partitions.
  11. /// Where the k'th partition ends at position i.
  12. int cost[Size][Size];
  13. int csum[Size];
  14.  
  15. /// Knuth's Conditions:
  16. /// mid[i,j-1] <= mid[i,j] <= mid[i+1,j]
  17. /// Here, mid[i][j] = k represents the index which gives the optimal answer if we make the j'th partition at k.
  18. /// cost[i][j] represents the cost for the interval i to j.
  19. /// For any a,b,c,d where a <= b <= c <= d :
  20. /// cost[a][c] + cost[b][d] <= cost[a][d] + cost[b][c] (quadrangle inequality).
  21. /// cost[b][c] <= cost[a][d] (monotonicity).
  22.  
  23. void costFunction(){
  24.     for(int i = 1;i<=N;i++){
  25.         csum[i] = A[i];
  26.         cost[i][i] = 0;
  27.         for(int j = i+1;j<=N;j++){
  28.             csum[j] = csum[j-1] + A[j];
  29.             cost[i][j] = cost[i][j-1] + csum[j-1]*A[j];
  30.         }
  31.     }
  32. }
  33.  
  34. /// Check if the cost function satisfy knuth conditions:
  35.  
  36. bool knuthValidation(int N){
  37.     int a,b,c,d;
  38.     int A[4];
  39.     /// a <= b <= c <= d
  40.     for(int i = 0;i<1000;i++){
  41.         for(int p = 0;p<4;p++){
  42.             A[p] = rand()%N;
  43.             if(A[p] == 0) A[p] = 1;
  44.         }
  45.         sort(A,A+4);
  46.         a = A[0], b = A[1], c = A[2], d = A[3];
  47.         int ac_bd = cost[a][c] + cost[b][d];
  48.         int ad_bc = cost[a][d] + cost[b][c];
  49.         int bc = cost[b][c];
  50.         int ad = cost[a][d];
  51.         if(ac_bd > ad_bc || bc > ad){
  52.             printf("Knuth Condition Mismatch for (a, b, c, d) = (%d, %d, %d, %d)\n",a,b,c,d);
  53.             return false;
  54.         }
  55.     }
  56.     return true;
  57. }
  58.  
  59. int knuthOptimization(){
  60.     for(int k = 1;k<=M;k++){
  61.         mid[N+1][k] = N;
  62.     }
  63.  
  64.     for(int i = 1;i<=N;i++){
  65.         DP[i][1] = cost[1][i];
  66.         mid[i][1] = 0;
  67.     }
  68.  
  69.     for (int k = 2; k <= M; k++){
  70.         for (int i = N; i >= 1; i--) {
  71.             int L1 = mid[i][k-1];
  72.             int L2 = mid[i+1][k];
  73.             DP[i][k] = inf;
  74.             if(L1>L2){
  75.                 /// Knuth condition mismatch.
  76.             }
  77.             /// The optimal answer lie for an index between (L1 - L2).
  78.             /// So we don't need to check for all (1 - i) to make a partition.
  79.             for(int m = L1;m<=L2 && m<i;m++){
  80.                 int rs = DP[m][k-1] + cost[m+1][i];
  81.                 if(rs < DP[i][k]){
  82.                     DP[i][k] = rs;
  83.                     mid[i][k] = m;
  84.                 }
  85.             }
  86.         }
  87.     }
  88.     return DP[N][M];
  89. }
  90.  
  91. int solve(){
  92.     costFunction();
  93.     if(knuthValidation(N) == false) return -1;
  94.     return knuthOptimization();
  95. }
  96.  
  97. int main () {
  98.     scanf("%d %d",&N,&M);
  99.     M++;
  100.     for(int i = 1;i<=N;i++){
  101.         scanf("%d",&(A[i]));
  102.     }
  103.     int res = solve();
  104.     printf("%d\n",res);
  105.     return 0;
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement