POJ 3134 Power Calculus ID-DFS +剪枝
题意:给你个数n 让你求从x出发用乘除法最少多少步算出x^n。
思路:
一看数据范围 n<=1000 好了,,暴搜。。
但是 一开始写的辣鸡暴搜 样例只能过一半。。 大数据跑了10分钟才跑出来。。。
看来是要加剪枝了。
剪枝1:
我们可以知道 如果花k步得到了一个数m,那么如果比k步多q步才得到m,,这肯定不是最优解。
原因:
得到m最优解的路径上在q步内总能组合出在k+q步得到m的路径上的所有值。
剪枝2:
剪枝2是在剪枝1之上的。。。 因为我们用的是迭代加深搜索,不用每次清空这个最小值数组了。
剪枝3:(但是剪枝3很弱,只有15ms的优化效果)
我们可以用看二进制最高位的方法求出一个下界,每回从下界开始搜索就好了。
有人用答案在12以内时 ID-DFS,(因为程序的效率差), 如果没有得出答案,直接贪心输出13.。。。
这种 情况 我只能说 你RP真好。。。
版本1:
Problem: 3134 User: 2553015307
Memory: 176K Time: 4125MS
Language: C++ Result: Accepted
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,T,s[33],flag,vis[2048];
void dfs(int t){
if(t==T+1){if(s[t]==n)flag=1;return;}
for(int i=1;i<=t;i++){
int tempx=s[t]+s[i],tempy=s[t]-s[i],temp=T-t+1;
if(tempx<<(temp)>=n&&tempx<2048&&t<=vis[tempx])vis[tempx]=t,s[t+1]=tempx,dfs(t+1);
if(tempy<<(temp)>=n&&tempy>0&&t<=vis[tempy])vis[tempy]=t,s[t+1]=tempy,dfs(t+1);
}
}
int main(){
while(scanf("%d",&n)&&n){
flag=0,s[1]=1;
for(T=0;;T++){
memset(vis,0x3f,sizeof(vis)),dfs(1);
if(flag){printf("%d\n",T);break;}
}
}
}
每回清空vis数组,,卡时过的。
终极版:
#include <cstdio>
#include <cstring>
using namespace std;
int n,T,s[33],flag,vis[2048];
bool dfs(int t){
if(t==T+1){if(s[t]==n)return 1;return 0;}
for(int i=1;i<=t;i++){
int tempx=s[t]+s[i],tempy=s[t]-s[i],temp=T-t+1;
if(t<=vis[tempx]&&tempx<<temp>=n&&tempx<2048){vis[tempx]=t,s[t+1]=tempx;if(dfs(t+1))return 1;}
if(tempy>0&&t<=vis[tempy]&&tempy<<temp>=n){vis[tempy]=t,s[t+1]=tempy;if(dfs(t+1))return 1;}
}
return 0;
}
int main(){
while(scanf("%d",&n)&&n){
memset(vis,0x3f,sizeof(vis)),vis[1]=T=flag=0,s[1]=1;
for(int i=10;i;i--)if(n/(1<<i)){T=i;break;}
for(;;T++)if(dfs(1)){printf("%d\n",T);break;}
}
}
POJ 3134 Power Calculus ID-DFS +剪枝的更多相关文章
- poj 3134 Power Calculus(迭代加深dfs+强剪枝)
Description Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multipli ...
- POJ 3134 Power Calculus (迭代剪枝搜索)
题目大意:略 题目里所有的运算都是幂运算,所以转化成指数的加减 由于搜索层数不会超过$2*log$层,所以用一个栈存储哪些数已经被组合出来了,不必暴力枚举哪些数已经被搜出来了 然后跑$iddfs$就行 ...
- 迭代加深搜索POJ 3134 Power Calculus
题意:输入正整数n(1<=n<=1000),问最少需要几次乘除法可以从x得到x的n次方,计算过程中x的指数要求是正的. 题解:这道题,他的结果是由1经过n次加减得到的,所以最先想到的就是暴 ...
- poj 3134 Power Calculus(IDA*)
题目大意: 用最小的步数算出 x^n 思路: 直接枚举有限步数可以出现的所有情况. 然后加一个A* 就是如果这个数一直平方 所需要的步骤数都不能达到最优 就剪掉 #include < ...
- POJ 3134 - Power Calculus (IDDFS)
题意:求仅仅用乘法和除法最快多少步能够求到x^n 思路:迭代加深搜索 //Accepted 164K 1094MS C++ 840B include<cstdio> #include< ...
- POJ 3134 - Power Calculus
迭代加深 //Twenty #include<cstdio> #include<cstdlib> #include<iostream> #include<al ...
- 【POJ】3134 Power Calculus
1. 题目描述给定一个正整数$n$,求经过多少次乘法或除法运算可以从$x$得到$x^n$?中间结果也是可以复用的. 2. 基本思路实际结果其实非常小,肯定不会超过20.因此,可以采用IDA*算法.注意 ...
- 【POJ - 1190】生日蛋糕 (dfs+剪枝)
Descriptions: 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为 ...
- POJ 1564 Sum It Up (DFS+剪枝)
...
随机推荐
- [原创]一道基本ACM试题的启示——多个测试用例的输入问题。
Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离. Input 输入数据有多组,每组占一行,由4个实数组成,分别表示x1,y1,x2,y2,数 ...
- [转]C++内存管理
[导语] 内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不 ...
- 如何修改wifi为家庭网络
一不小心手快,把新链接的 wifi 选择成“公用网络”了,使用过程中导致某些应用无法联网,那个恨呐!!! 幸好,咱们可以进行手工更改,哈哈,跟哥一起来操作: 进入”网络与共享中心界面": 选 ...
- php 单例模式与常驻服务
运行机制使得每个PHP页面被解释执行后,所有的相关资源都会被回收.也就是 说,PHP在语言级别上没有办法让某个对象常驻内存.在PHP中,所有的变量都是页面级的,无论是全局变量,还是类的静态成员,都会在 ...
- 洛谷 P2365 任务安排_代价提前计算 + 好题
最开始,笔者将状态 fif_{i}fi 定义为1到i的最小花费 ,我们不难得到这样的一个状态转移方程,即 fi=(sumti−sumtj+S+Costj)∗(sumfi−sumfj)f_{i}=(s ...
- 【Java编程】volatile和transient关键字的理解
理解volatile volatile是java提供的一种轻量级的同步机制,所谓轻量级,是相对于synchronized(重量级锁,开销比较大)而言的. 根据java虚拟机的内存模型,我们知道 ...
- 封装自己的jquery框架
jQuery is a fast small JavaScript library 如何封装自己的jQuery <script> // 这里使用沙箱模式,可以防止全局污染 (functio ...
- CentOS 笔记(四) Jexus部署相关
①设置jexus 为服务 cd /lib/systemd/system/ sudo vi jexus.service #注意 jexus 实际路径 [Unit] Description=jexus A ...
- 02.OOP面向对象-2.例子
class clothes: #初始化属性 def __init__(self,name,color): self.name = name self.color = color #转字符串 def _ ...
- 【codeforces 807D】Dynamic Problem Scoring
[题目链接]:http://codeforces.com/contest/807/problem/D [题意] 给出n个人的比赛信息; 5道题 每道题,或是没被解决->用-1表示; 或者给出解题 ...