生日蛋糕 POJ

http://poj.org/problem?id=1190

题解:四个剪枝。

#define _CRT_SECURE_NO_WARNINGS
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<cmath>
#include<cstdio>
#include<string>
#include<stack>
#include<ctime>
#include<list>
#include<set>
#include<map>
#include<queue>
#include<vector>
#include<sstream>
#include<iostream>
#include<functional>
#include<algorithm>
#include<memory.h>
//#define INF 0x3f3f3f3f
#define eps 1e-6
#define pi acos(-1.0)
#define e exp(1.0)
#define rep(i,t,n)  for(int i =(t);i<=(n);++i)
#define per(i,n,t)  for(int i =(n);i>=(t);--i)
#define mp make_pair
#define pb push_back
#define mmm(a,b) memset(a,b,sizeof(a))
//std::ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
void smain();
#define ONLINE_JUDGE
int main() {
//    ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long _begin_time = clock();
#endif
    smain();
#ifndef ONLINE_JUDGE
    long _end_time = clock();
    printf("time = %ld ms.", _end_time - _begin_time);
#endif
    return 0;
}
int n, m;
int mn = 1 << 30;
int area = 0;
int mnV[30];
int mnA[30];
int maxVforNRH(int n, int r, int h) {
    int v = 0;
    rep(i, 0, n - 1) 
        v += (r - i)*(r - i)*(h - i);
        return v;
    
}
void  dfs(int v,int n,int r,int h) {//n层凑v,底层不超r,h
    if (n == 0) {
        if (v)return;
        else {
            mn = min(mn, area);
            return;
        }
    }
    if (v <= 0)return;
    if (mnV[n] > v)return;//3
    if (area + mnA[n] >= mn)return;//1
    if (h < n || r < n)return; //2
    if (maxVforNRH(n,r,h)< v)return;//4
    per(rr, r, n) {
        if (n == m)area = rr*rr;
        per(hh, h, n) {
            area += 2 * rr*hh;
            dfs(v - rr*rr*hh, n - 1, rr - 1, hh - 1);
            area -= 2 * rr*hh;
        }
    }
}
void Run() {
    
}

void smain() {
    
    cin >> n >> m;
    mnV[0] = 0;
    mnA[0] = 0;
    rep(i, 1, m) {
        mnV[i] = mnV[i - 1] + i*i*i;
        mnA[i] = mnA[i - 1] + 2 * i*i;
    }
    if (mnV[m] > n)cout << 0 << endl;
    else {
        int maxH = (n - mnV[m - 1]) / (m*m) + 1;
        int maxR = sqrt(double(n - mnV[m - 1]) / m) + 1;//底层最大的H,R
        area = 0;
        mn = 1 << 30;
        dfs(n, m, maxH, maxR);
        if (mn == 1 << 30) {
            cout << 0 << endl;

        }
        else cout << mn << endl;
    }
    Run();
}
成功的路并不拥挤,因为大部分人都在颓(笑)
原文地址:https://www.cnblogs.com/SuuT/p/8984550.html