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. 『Python基础』第4节:基础数据类型初识

    本节只是对基础数据类型做个简单介绍, 详情会在之后慢慢介绍 什么是数据类型? 我们人类可以分清数字与字符串的区别, 可是计算机不能. 虽然计算机很强大, 但在某种程度上又很傻, 除非你明确告诉它数字与 ...

  2. vi 使用系统剪贴板(clipboard)

    ref : https://www.jianshu.com/p/771b95e34293 http://www.bubuko.com/infodetail-469867.html 在vi中,如果编译时 ...

  3. NodeJs 的Module.export 和 export

    NodeJs  的Module.export 和 export 是一样的. 但是Module.export ={....} 可以起效,.export ={....} 是失效的. 这里的export  ...

  4. JS基础_构造函数修改

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. kong网关命令(一)

    上次在虚拟机里安装kong网关后,因为版本(1.4)太高,目前Kong Dashboard无法支持, 后续发现Git上有个开源工具Kong admin ui,下载源码并部署到NGINX. 但是发现使用 ...

  6. pytorch神经网络实现的基本步骤

    转载自:https://blog.csdn.net/dss_dssssd/article/details/83892824 版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载 ...

  7. Laravel with 查询指定的字段(非复制的哦)

    问题: 在with里面指定查询字段,结果是null. 在模型里面指定查询字段,结果是null. 解决办法: 在查询指定字段的时候要顺带着查询关联的外键,例: // user 表 id name // ...

  8. VBA宏注释(四)

    注释用于记录程序逻辑和用户信息,其他程序员将来可以阅读并理解相同的代码无缝工作. 它包括由开发者,修改者以及还可以包括合并逻辑的信息. 解释器在执行时忽略注释. VBA中的注释用两种方法表示,它们分别 ...

  9. 记录在苹果X手机上运行遇到的代码Dom被阻塞不更新的一个坑

    一.问题产生背景: 开发支付功能,代码逻辑如下:点击支付后,请求后台接口得到流水号以及第三方支付台链接,跳转支付台(在苹果手机则是弹出支付台层):支付完毕后返回支付页面,或中途退出支付台返回支付页面: ...

  10. Apache Log View 5.37破解笔记

    i春秋作家:Sp4ce 之前说过要分享这个日志分析工具[记一次简单的攻击日志分析]的破解版,在破解的路上踩了几个坑,记录分享下. 0×00程序概述 原程序 大小: 2283672 字节文件版本: 5. ...