您的位置:首页 > 理论基础 > 计算机网络

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

2013-08-10 10:54 351 查看
/*
此题是对半径和高的枚举搜索,但要进行剪枝
*/
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int n,m,minv[21],mins[21],best;
void dfs(int M,int v,int s,int r,int h)
{
int i,j,hmax;
if(M==0) {
if(v==n&&s<best) best=s;
return ;
}
if(v+minv[M]>n||s+mins[M]>=best||2*(n-v)/r+s>=best) return ;
//进行剪枝当前体积与剩下M层的最小体积大于n
//侧面积与剩下M层的最小侧面积大于等于best
/*剩下M层的侧面积为lefts=2*(r[k]*h[k]+...+r[m]*h[m]) , k=(M+1,..,m)
lefts>2*(n-v)/r; lefts=best-s;
*/
for(i=r-1;i>=M;i--)
{
if(M==m) s=i*i;
hmax=min((n-v)/(i*i),h-1);
for(j=hmax;j>=M;j--)
dfs(M-1,v+i*i*j,s+2*i*j,i,j);
}
}
int main(int argc, char *argv[])
{
int i,rmax,hmax;
minv[0]=0; mins[0]=0;
for(i=1;i<21;i++)
mins[i]=mins[i-1]+2*i*i,minv[i]=minv[i-1]+i*i*i;
//数组mins,minv记录在该层的最小面积和体积,在等于i时取得;
while(cin>>n>>m)
{
rmax=sqrt(1.0*n)+1;
hmax=n/(m*m)+1;
best=1000000;
dfs(m,0,0,rmax,hmax);
if(best==1000000) best=0;
cout<<best<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: