您的位置:首页 > 其它

[POJ 1190] 生日蛋糕

2015-07-19 21:50 330 查看
http://poj.org/problem?id=1190

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

[code]#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: