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. 利用box-shadow制作loading图

    我们见过很多利用css3做的loading图,像下面这种应该是很常见的.通常制作这种loading,我们会一个标签对应一个圆,八个圆就要八个标签.但是这种做法很浪费资源.我们可以只用一个标签,然后利用 ...

  2. 定制自己的动画 View 控件(Canvas 使用)

    定制自己的动画 View 控件(Canvas 使用) 如果要定义自己的 View 控件,则需要新建一个类继承 android.view.View.然后在 onDraw 中写自己需要实现的方式. 这里定 ...

  3. 【Alpha】阶段第五次Scrum Meeting

    [Alpha]阶段第五次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 增加课程接口 增加教师接口 赵智源 整合前端进行部署 构建后端测试点测试框架 肖萌威 编 ...

  4. 03 JAVA IO

    java.io包中定义了多个流类型来实现输入输出功能,以不同的角度进行分类: 按数据流的方向不同可以分为输入流和输出流 按处理数据单位不通可以分为字节流和字符流 按照功能不同可以分为节点流和处理流 所 ...

  5. Codeforces Beta Round #7 D. Palindrome Degree manacher算法+dp

    题目链接: http://codeforces.com/problemset/problem/7/D D. Palindrome Degree time limit per test1 secondm ...

  6. C#高级编程 (第六版) 学习 第五章:数组

    第五章 数组 1,简单数组 声明:int[] myArray; 初始化:myArray = new int[4]; 为数组分配内存. 还可以用如下的方法: int[] myArray = new in ...

  7. 判断字符串中是否存在的几种方案:string.indexof、string.contains、list.contains、list.any几种方式效率对比

    我们在做项目时,可能会遇到这样的需求,比如判断,1,2,3,33,22,123, 中是否存在,3,. var str=",1,2,3,33,22,123,"; 一般有几种方式: 1 ...

  8. Hadoop环境搭建(三)

    长久没用了,再次登陆Ubuntu的时候提醒密码错误,然后就进入了guest session,依然可以进入系统进行工作但身份是guest,于是开始了找回密码的漫漫长路. 首先,在guest模式下,右上角 ...

  9. PAT L1-015 跟奥巴马一起画方块

    https://pintia.cn/problem-sets/994805046380707840/problems/994805124398956544 美国总统奥巴马不仅呼吁所有人都学习编程,甚至 ...

  10. win7 64位机ODBC的数据源DSN添加和移除问题

    64位机器上ODBC的操作方法与32位机器是不一样的,如果直接从控制面板上-管理员工具-ODBC进去的话会发现User DSN以及System DSN里面都为空,ADD的时候连ODBC Driver都 ...