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. 剑指offer30:连续子数组的最大和

    1 题目描述 HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但是,如果 ...

  2. FishingMaster(HDU-6709)【贪心】

    题目链接:https://vjudge.net/problem/HDU-6709 题意:一个人要抓n条鱼,每抓一条鱼用时K,每烹饪一条鱼用时a[i],抓鱼的过程不能被打断,烹饪鱼的时候可以抓鱼,也可以 ...

  3. BFC的作用及其应用

    简单介绍BFC BFC 就是块级格式化上下文,是页面盒模型布局中的一种 CSS 渲染模式,相当于一个独立的容器,里面的元素和外部的元素相互不影响. 创建 BFC 的方式有: 1.html的根元素 2. ...

  4. python读写文件的操作

    编程语言中,我们经常会和文件和文件夹打交道,这篇文章主要讲的是Python中,读写文件的常用操作: 一.打开文件 openFile = open('../Files/exampleFile.txt', ...

  5. Django查找数据库objects.filter() 排序order_by Q()与或非 F()属性之间比较 聚合函数的用法

    条件选取QuerySet的时候,filter表示=参数可以写查询条件,exclude表示!=,querySet.distinct() 去重复(除了get返回值都是QuerySet,可以继续调用所有函数 ...

  6. WUSOJ 1293: Fibonacci数列(Java)

    题目:

  7. 嵌入式Linux学习笔记之第一阶段---基础篇

    嵌入式Linux学习分五个阶段 第一阶段: 01嵌入式环境搭建初期 02C语言语法概述 03C语言内存操作 04c语言函数 05linux基础 06gun基础 第二阶段: 01-linux之io系统编 ...

  8. Bminer

    Bminer https://www.bminer.me/zh/ Bminer: When Crypto-mining Made Fast¶ Bminer是一款为NVIDIA和AMD GPU深度优化的 ...

  9. 在网页中添加google搜索

    网页中插入谷歌搜索,至于怎么上谷歌,后面有时间会更,推荐百度 <form method="GET" action="http://www.google.com.hk ...

  10. [LeetCode] 219. Contains Duplicate II ☆(存在重复元素2)

    每天一算:Contains Duplicate II 描述 给出1个整形数组nums和1个整数k,是否存在索引i和j,使得nums[i] == nums[j] 且i和j之间的差不超过k Example ...