先打表然后dfs加剪枝
#include <iostream>
using namespace std;
int ans=0;
int N,M;
int minv[20];
int mins[20];
void dfs(int m,int v,int s,int h,int r)
{
int i,j,t;
if(m==0)
{
if(ans>s&&v==N)
ans = s;
return;
}
if(v+minv[m]>N||s+mins[m]>ans||2*(N-v)/r+s+1>ans)//剪枝
return;
for(i=r-1;i>=m;i--)
{
t = (N-minv[m-1]-v)/(i*i)+1;
j = t>h-1?h-1:t;//剪枝
for(;j>=m;j--)
{
if(m==M)
dfs(m-1,v+j*i*i,i*i+2*j*i,j,i);
else
dfs(m-1,v+j*i*i,s+2*j*i,j,i);
}
}
}
void init()
{
int i;
minv[0] = 0;
mins[0] = 0;
for(i=1;i<20;i++)
{
minv[i] = minv[i-1]+i*i*i;
mins[i] = mins[i-1]+2*i*i;
}
}
int main()
{
cin>>N>>M;
init();
ans = 3*N*N;
dfs(M,0,0,N+1,N+1);
if(ans==3*N*N)
cout<<0<<endl;
else
cout<<ans<<endl;
return 0;
}