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 "); return 0; } a[0]=1; for(int i=1;i<=N;i++) if(dfs(0,i)) { printf("%d ",i); return 0; } return 0; }