UVA 1374 Power Calculus(迭代深搜)
阿新 • • 發佈:2018-11-17
題目:Power Calculus
題意:輸入正整數n(1≤n≤1000),問最少需要幾次乘除法可以從x得到xn?例如,x31需要6次: 。 計算過程中x的指數應當總是正整數(如x-3=x/x4是不允許的)。
思路:繼續IDA*,看了紫書分析,我想的是每次將得到的集合排序後才能得到最大,看了程式碼庫後,其實只需從深度d開始計算即是最大的。。。
(1)列舉搜尋深度,最大列舉深度13
(2)dfs搜尋:每次從當前深度d列舉集合中的元素,用a[d](當前集合中最大值) + 列舉a[i] = a[d+1] 新增元素,然後繼續遞迴,還有一次相減過程,同相加一樣!直到找到,或者達到當前最大深度退出,或剪枝退出。
(3)剪枝:用當前序列最大的數乘以2^(maxd-d)之後仍小於n,則剪枝。()
---------------------
作者:GuoZLH
來源:CSDN
原文:https://blog.csdn.net/GuoZLH/article/details/55097078
版權宣告:本文為博主原創文章,轉載請附上博文連結!
#include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int maxn = 13;//最大深度 int a[maxn+1]={1}; inline int h(int d){//求指數集合中最大的值 int ans_max = 0; for(int i=0;i<=d;i++) ans_max = max(ans_max,a[i]); return ans_max; } inline bool is_fin(int d,int n){//是否達到結果 if(a[d] == n) return true; return false; } bool dfs(int d,int maxd,int n){ if(is_fin(d,n)) return true;//是否達到結果 if(d == maxd) return false;//列舉深度達到上限停止 if((h(d) << (maxd-d)) < n) return false;//剪枝: //列舉:從指數集合中最大的開始 for(int i=d;i>=0;i--){ a[d+1] = a[d] + a[i];//將集合中當前最大的依次加上較大的為新的元素 if(dfs(d+1,maxd,n)) return true;//進行遞迴,找到返回成功 a[d+1] = a[d] - a[i];//將集合中當前最大的依次減去較大的為新的元素 if(dfs(d+1,maxd,n)) return true;//進行遞迴,找到返回成功 } return false; } int solve(int n){ if(n == 1) return 0; for(int maxd=1;maxd<maxn;maxd++){ if(dfs(0,maxd,n)) return maxd; } return maxn; } int main() { int n; while(scanf("%d",&n) == 1 && n) printf("%d\n",solve(n)); return 0; } --------------------- 作者:GuoZLH 來源:CSDN 原文:https://blog.csdn.net/GuoZLH/article/details/55097078 版權宣告:本文為博主原創文章,轉載請附上博文連結!