华师一附中OI组
标题:
用递归的方法求2^100至少要算多少次乘法
[打印本页]
作者:
diggersun
时间:
2015-11-1 00:14
标题:
用递归的方法求2^100至少要算多少次乘法
其实就是求一个最短的序列 A1 A2 A3** An 满足
1、A1=1
2、对于x >1有Ax=Ay+Az,其中y<=x,z<x;
3、An=100
我们尝试使用回溯法(也叫递归,深度优先搜索,意义都差不多)
作者:
diggersun
时间:
2015-11-1 00:32
#include<iostream>
#include<iomanip>
using namespace std;
int a[200],x,y,n,iiii;
bool can(int i,int k) //判断前面i-1个数字中能有某两个数字之和为k
{
bool bb=false;
for (int ii=0; ii<=i; ii++)
for (int jj=0; jj<=i; jj++)
if (a[ii]+a[jj]==k) bb=true; //很笨的做法没有优化
return bb;
}
void dfs(int i)
{
int j,k;
if (i>=n) //达到预定的长度就不再往下找了
{
if (a[n-1]==x) //符合要求的话
{
for (j=0; j<=n-1; j++) cout<<setw(3)<<a[j];
cout<<endl;
n--; //下次就最大长度减一
}
}
else
for (k=1+a[i-1]; k<=(2*a[i-1]); k++) // 下一个数字的范围若能由大到小更好
if (can(i-1,k))
{
a[i]=k;
dfs(i+1);
}
}
int main()
{
x=20;
n=20;//假设最大值要算20次,这个是很保守的。
a[0]=1; a[1]=2; //前面两个数字没有选择只能是1和2
dfs(2);//从第三个数字开始搜索
}
复制代码
作者:
diggersun
时间:
2016-8-2 21:46
二楼的只是一个标准的参考程序,有很多的地方可以优化,比如,n=20,假设最大次数要算20次,其实,我们可以使用类似快速幂的形式计算最大计算次数,(神奇的是:快速幂算法80%情况下都是对的,除非15,23,46等)或者使用log2(x)*2。再比如,我们在递归的时候一般是由小到大搜索,此题也不例外,但是,可以想象,应该由大到小找更快捷, 第26行 for (k=1+a[i-1]; k<=(2*a[i-1]); k++) 可以考虑改成 k--的形式。
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2