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. 使用 netkeeper 创翼网速慢解决方案(13)

    1. 方法1 步骤: 卸载Netkeeper,并删除 卸载以太网(本地连接)驱动 重置网络 重启 重新安装Netkeeper.如果登录出错,卸载「IP,IPv6,Network Monitor」,然后 ...

  2. Yet Another Problem On a Subsequence CodeForces - 1000D (组合计数)

    大意:定义一个长为$k>1$且首项为$k-1$的区间为好区间. 定义一个能划分为若干个好区间的序列为好序列. 给定序列$a$, 求有多少个子序列为好序列. 刚开始一直没想出来怎么避免重复计数, ...

  3. 一篇文章彻底搞懂异步,同步,setTimeout,Promise,async

    之前翻看别的大佬的博客看到了关于setTimeout,promise还有async执行顺序的文章.观看了几篇之后还是没有怎么看懂,于是自己开始分析代码,并整理了此文章,我相信通过此文章朋友们能对异步同 ...

  4. ASP.NET WEB应用程序(.network4.5)MVC 程序的结构解读1

    https://www.cnblogs.com/-beauTiFul/p/8036509.html 简介 开发环境:VS2015 ASP.NET:可以开发出几乎所有运行在Windows上的应用程序:. ...

  5. MVC的12种ActionResult介绍以及应用示例【转】

    一.介绍 1.ViewResult 表示一个视图结果,它根据视图模板产生应答内容.对应得Controller方法为View. 2.PartialViewResult 表示一个部分视图结果,与ViewR ...

  6. 3、java基础:抽象类与接口的区别

    抽象类 我们都知道在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的.如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样 ...

  7. vs-code 的常用插件

    最近编辑器转移至VS-Code上面了,为什么抛弃sublime呢,因为,sublime在项目逐渐变大的过程中(项目已上万行,还在不停继续变大),sublime会出现卡顿,反应缓慢,甚至未响应状态,基于 ...

  8. 移动端适配flexible.js

    npm install lib-flexible --save npm install px2rem-loader --save-dev

  9. django_redis

    目录 下载 说明 补充: 内存中设置值 取值 使用 配置: settings/dev.py缓存配置 - redis存储:依赖 django-redis,要安装>>>pip insta ...

  10. 服务器CPU架构演变过程

    第一阶段: 单CPU,没啥好说的.和我们今天打游戏的台式机差不多. 第二阶段: 双CPU 或者 多CPU的SMP架构 或者 AMP架构.参考:http://www.lauterbach.com/smp ...