$ [NOI1999] $ birthday cake

\(\mathcal{Description}\)

July 17 is \ (Mr.W \) birthday, \ (the THU-the ACM \) for this purpose to create a volume of \ (M \) layer birthday cake, are each a cylinder. Set up from under the number \ (I \) \ ((. 1 \ Leq I \ Leq M) \) layer cake with a radius \ (R_i \) , height \ (H_i \) cylinder. When (i \ <M \) , the required \ (R_i> R_ {i + 1} \) and \ (H_i> H_ {i + 1} \) due to rubbed cream cake, cost reduction is possible, we hope (lowermost layer under the bottom surface excluding) the area of the outer surface of the cake \ (Q \) minimum. Order \ (Q = S \ PI \) , to program a given \ (N \) and \ (M \) , to find the cake recipe programs (appropriate \ (R_i \) and \ (H_i \) of value), so that \ (S \) minimum. (Except \ (Q \) , all the above data are all positive integer)

\(\mathcal{Input\ Format}\)

There are two rows, the first row \ (N \) , represents the volume of the cake to be made to \ (N \ PI \) ; a second behavior \ (M \) , represents the number of layers of cake \ (M \) .

\(\mathcal{Output\ Format}\)

Only one row is a positive integer \ (S \) (if no solution is \ (S = 0 \) ).

\(\mathcal{DataSize\ Agreement}\)

\ (1 \ leq N \ leq 20000, 1 \ leq M \ leq 15 \) .

\(\mathcal{Solution}\)

First is difficult to think of search, direct search will be very slow, considering to add some pruning:

Feasibility of pruning: the current level plus the smallest volume than \ (n-\) large, is not feasible;

Optimal Pruning:
1, plus the minimum current area side than the recording layer at the area of \ (ANS \) is large, the kinds of programs that will certainly not optimal;
2, if the lower layer side of the area corresponding to the remaining volume plus the current area is not less than \ (ANS \) , this solution is not optimal (must be greater than equal to the radius of the next layer because of not taking the current \ (R & lt \) )

A pretreatment tips of the minimum volume of each layer, and the minimum area

\(\mathcal{Code}\)

#include <bits/stdc++.h>
#define LL long long
#define reg register

using namespace std;

const int kMax = 21;
const int inf = 0x7f7f7f7f;

int mins[kMax], minv[kMax];
int N, M, Ans = inf;

void dfs(int v, int s, int p, int r, int h) {
  if (p == 0) {
    if (v == N) Ans = min(Ans, s);
    return ;
  }
  if (v + minv[p - 1] > N) return ; // 可行性剪枝 
  if (s + mins[p - 1] > Ans) return ;  // 最优性剪枝
  if (s + (N - v) / r * 2 >= Ans) return ; //最优性剪枝
  for (reg int i = r - 1; i >= p; --i) {
    if (p == M) s = i * i;
    int minh = min(h - 1, (N - v - minv[p - 1]) / (i * i));
    for (reg int j = minh; j >= p; --j)
      dfs(v + i * i * j, s + 2 * i * j, p - 1, i, j);
  }
}

int main() {
  scanf("%d%d", &N, &M);
  for (reg int i = 1; i <= 20; ++i) mins[i] = mins[i - 1] + i * i, minv[i] = minv[i - 1] + i * i * i;
  dfs(0, 0, M, N + 1, N + 1);
  printf("%d\n", (Ans == inf ? 0 : Ans));
  
  return 0;
}

Guess you like

Origin www.cnblogs.com/1miharu/p/11324527.html