AcWing 168 生日蛋糕 (搜索 + 剪枝)
题目链接:https://www.acwing.com/problem/content/170/
剪枝剪枝剪枝。。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 21;
const int INF = 1000000007;
int N, M, ans;
int miV[20], miS[20];
void dfs(int d, int R, int H, int S, int V){
if(S >= ans || S + miS[M - d] >= ans || S + 2 * (N - V) / R >= ans) return;
if(d == M){
if(V == N) ans = min(ans, S);
return;
}
for(int r = min(R - 1, (int) sqrt(N - V)) ; r >= 1; --r){
for(int h = min(H - 1, (N - V) / (r * r)) ; h >= 1; --h){
if(V + r * r * h > N || V + miV[M - d] > N) continue;
dfs(d + 1 , r, h, S + 2 * r * h, V + r * r * h);
}
}
}
ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }
int main(){
for(int i = 1; i <= 20 ; ++i ){
miV[i] = miV[i-1] + i * i * i;
miS[i] = miS[i-1] + 2 * i * i;
}
N = read(), M = read(); ans = INF;
for(int R = (int)sqrt(N) ; R >= 1; --R){
for(int H = (N / (R * R)) ; H >= 1; --H){
dfs(1, R, H, 2 * R * H + R * R, R * R * H);
}
}
if(ans == INF) printf("0\n");
else printf("%d\n",ans);
return 0;
}