Power Calculus 快速幂计算 (IDA*/打表)
原题:1374 - Power Calculus
题意:
求最少用几次乘法或除法,可以从x得到x^n。(每次只能从已经得到的数字里选择两个进行操作)
举例:
x^31可以通过最少6次操作得到(5次乘,1次除)
x^2 = x*x
x^4 = (x^2)*(x^2)
x^8 = (x^4)*(x^4)
x^16 = (x^8)*(x^8)
x^32 = (x^16)*(x^16)
x^31 = (x^32)÷x
分析:
可以看到,每次从已得到的数字中选取两个操作,这样就有了枚举的思路。
这道题又是没有明显的枚举次数上限,所以很自然想到了用迭代加深搜索算法。
因为n的数据范围是1~1000,所以可以通过计算,预设最大的枚举层次数上限MAXD是13.
而且可以发现如果当前的数字num*2^(MAXD-d) < n,就没有继续搜的必要了,回溯(num是通过前d步得到的数字)
所以我们的IDA*算法思路基本上就完全了。
进一步优化:
如果只依靠上述的思路,写出来的程序要跑2.7s(上限是3s),所以属于刚刚好AC.
我们这里有很多种优化方法,我就说两个我用了的。
1. 寻找幂的时候,我们每次不应该从已得到数字里任意抽两个,这样效率很低。而且很容易出一道,我们每一次都是操作上一步得到的数字,所以这样只需要枚举另一个操作数就够了。
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXD = ;
int n, f[<<(MAXD - )], maxd, a[]; bool dfs(int d) {
if (a[d] == n) return true;
if (d < maxd && (a[d]<<(maxd - d)) >= n) {
for (int i = d; i >= ; i--)
for (int j = ; j < ; j++) {
int nextn = j ? a[d] + a[i] : a[d] - a[d - i];
if (nextn <= || f[nextn]) continue;
f[nextn] = ;
if (nextn <= ) continue;
a[d + ] = nextn;
if (dfs(d + )) return true;
f[nextn] = ;
}
}
return false;
}
int main() {
a[] = ;
while (scanf("%d", &n) == && n) {
if (n == ) { printf("0\n"); continue;}
for (maxd = ; maxd < MAXD; maxd++) {
memset(f, , sizeof(f));
f[] = ;
if (dfs()) break;
}
printf("%d\n", maxd);
}
return ;
}
2.打表。
因为n的范围是1~1000, 所以我们可以用稍微慢一点的算法,提前算出来结果,保存到文件里,然后再粘贴到提交的代码里。
比如我的代码是
int main() {
freopen("ans_table", "w", stdout);
/*
some code.
*/
for(n = ; n <= ; n++) {
if (n == ) { printf("ans[%d] = 0;\n", i); continue;}
for (maxd = ; maxd < MAXD; maxd++) {
/*
some code.
*/
if (dfs(, )) break;
}
printf("ans[%d] = %d;\n", i, maxd);
}
return ;
}
这样我们就本地生成了文件"ans_table"。
里面的答案都是形如
ans[1] = 0;
ans[2] = 1;
ans[3] = 2;
ans[4] = 2;
ans[5] = 3;
ans[6] = 3;
ans[7] = 4;
ans[8] = 3;
ans[9] = 4;
ans[10] = 4;
ans[11] = 5;
ans[12] = 4;
相当于直接生成代码形式的表格。
速度自然是0ms
Power Calculus 快速幂计算 (IDA*/打表)的更多相关文章
- 7-13 Power Calculus 快速幂计算 uva1374
想到快速幂 但是这题用不上 用迭代加深搜索 注意启发函数为 当前最大数<<(maxx-d) 如果大于n则剪枝 注意跳出语句的两种写法 一种170ms 一种390ms !!! d ...
- 矩阵快速幂计算hdu1575
矩阵快速幂计算和整数快速幂计算相同.在计算A^7时,7的二进制为111,从而A^7=A^(1+2+4)=A*A^2*A^4.而A^2可以由A*A得到,A^4可以由A^2*A^2得到.计算两个n阶方阵的 ...
- POJ 3233 Matrix Power Series——快速幂&&等比&&分治
题目 给定一个 $n \times n$ 的矩阵 $A$ 和正整数 $k$ 和 $m$.求矩阵 $A$ 的幂的和. $$S = A + A^2 + ... + A^k$$ 输出 $S$ 的各个元素对 ...
- UVa 1374 快速幂计算(dfs+IDA*)
https://vjudge.net/problem/UVA-1374 题意:给出n,计算最少需要几次能让x成为x^n(x和已经生成的数相乘或相除). 思路:IDA*算法. 如果当前数组中最大的数乘以 ...
- uva 1374 快速幂计算
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #i ...
- UVa 1374 - Power Calculus——[迭代加深搜索、快速幂]
解题思路: 这是一道以快速幂计算为原理的题,实际上也属于求最短路径的题目类型.那么我们可以以当前求出的幂的集合为状态,采用IDA*方法即可求解.问题的关键在于如何剪枝效率更高.笔者采用的剪枝方法是: ...
- POJ 3233 Matrix Power Series (矩阵快速幂+二分求解)
题意:求S=(A+A^2+A^3+...+A^k)%m的和 方法一:二分求解S=A+A^2+...+A^k若k为奇数:S=(A+A^2+...+A^(k/2))+A^(k/2)*(A+A^2+...+ ...
- UVa 11149 Power of Matrix (矩阵快速幂,倍增法或构造矩阵)
题意:求A + A^2 + A^3 + ... + A^m. 析:主要是两种方式,第一种是倍增法,把A + A^2 + A^3 + ... + A^m,拆成两部分,一部分是(E + A^(m/2))( ...
- ZZNU 2182 矩阵dp (矩阵快速幂+递推式 || 杜教BM)
题目链接:http://47.93.249.116/problem.php?id=2182 题目描述 河神喜欢吃零食,有三种最喜欢的零食,鱼干,猪肉脯,巧克力.他每小时会选择一种吃一包. 不幸的是,医 ...
随机推荐
- 将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据
领导让在存储过程中批量添加数据,找出效率最高的,我看到后台代码后,发现可以将list<对象>转换成DataTable,把DataTable转换成参数传入存储过程实现批量插入数据,知道还有其 ...
- Android常用第三方框架
1.volley (截击) 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载: (2) 网络请求的排序(sch ...
- postgresql sql修改表,表字段
1.更改表名 alter table 表名 rename to 新表名 2.更改字段名 alter table 表名 rename 字段名 to 新字段名 3.增加列 ALTER TABLE ud_w ...
- 浅析angular框架的cookie
相信接触过网页编程的基本上都知道cookie这个东西吧,一个毫不起眼,但是又十分的重要的东西,今天我们就来分析一下这个小东西,我们都知道客服端通过发送http请求到服务器请求我们的数据,当我们的服务器 ...
- Codeforces 551C GukiZ hates Boxes(二分)
Problem C. GukiZ hates Boxes Solution: 假设最后一个非零的位置为K,所有位置上的和为S 那么答案的范围在[K+1,K+S]. 二分这个答案ans,然后对每个人尽量 ...
- Cocos2dx开发(1)——Win8.1下 NDK r10 环境搭建
内容简要:仅讲述NDK在Windows环境下搭建方法,至于NDK何物一概不属于本文内容,老鸟或已有环境的跳过. 笔者已安装的环境: vs2013企业版.谷歌官网adt 22.3.0(推荐)省得自己ec ...
- Fedora 21 安装VirtualBox
注: 所有操作需要root权限 如果不是root用户在下面所有命令前加sudo 装dkms,kernel-devel,makecache: yum install dkms yum install ...
- javascript常用代码大全
http://caibaojian.com/288.html 原文链接 jquery选中radio //如果之前有选中的,则把选中radio取消掉 $("#tj_cat .pro_ca ...
- wdcp对default站点开启apache url重写功能
网站开启对default网站的重写功能
- java 多线程sleep和wait的区别
对于sleep()方法,我们首先要知道该方法是属于Thread类中的.而wait()方法,则是属于Object类中的. sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监 ...