[LuoGu] P1731 生日蛋糕

\(\color{red}{\mathcal{Description}}\)

7月17日是 \(Mr.W\) 的生日,\(ACM-THU\) 为此要制作一个体积为的 \(M\) 层生日蛋糕,每层都是一个圆柱体。设从下往上数第 \(i\) \((1 \leq i \leq M)\) 层蛋糕是半径为 \(R_i\) , 高度为 \(H_i\) 的圆柱。当 \(i<M\) 时,要求 \(R_i>R_{i+1}\)\(H_i>H_{i+1}\) 由于要在蛋糕上抹奶油,为尽可能节约经费,我们希望蛋糕外表面(最下一层的下底面除外)的面积 \(Q\) 最小。令 \(Q = S\pi\) ,请编程对给出的 \(N\)\(M\) ,找出蛋糕的制作方案(适当的 \(R_i\)\(H_i\) 的值),使 \(S\) 最小。(除 \(Q\) 外,以上所有数据皆为正整数)

\(\color{red}{\mathcal{Input\ Format}}\)

有两行,第一行为 \(N\) ,表示待制作的蛋糕的体积为 \(N\pi\);第二行为 \(M\),表示蛋糕的层数为 \(M\)

\(\color{red}{\mathcal{Output\ Format}}\)

仅一行,是一个正整数 \(S\)(若无解则 \(S=0\))。

\(\color{red}{\mathcal{DataSize\ Agreement}}\)

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

\(\color{red}{\mathcal{Hint}}\)

圆柱相关公式:\(V=\pi R^2H\)体积 ;侧面积 \(S'=2 \pi RH\);底面积 \(S=\pi R^2\)

\(\color{red}{\mathcal{Solution}}\)

首先不难想到的是搜索,但直接搜索会很慢,考虑到要加一些剪枝:

可行性剪枝:当前体积加上下一层最小的体积也比 \(n\) 大,不可行;

最优性剪枝:
1、当前面积加上下一层的最小侧面积比记录的 \(ans\) 大,那么该种方案定然不是最优的;
2、如果剩余体积对应的下一层侧面积加上当前面积大于等于 \(ans\) ,该方案不是最优的(必须是大于等于因为下一层的半径取不到当前的 \(r\)

一个小技巧是预处理出每一层的最小体积以及最小面积

\(\color{red}{\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;
}

\(\color{red}{\mathcal{Source}}\)

\(NOI\ 1999\)

posted @ 2019-08-08 23:30  1Mi  阅读(130)  评论(0编辑  收藏  举报
Live2D