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;
}
posted @ 2020-11-10 14:52  Tartarus_li  阅读(85)  评论(0编辑  收藏  举报