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. IIC通讯程序

    IIC程序 IIC起始信号 void IIC_Start(void) { SDA_OUT();//sda设为输出 IIC_SDA=; IIC_SCL=; delay_us();//延时一段时间,具体时 ...

  2. Linux权限管理命令

    查询linux命令用法网址:cht.sh 1.chmod——改变文件/目录的权限 用法: ① chmod [{ugoa}{+-=}{rwx}] [文件/目录]   ---给文件的(用户.所属组.其他人 ...

  3. 《零基础学JavaScript(全彩版)》学习笔记

    <零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...

  4. CDQ分治_占坑

    准备系统地学习一波CDQ分治,持续更新中... 首先,CDQ分治也还是分治的一种,只不过普通分治是独立的解决两个子问题,而CDQ分治还要计算第一个子问题对于第二个的影响. CDQ分治几乎都是用来解决多 ...

  5. Python3 迭代器和生成器

    想要搞明白什么是迭代器,首先要了解几个名词:容器(container).迭代(iteration).可迭代对象(iterable).迭代器(iterator).生成器(generator). 看图是不 ...

  6. nginx原声方法按照每天日志切割保存

    首先配置日志变量,然后配置日志 在/etc/nginx/conf.d/default.conf 配置变量 server{ if ($time_iso8601 ~ "^(\d{4})-(\d{ ...

  7. 第七次作业PSP

    psp 进度条 代码累积折线图 博文累积折线图 psp饼状图

  8. FPGA的软核与硬核

    硬核 zynq和pynq系列的fpga都是双ARM/Cortex-A9构成,这里的ARM处理器为硬核,Cortex-A9部分为FPGA部分.即整体分为两部分:PS/PL.PS部分为A9处理器部分,PL ...

  9. GIT团队实战

    项目要求 组长博客 遇到的困难及解决办法 组员1(组长):王彬 遇到的困难  在团队任务分工的时候没有充分照顾到所有人,导致队员们的工作量不均. 现场编程时间不够 解决办法 在此对组员们表示抱歉,由于 ...

  10. [图算法] 1030. Travel Plan (30)

    1030. Travel Plan (30) A traveler's map gives the distances between cities along the highways, toget ...