深搜优化 生日蛋糕 from 王 (快速读数示范)

 #include<iostream>
#include<cstdio>
#include<cmath>
#define f(i,a,b)    for(register int i=a;i<=b;++i)
#define fd(i,a,b)    for(register int i=a;i>=b;--i)
using namespace std;
const int N=20000+7;
int ans=987654321,n,m,Minv[N],Mins[N];
int read()
{
      int num=0;
      char c;
      while(isspace(c=getchar()));
      while(num=num*10+c-48,isdigit(c=getchar()));
      return num;
}
bool flag=1;
void dfs(int now,int S,int V,int lasth,int lastr)
{
    if(now==0) 
    {
        if(V==n)    ans=min(ans,S);
        return;
    }
    if(S+2*(n-V)/lastr>ans)    return;
    if(V+Minv[now]>n) return;
    if(S+Mins[now]>ans)    return;
    fd(i,lastr-1,now)
    {
        if( now==m)    S=i*i;
        int Maxh=min(lasth-1,(n-V-Minv[now-1])/(i*i));
        fd(j,Maxh,now) 
            dfs(now-1,S+2*i*j,V+i*i*j,j,i);
    }
}
int main()
{
    n=read();m=read();
    f(i,1,m)
        Minv[i]=Minv[i-1]+i*i*i,
        Mins[i]=Mins[i-1]+2*i*i;
    int MaxR=sqrt(n);
    dfs(m,0,0,n,MaxR);
    printf("%d",ans==987654321 ? 0 :ans);
    return 0;
posted @ 2018-08-17 17:30  StoneXie  阅读(142)  评论(0)    收藏  举报