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 题目描述 河神喜欢吃零食,有三种最喜欢的零食,鱼干,猪肉脯,巧克力.他每小时会选择一种吃一包. 不幸的是,医 ...
随机推荐
- VMware Workstation 11序列号一枚
VMware Workstation 11序列号: 1F04Z-6D111-7Z029-AV0Q4-3AEH8
- 寻找链表中倒数第K个结点的位置
输入一个链表,输出该链表中倒数第K个结点. struct ListNode { int m_nValue; ListNode* m_pNext; }; ListNode* FindKthToTail( ...
- 理解pkg-config工具
你在 Unix 或 Linux 下开发过软件吗?写完一个程序,编译运行完全正常,在你本机上工作得好好的,你放到源代码管理系统中.然后,告诉你的同事说,你可以取下来用了.这时,你长长的出了一口气,几天的 ...
- MVC 文本转换成html显示
最近在学习ASP.NET MVC,项目中需要将后台传输的HTML文本在前台页面显示:@Html.Raw(HttpUtility.HtmlDecode(ViewBag.DisplayText)).记下来 ...
- php判断手机移动设备访问
<?php function isMobile() { // 如果有HTTP_X_WAP_PROFILE则一定是移动设备 if (isset ($_SERVER['HTTP_X_WAP_PROF ...
- 写个自己的Xcode4插件
推荐:http://onevcat.com/2013/02/xcode-plugin/ 刚写iOS程序的时候就知道Xcode支持第三方插件,比如ColorSense等很实用的插件,但Xcode的插 ...
- HTML DOM(一):认识DOM
分类: HTML/JavaScript/CSS(10) 版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/ghsau. 什么是DOM? 通过 Jav ...
- 新站如何做SEO及注意事项
最近公司做了新网站,完成后运营优化的工作就落在我身上了,由于之前也没有.就去网上百度了一下,上了各种论坛查阅大牛的博客.自己也总结了一些要点,在这里和大家分享一下.新网站大家可以点击查看牛羊养殖在线. ...
- 转:PHP中实现非阻塞模式
原文来自于:http://blog.csdn.net/linvo/article/details/5466046 程序非阻塞模式,这里也可以理解成并发.而并发又暂且可以分为网络请求并发 和本地并发 . ...
- C# 日期格式精确到毫秒 【转】
有时候我们要对时间进行转换,达到不同的显示效果 默认格式为:2009-6-24 14:33:34 如果要换成成200906,06-2009,2009-6-24或更多的该怎么办呢 我们要用到:DateT ...