Noi 1999 birthday cake

Title Link: Poke me

Pruning search questions
We consider enumerating each layer from large to small

  • If the current volume is greater than the total volume return
  • When enumerating the next layer is [the remaining layers, the - 1 of the previous layer]
  • If the current area plus the possible maximum area is still larger than ans, return
  • If the current volume plus the possible minimum volume is smaller than n, return
  • Area calculation directly brings in parameters, do not reopen function calculation
  • h,r enumeration from \ (\ sqrt n \)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<ctime>
#define MAXN 20
using namespace std;
int n,m;
int r[MAXN],h[MAXN];
int ans=2147483647;
inline int sqr(double x){return x*x;}
inline int calc()
{
    // for(int i=1;i<=m;i++) printf("i=%d r=%d h=%d\n",i,r[i],h[i]);
    int cur_ans=0;
    for(int i=1;i<=m;i++) cur_ans+=r[i]*h[i];
    return cur_ans;
}
inline void search(int pos,int now,int cans)
{
    if(cans+(m-pos+1)+r[1]*r[1]>ans&&pos<=m) return;//The measure of area
    if(now+(m-pos+1)*sqr(r[pos-1])*(h[pos-1])<n&&pos<=m) return;//volume
    if(pos>m)
    {
        if(now==n)
        {
            cans+=r[1]*r[1];
            ans=min(ans,cans);
        }
        return; 
    }
    for(int i=r[pos-1]-1;i>=m-pos+1;i--)
    {
        for(int j=h[pos-1]-1;j>=m-pos+1;j--)
        {
            if(now+sqr(i)*j<=n)
            {
                r[pos]=i;
                h[pos]=j;
                search(pos+1,now+sqr(i)*j,cans+2*i*j);
                r[pos]=0,h[pos]=0;
            }
        }
    }
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    // freopen("ce.out","w",stdout);
    #endif
    scanf("%d%d",&n,&m);
    h[0]=(int)sqrt(n);
    r[0]=(int)sqrt(n);
    search(1,0,0);
    printf("%d\n",ans);
    // cout<<(double)clock()/CLOCKS_PER_SEC<<endl;
    return 0;
}

Keywords: PHP

Added by Nexy on Sun, 03 Nov 2019 05:34:49 +0200