Description:

    就是给你一个数,你可以把它自乘,也可以把他乘或除以任意一个造出过的数,问你最多经过多少次操作能变换成目标数

思路:这题真的不怎么会啊。n = 20000,每一层都有很多个扩展状态,裸宽搜会被T,启发式函数又设计不出来……

看了一个Vjudge上的代码才知道这题怎么写。

就是每一个状态是由最多两个数转化而来的,所以可以把两个数看做一个状态。

用一个多元组$node(x,y,g,h)$表示状态,$x, y$分别表示两个数中的较大数和较小数,然后$g$表示转换成当前的状态需要多少步,$h$表示大数$x$转换到大于等于目标状态至少还要多少步。

启发式函数就是当前步数+预期至少需要的步数,即$g+h$

再用一个哈希表把二元组$(x,y)$与转换到这个状态需要几步对应起来,这样可以完成去重。当然也可以用$map$实现,但按照poj的尿性,很可能TLE。。

然后加几个剪枝,排除以下多余状态:

1.如果$x > 2*n$,这个都能理解吧。

2.如果$x=y$,因为该状态和一个$x$的状态对未来的贡献是等价的,反正自乘自除也能达到一样的效果,不管$y$取什么数,都比$x$与$y$相等时更优。

3.如果$x > n$ 并且 $y = 0$,因为这样的话该状态永远达不到$x=n$。

4.如果$n $ $mod$ $gcd(x,y) != 0$,因为这样的状态不管怎么乘怎么除,也永远达不到$x=n$。

5.如果$(x,y)$已经在哈希表里了且对应的$g$更小,这个也都能理解吧。

这样的话就应该能过了。

然后款搜的时候要注意下,枚举出一个二元组能变换出来的所有可能的二元组,这个具体可以看代码。

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
const int N = , SIZE = 1e6 + ;
int n;
struct node{
int x, y, g, h;
bool operator < (const node &a)const{
return g + h == a.g + a.h ? h > a.h : g + h > a.g + a.h;
}
};
struct Node{
int to, next, w;
};
struct hash_map{
int head[N], now;
Node a[SIZE];
bool insert(int sta, int w){
int x = sta % N;
for(int i = head[x]; i; i = a[i].next){
if(a[i].to == sta){
if(a[i].w <= w) return ;
a[i].w = w; return ;
}
}
a[++now] = {sta, head[x], w};
head[x] = now;
return ;
}
}dict;
priority_queue<node> heap;
node now;
int gcd(int a, int b){ return b ? gcd(b, a % b) : a;}
void che(int x, int y){
if(x < y) swap(x, y);
if(x > * n) return ;
if(x > n && y == ) return ;
if(x == y) return ;
if(n % gcd(x, y)) return;
if(!dict.insert(x * + y, now.g + )) return;
int h = , tx = x;
while(tx < n) h++, tx <<= ;
heap.push({x, y, now.g + , h});
}
void A_star(){
heap.push({, , , });
while(!heap.empty()){
now = heap.top(); heap.pop();
if(now.x == n || now.y == n){
printf("%d\n", now.g); break;
}
int a[] = {now.x, now.y};
for(int i = ; i < ; i++)
for(int j = i; j < ; j++)
for(int k = ; k < ; k++){
int b[] = {a[], a[]};
b[k] = a[i] + a[j];
che(b[], b[]);
}
che(now.x - now.y, now.y);
che(now.x, now.x - now.y);
}
}
int main(){
scanf("%d", &n);
A_star();
return ;
}

poj 1945 Power Hungry Cows 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 2109 Power of Cryptography

    题目地址:http://poj.org/problem?id=2109 /* 题意:k ^ n = p,求k 1. double + pow:因为double装得下p,k = pow (p, 1 / ...

  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. POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Network / FZU 1161 (网络流,最大流)

    POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Networ ...

  8. POJ 2387 Til the Cows Come Home (图论,最短路径)

    POJ 2387 Til the Cows Come Home (图论,最短路径) Description Bessie is out in the field and wants to get ba ...

  9. POJ.2387 Til the Cows Come Home (SPFA)

    POJ.2387 Til the Cows Come Home (SPFA) 题意分析 首先给出T和N,T代表边的数量,N代表图中点的数量 图中边是双向边,并不清楚是否有重边,我按有重边写的. 直接跑 ...

随机推荐

  1. 【shell 每日一练7】一键安装mysql5.7,以及密码及策略修改

    一.一键安装Mysql脚本 [root@uat01 ~]# cat InstallMysql01.sh #!/bin/bash #-- #旅行者-Travel #.安装wget yum -y inst ...

  2. 音频分析框架pyAudioAnalysis文档

    “ pyAudioAnalysis是一个非常好用且强大的音频分析开源工具,能实现音频的特征提取.分类和回归模型的训练和执行,以及其他一些实用的功能.此外,本文档并非直译,也有部分比较简略,可以结合源码 ...

  3. New begin

    Purpose 今天更换了id,希望重新沉淀. 晚上看到国外一个博客,落款有个中文: 敬惜字纸. 共勉.

  4. 1.2Linux下C语言开发基础(学习过程)

    ===============第二节  Linux下C语言开发基础=========== ********************** 重要知识点总结梳理********************* 一 ...

  5. c# 读取blob数据

    Stream stream = new MemoryStream(data); BinaryReader r = new BinaryReader(stream); int iRawImageWidt ...

  6. 从一个app开始学iOS

    在大学上了4年学,老师一直给灌输的思想就是,从细微处着手最后看到整体.举个网站的例子.第一个学期老师安排一门课java语言,期末考试就是考试java语言的知识.第二学期java web,第一次课配置j ...

  7. 寒假学习计划(C++)

    课程 1,计算机程序设计(C++)-西安交通大学(中国大学mooc)课程链接 2,面向对象程序设计-C++-浙大-翁恺(网易云课堂)课程链接 理由 1西安交大的C++慕课从零基础教起,更注重基础,重点 ...

  8. Alpha事后诸葛亮(团队)

    设想和目标 1.我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件要解决用手机使没有指纹验证硬件的电脑可以利用指纹进行文件的加密.定义的很清楚.我们针对的是 ...

  9. Myeclipse错误:Errors occurred during the build. Errors running builder 'DeploymentBuilder' on project ...解决方法

    解决办法:1.首先关闭MyEclipse工作空间.2.然后删除工作空间下的“/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.gen ...

  10. .NET中的堆(Heap)和栈(Stack)的本质

    计算机的内存可以分为代码块内存,Stack内存和Heap内存.代码块内存是在加载程序时存放程序机器代码的地方. 栈(Stack)一般存放函数内的局部变量. 堆(Heap)一般存放全局变量和类对象实例等 ...