Description
小KITTY想要快速计算整数P的幂 (1 <= P <=10,000),它们需要你的帮助。因为计算极大数的幂,所以它们同一时间仅能使用2个存储器,每个存储器可记录某个结果值。第一件工作是初始化存储器内的值一个为底数x, 另一个为1。 小KITTY可以相乘或相除2个存储器中的值,并把结果存在其中某个存储器内,但所有存储的结果必须是整数。
例如, 如果他们想计算x^31, 一种计算方法是:
WV1 WV2
开始: x 1
存储器1和存储器1相乘,结果存于存储器2: x x^2
存储器2和存储器2相乘,结果存于存储器2: x x^4
存储器2和存储器2相乘,结果存于存储器2: x x^8
存储器2和存储器2相乘,结果存于存储器2: x x^16
存储器2和存储器2相乘,结果存于存储器2: x x^32
存储器2和存储器1相除,结果存于存储器2: x x^31
因此, x^31可以通过6次计算得出。给出要计算的幂次,要求求出最少需要几次计算。
Input
仅一个整数: P
Output
仅一个整数:最少计算次数。
Sample Input
31
Sample Output
6

提醒一下:爆搜样例都过不了是真的会爆
这篇博客主要是讲不用A*怎么优化代码不TLE的。
这道题目网上有很多做法,但是正解都统一到了一个知识点:

A*启发型搜索
这个东西很麻烦,会引申到知识点:

哈希表
估价函数
以及很多…
完全不是搜索初学者能够完成的一道题目!!!!

但是!
这道题目真的有这么麻烦吗?
这里需要普及一种算法:

极大化剪枝
这是个好东西!就是这个算法让我能够不碰A*就能写出代码。
什么是极大化剪枝呢?
每个有效状态都使得它之后的所有状态极大化,如果这样都无法得到最终的答案,那么这个状态是一个无解的状态,可以剪枝。
这个极大化剪枝对程序时间的控制有多大的作用呢?
这么说吧:

当我的代码没有A*,没有极大化剪枝的时候,p=500我需要6000ms,但是加了极大化剪枝,p=500只需要0ms就可以跑出来。
怎么实现呢?其实很简单,这道题目的极大化剪枝的难点就在于怎么模拟每个状态之后所有状态极大化所得到的值呢?

这道题目还用到了分支限界
因为这不是重点,所以简单说一下:
分支限界,每次都规定搜索的深度,如果深度到达了规定的限度,不管是否达到目标状态,都要退出搜索。
分支限界的好处在于可以减少DFS的搜索量,能够快速的计算输出最优解的步数(或者是其他)
通常定义一个全局变量(lim),然后在主函数里面写:

 for(lim=;;lim++)
dfs...

相应的,DFS里的返回条件,变成了:

 if(深度超限)
{
if(达到目标状态)
{
进行操作
}
return;
}

这样就达到了分支限界的效果了.
极大化剪枝怎么实现呢?
在什么情况下,就算在极限状态下也无法让a或b大于等于p?
只有当a,b中较大的在极限次数范围内不停自加,最终结果还是<p的时候,当前状态是无解的。
那么我们就可以开一个数组,下标为i的存储2的i次方(预处理数组),然后拿a,b较大数乘剩下的操作次数(lim-dep+1)为下标的预处理数组,如果结果还小于p,那么就剪枝.。
然后加上网上搜集整理的剪枝:(为了方便处理,a一定是大于等于b的)

 if(a==b)return;
if(a>p&&b==)return;
if(p%__gcd(a,b)!=)return;
if(a>*p)return;

不要问为什么我也不会证
另外就是拓展问题。
看到有些大佬是拓展了12种方案的,但是做减法的四种可以优化一下,只弄2种:

dfs(abs(a-b),b,s+);
dfs(a,abs(a-b),s+);

然后自除太弱鸡我直接删了
就只剩下8种拓展方案:

 dfs(a+b,b,s+);
dfs(a,a+b,s+);
dfs(abs(a-b),b,s+);
dfs(a,abs(a-b),s+);
dfs(a*,b,s+);
dfs(a,a*,s+);
dfs(a,b*,s+);
dfs(b*,b,s+);

完整代码也很简单,至少比什么A*简单多了

 #include<bits/stdc++.h>
using namespace std;
int p,cnt,lim,st,ed,cut[]={};
void dfs(int a,int b,int s)
{
if(a<=b)swap(a,b);
if(s>lim)
{
if(a==p||b==p)
{
cout<<s<<endl;
exit();
}
return;
}
if(a*cut[lim-s+]<=p)return;
if(a==b)return;
if(a>p&&b==)return;
if(p%__gcd(a,b)!=)return;
if(a>*p)return;
if(a<&&b<)return;
dfs(a+b,b,s+);
dfs(a,a+b,s+);
dfs(abs(a-b),b,s+);
dfs(a,abs(a-b),s+);
dfs(a*,b,s+);
dfs(a,a*,s+);
dfs(a,b*,s+);
dfs(b*,b,s+);
}
int main()
{
cin>>p;
if(p==||p==)
{
cout<<<<endl;
return ;
}
for(int i=;i<=;i++)
{
cut[i]=cut[i-]*;
}
for(lim=;;lim++)
dfs(,,);
return ;
}

经过这番优化,10个点总用时只有惊人的16ms

ov.

【极大化剪枝】Power Hungry Cows-C++【没有用A*!】【超级简单!】的更多相关文章

  1. 『Power Hungry Cows A*启发式搜索』

    Power Hungry Cows(POJ 1945) Description FJ的奶牛想要快速计算整数P的幂 (1 <= P <=20,000),它们需要你的帮助.因为计算极大数的幂, ...

  2. [USACO2002][poj1945]Power Hungry Cows(启发式搜索)

    Power Hungry CowsTime Limit: 1000MS Memory Limit: 30000K Total Submissions: 4570 Accepted: 1120 Desc ...

  3. 【BFS】Power Hungry Cows

    Power Hungry Cows Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5522   Accepted: 1384 ...

  4. poj 1945 Power Hungry Cows A*

    Description:     就是给你一个数,你可以把它自乘,也可以把他乘或除以任意一个造出过的数,问你最多经过多少次操作能变换成目标数 思路:这题真的不怎么会啊.n = 20000,每一层都有很 ...

  5. BZOJ1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛

    1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 665  Solved: 419 ...

  6. BZOJ 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛( LIS )

    裸的LIS ----------------------------------------------------------------- #include<cstdio> #incl ...

  7. 【动态规划】bzoj1669 [Usaco2006 Oct]Hungry Cows饥饿的奶牛

    #include<cstdio> #include<algorithm> using namespace std; int n,a[5001],b[5001],en; int ...

  8. 【BZOJ】1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛(lis)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1669 水题太严重 #include <cstdio> #include <cstr ...

  9. bzoj 1669: [Usaco2006 Oct]Hungry Cows饥饿的奶牛【dp+树状数组+hash】

    最长上升子序列.虽然数据可以直接n方但是另写了个nlogn的 转移:f[i]=max(f[j]+1)(a[j]<a[i]) O(n^2) #include<iostream> #in ...

随机推荐

  1. Word 查找替换高级玩法系列之 -- 给数字批量添加空格和下划线

    Word中的查找和替换是一个很强大的功能,很多人都在使用这项功能.查找和替换,顾名思义就是说,查找到符合条件的内容,然后将那些内容替换成我们所需要的内容.下面,我们就通过实例来了解一下查找和替换功能, ...

  2. python中浅拷贝和深拷贝分析

    首先,我们知道Python3中,有6个标准的数据类型,他们又分为可以变和不可变.不可变:Number(数字).String(字符串).Tuple(元组).可以变:List(列表).Dictionary ...

  3. asp.net core-11.WebHost的配置

    1.添加空的web网站 ,在目录下添加settings.json文件,在控制台上输出json的信息 public class Program { public static void Main(str ...

  4. pause的作用

    重要概念:Pod内的容器都是平等的关系,共享Network Namespace.共享文件 pause容器的最主要的作用:创建共享的网络名称空间,以便于其它容器以平等的关系加入此网络名称空间 pause ...

  5. Python中的内存管理机制

    Python是如何进行内存管理的 python引用了一个内存池(memory pool)机制,即pymalloc机制,用于管理对小块内存的申请和释放 1.介绍 python和其他高级语言一样,会进行自 ...

  6. Recastnavigation 创建 off-mesh link 的潜规则

    Recastnavigation 在创建off-mesh link 时,发现有的off-mesh link 无法寻路(虽然在地图上能看到off-mesh link 的连线   在Google Grou ...

  7. S2-029

    前言 S2-029漏洞是由于Struts2的i18n.text标签中的name属性的值会经过两次Ognl表达式解析. 正文 假设有如下缺陷代码: jsp文件中使用Struts2的i18n标签获取请求中 ...

  8. vscode-golang跳转定义无效问题

    问题发现: 本来可以进行"ctrl"+点击或者F12,进行跳转定义的方式,突然失效了 问题分析: 1.辅助工具是否关闭 解决方案,进入首选项,设置,查找go.docsTool,选项 ...

  9. 二〇一八-美团工程师面试解析(Java)

    一轮面试: 小数是怎么存的 算法题:N二进制有多少个1 Linux命令(不熟悉 JVM垃圾回收算法 C或者伪代码实现复制算法 volatile 树的先序中序后序以及应用场景 Mysql存储记录的数据结 ...

  10. Maven 三种archetype说明--转载

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 原文链接:https://blog.csdn.net/cx1110162/article/deta ...