• 洛谷 P1731 [NOI1999] 生日蛋糕


    Description

    P1731 [NOI1999] 生日蛋糕

    Solution

    明显的就是搜索(但是我一点都不会写,我好蒻啊)。

    首先一定是从下往上搜,如果从上往下的话就没有上界了,容易一搜到底。

    然后再考虑这么几个优化:

    • 当前体积 (> n),返回。

    • 当前层数 (> m),返回。

    • 当前面积 (geq) 已经搜到的最大面积,返回。

    • 当前体积 (+) 之后的最大体积 (< n),返回。

    • 当前表面积 (+) 之后最大表面积 (geq) 已经搜到的答案,直接返回(emm……有了这条前面那个好像就不用了,算了不管了)。

    (dfs) 时,记录一下当前层数,剩余体积,当前侧面积

    半径,高度的枚举,从上一层的半径,高度开始,一直到还需要的层数即可,每层都留一个 1.

    Code

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    int n, m, ans = INF;
    int r[30], h[30];
    
    inline void dfs(int x, int v, int res){//x:层数  v:剩余体积  res:当前表面积
    	int tmp = m - x + 1;//还需要多少层
    	if(v < 0 || x > m + 1 || res >= ans) return;
    	if(!v && x == m + 1){
    		res += r[1] * r[1];
    		ans = min(ans, res);
    		return;
    	}
    	if(res + tmp + r[1] * h[1] > ans) return;
    	if(v - r[x - 1] * r[x - 1] * h[x - 1] * tmp > 0) return;
    	for(int i = r[x - 1] - 1; i >= tmp; i--){
    		for(int j = h[x - 1] - 1; j >= tmp; j--){
    			if(v - i * i * j >= 0 && x <= m){
    				r[x] = i, h[x] = j;
    				dfs(x + 1, v - i * i * j, res + (2 * i * j));
    				r[x] = h[x] = 0;
    			}
    		}
    	}
    }
    
    int main(){
    	scanf("%d%d", &n, &m);
    	r[0] = h[0] = (int)sqrt(n);
    	dfs(1, n, 0);
    	printf("%d
    ", ans == INF ? 0 : ans);
    	return 0;
    }
    

    End

    本文来自博客园,作者:xixike,转载请注明原文链接:https://www.cnblogs.com/xixike/p/15379054.html

  • 相关阅读:
    DS博客作业05--查找
    DS博客作业04--图
    DS博客作业03--树
    栈和队列
    第六次作业
    第五次作业
    第四次作业
    第三次作业
    java任务
    第三周-自主学习任务-面向对象基础与类的识别
  • 原文地址:https://www.cnblogs.com/xixike/p/15379054.html
Copyright © 2020-2023  润新知