码迷,mamicode.com
首页 > 编程语言 > 详细

《算法竞赛进阶指南》0x23剪枝 POJ1190上下界搜索与剪枝

时间:2020-06-19 16:36:53      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:namespace   size   inf   面积   http   上下   cin   const   max   

题目链接:http://poj.org/problem?id=1190

剪枝的常用思考策略:优化搜索顺序(从决策数量越少的位置开始决策)、排除冗余的等效的操作、可行性剪枝、最优性剪枝、上下界剪枝,其中在可行性剪枝方面可以利用“未来期望进行剪枝”

要充分利用不等式关系进行放缩,将不可能的状态进行剪枝,也是一个对“未来状态的估计”。

代码:

#include<iostream>
#include<cstdio>
#include<math.h>
using namespace std;
#define maxn 25
const int inf=0x3f3f3f3f;
int n,m;
int minv[maxn],mins[maxn];
int h[maxn],r[maxn];
int ans=inf;
void dfs(int dep,int s,int v){
    
    if(mins[dep]+s >= ans)return ;
    if(minv[dep]+v > n)return ;
    if(2*(n-v)/r[dep+1]+s >= ans) return ;
    
    if(dep==0){
        if(n==v)ans=min(ans,s);
        return ;
    }
    //枚举上下界 
    for(int R=min((int)sqrt((double)n-v),r[dep+1]-1);R>=dep;R--)
        for(int H=min((n-v)/R/R,h[dep+1]-1);H>=dep;H--){            
            int t=0;
            if(dep==m)t=R*R;//所有的上表面都加到最后一层上
            r[dep]=R;
            h[dep]=H;
            dfs(dep-1,s+2*R*H+t,v+R*R*H);
        }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){//计算前i层的最小面积和体积 
        mins[i]=mins[i-1]+2*i*i;
        minv[i]=minv[i-1]+i*i*i; 
    }
    r[m+1]=h[m+1]=inf;//保证最后一行的时候上界无限制 
    dfs(m,0,0);
    if(ans==inf)cout<<0<<endl;
    else cout<<ans<<endl;    
}

 

《算法竞赛进阶指南》0x23剪枝 POJ1190上下界搜索与剪枝

标签:namespace   size   inf   面积   http   上下   cin   const   max   

原文地址:https://www.cnblogs.com/randy-lo/p/13163123.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!