[POJ 1190] 生日蛋糕

http://poj.org/problem?id=1190
集训队测试的时候老师找了这样一题,第一眼以为是个DP,但是发现DP的话内存不够用啊,无奈最后没写出来,百度之后发现居然是个搜索,不过对于数学太弱的我来说肯定是想不到的,因为要知道确定体积后把后面的全部做成一个圆柱的时候表面积是最小的。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

int n, m, minn;
int mins[25],minv[25]; //保存对应深度的最小体积和面积

void Init()
{
    minv[0] = 0;
    mins[0] = 0;
    for(int i = 1; i <= 20; i++){
        mins[i] = mins[i-1] + 2*i*i; //i层的蛋糕最底层的最小半径和高度都是i。
        minv[i] = minv[i-1] + i*i*i; 
    }
}

int Dfs(int deep, int sums, int sumv, int maxr, int maxh)//深度,已经算过的面积和体积,最大半径和高度
{
    if(deep == 0){
        if(sumv == n && sums < minn)
            minn = sums;
        return 0;
    }
    if(sumv + minv[deep] > n || sums + mins[deep] > minn || 2*(n - sumv)/maxr + sums >= minn)//剪枝
        return 0;
    for(int i = maxr; i >= deep; i--){
        if(deep == m)
            sums = i*i;
        for(int k = min((n - sumv - minv[deep-1])/(i*i), maxh); k >= deep; k--){//确定半径求最小高度
            Dfs(deep-1, sums+2*i*k, sumv+i*i*k, i-1, k-1);
        }
    }
}

int main()
{
    Init();
    //freopen("D:\\7.in", "r", stdin);
    while(cin>>n>>m){
        minn = 10000000;
        Dfs(m, 0, 0, n, n);
        if(minn == 10000000)
            minn = 0;
        cout<<minn<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

achonor

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值