1. 程式人生 > >codevs 2541 冪運算(叠代加深搜索)

codevs 2541 冪運算(叠代加深搜索)

define 等級 mon hint -- 大小 animate input class

2541 冪運算

時間限制: 1 s 空間限制: 128000 KB 題目等級 : 鉆石 Diamond
題目描述 Description

從m開始,我們只需要6次運算就可以計算出m31:

m2=m×m,m4=m2×m2,m8=m4×m4,m16=m8×m8,m32=m16×m16,m31=m32÷m。

請你找出從m開始,計算mn的最少運算次數。在運算的每一步,都應該是m的正整數次方,換句話說,類似m-3是不允許出現的。

輸入描述 Input Description

輸入為一個正整數n

輸出描述 Output Description

輸出為一個整數,為從m開始,計算mn的最少運算次數。

樣例輸入 Sample Input

樣例1
1

樣例2
31

樣例3
70

樣例輸出 Sample Output

樣例1
0

樣例2
6

樣例3
8

數據範圍及提示 Data Size & Hint

n(1<=n<=1000)

數據沒有問題,已經出現過的n次方可以直接調用

/*
正解是叠代加深
這樣搜索的規模就大大減小 
同樣的維護已經得到的mi數組
數組的大小對應做了幾次運算 
加上幾個剪枝:
如果mi中最大的<<(deep-k) 都到不了n 搜索失敗
生成新的mi的時候 盡量組合數大的 這樣也可以減小規模 
*/ #include<iostream> #include<cstdio> #include<cstring> #define N 101 using namespace std; int n,a[N<<2]; int dfs(int k,int deep) { if(a[k]==n) return deep; if(deep==k) return 0; int maxx=0; for(int i=0;i<=k;i++)maxx=max(maxx,a[k]); if(maxx<<(deep-k)<n)return
0; for(int i=k;i>=0;i--) { a[k+1]=a[k]+a[i]; if(dfs(k+1,deep)) return 1; a[k+1]=a[k]-a[i]; if(dfs(k+1,deep)) return 1; }return 0; } int main() { scanf("%d",&n); if(n==1) { printf("0\n"); return 0; } a[0]=1; for(int i=1;i<=N;i++) if(dfs(0,i)) { printf("%d\n",i); return 0; } return 0; }

codevs 2541 冪運算(叠代加深搜索)