程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> http://poj.org/problem?id=1190

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

編輯:C++入門知識

/*
此題是對半徑和高的枚舉搜索,但要進行剪枝 
*/
#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;
}

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved