Birthday cake (pruning)

Insert picture description here

Idea: We search from bottom to top, that is, search upwards with large volume and surface area. We use R[i] and H[i] to record the height and radius of each layer. Pay attention to the process of enumerating r and h His value range. The minimum cannot be less than the current number of layers, and the h, r of each layer should be less than the inner layer below him. Then there is pruning.

1. So far, the volume + the volume of this layer cannot be greater than the total volume.

2. The area so far + the area of ​​this layer cannot be greater than the total area.

3. The inequality with the minimum side area can be obtained from the remaining volume.

n − v = ∑ i = 0 d e p r [ i ] 2 h [ i ] n-v=\sum_{i=0}^{dep} r[i]^2 h[i] nv=i=0depr[i]2h[i]

s d e p = ∑ i = 0 d e p 2 r [ i ] h [ i ] = 2 r [ d e p + 1 ] ∑ i = 0 d e p r [ i ] h [ i ] ∗ r [ d e p + 1 ] ≥ 2 r [ d e p + 1 ] ∑ i = 0 d e p r [ i ] 2 h [ i ] = 2 ( n − v ) r [ d e p + 1 ] s_{dep}=\sum_{i=0}^{dep}2r[i]h[i]=\frac2{r[dep+1]}\sum_{i=0}^{dep}r[i]h[i] *r[dep+1]\geq\frac2{r[dep+1]}\sum_{i=0}^{dep} r[i]^2 h[i]= \frac{2(n-v)}{r[dep+1]} sdep=i=0dep2r[i]h[i]=r[dep+1]2i=0depr[i]h[i]r[dep+1]r[dep+1]2i=0depr[i]2h[i]=r[dep+1]2 ( n - v )

No solution when sdep + s >= ans s_{dep}+s>=ans No solution sdep+s>=A n- S when no solution

#pragma GCC optimize(2)
#include<bits/stdc++.h>
 
using namespace std;
typedef long long ll;
#define SIS std::ios::sync_with_stdio(false)
#define space putchar(' ')
#define enter putchar('\n')
#define lson root<<1
#define rson root<<1|1
typedef pair<int,int> PII;
typedef pair<int,PII> PIII;
const int mod=1e9+7;
const int N=2e5+5;
const int inf=0x7f7f7f7f;

int gcd(int a,int b)
{
    
    
    return b==0?a:gcd(b,a%b);
}
 
ll lcm(ll a,ll b)
{
    
    
    return a*(b/gcd(a,b));
}
 
template <class T>
void read(T &x)
{
    
    
    char c;
    bool op = 0;
    while(c = getchar(), c < '0' || c > '9')
        if(c == '-')
            op = 1;
    x = c - '0';
    while(c = getchar(), c >= '0' && c <= '9')
        x = x * 10 + c - '0';
    if(op)
        x = -x;
}
template <class T>
void write(T x)
{
    
    
    if(x < 0)
        x = -x, putchar('-');
    if(x >= 10)
         write(x / 10);
    putchar('0' + x % 10);
}
ll qsm(int a,int b,int p)
{
    
    
    ll res=1%p;
    while(b)
    {
    
    
        if(b&1)
            res=res*a%p;
        a=1ll*a*a%p;
        b>>=1;
    }
    return res;
}
int n,m;
int ans=inf;
int R[N],H[N];
int minv[N],mins[N];
void dfs(int u,int v,int s)
{
    
    
    if(minv[u]+v>n)return ;
    if(mins[u]+s>=ans) return ;
    if(s+2*(n-v)/R[u+1]>=ans)return ;
    if(!u){
    
    
        if(n==v)ans=s;return ;
    }
    for(int r=min((int)sqrt(n-v),R[u+1]-1);r>=u;r--)
    {
    
    
       for(int h=min((n-v)/(r*r),H[u+1]-1);h>=u;h--)
       {
    
    
           int t=0;
           if(u==m) t=r*r;
           R[u]=r;H[u]=h;
           dfs(u-1,v+h*r*r,t+s+2*r*h);
       }
    }
}
int main()
{
    
    

   
   cin>>n>>m;
   for(int i=1;i<=m;i++)
   {
    
    
     minv[i]=minv[i-1]+i*i*i;
     mins[i]=mins[i-1]+2*i*i;
   }
   R[m+1]=H[m+1]=inf;
   dfs(m,0,0);
   if(ans==inf)
   cout<<0<<endl;
   else
   cout<<ans<<endl;
   
    
       

   
      
   return 0;

}


Guess you like

Origin blog.csdn.net/qq_43619680/article/details/112464409