博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 3134 Power Calculus ★(记录状态的BFS)
阅读量:4513 次
发布时间:2019-06-08

本文共 2507 字,大约阅读时间需要 8 分钟。

题目大意:给定初始的x,可以通过乘法将其变为x^2,再变为x^4,x^8,x^16,x^32,也可以用除法,x^31 = x^32 / x,但是操作数必须是已经计算出来的数,给定一个指数,要求得到这个指数的最小步数。比如31输出6(1 2 4 8 16 32 31).   想错了很多次……求最优路径问题嘛,就是ID-DFS or BFS。事实证明两种方法确实都可以。一般
当时间宽裕空间紧张时选ID-DFS;当时间紧而空间宽裕时选BFS。可是因为我的姿势丑……BFS加了各种优化才勉强2s过,ID-DFS显然各种吃紧了……囧。   回到题目。首先一个直观的想法就是BFS,并且因为我们每次扩展状态时都要依据前面过程中的数,所以需要用一个数组记录下来当前状态的前面的状态。这样我们BFS队列里存的就是一个结构体,包括当前状态的指数,当前步数,和存与当前状态相关的前面状态的数组。然后为了减少状态要去重,队列中只保存得到某个数花费步数最短的一种状态。 但是结果953怎么算都是13……跑到Discuss里看了下结果:(1 2 4 8 7 15 30 60 120 240 480 473 953),然后我们对473做一次BFS打印一下结果:(1 2 4 8 16 32 31 63 126 252 504 473)。于是我们发现了问题所在:得到某个数花费最少步数的状态可能不同,而不同的状态对后面数的影响是不同的,所以我们需要把某数步数相同且最短的状态都存起来。 (但我还有一个疑问是为什么步数更长的状态不会使后面有更好的结果……囧……反正数据没出现这种情况……) 但是因为我的姿势丑……T_T……这样还是TLE……看了一位大牛的博客又加了一个优化:限制某个数的状态在队列中只能出现limit次(我设的10),虽然确实通过了……但是还是不会证明正确性……T_T……   PS:为什么我的姿势这么丑……T^T……  
#include #include #include #include using namespace std;struct Queue{    int num, time;    int pre[20], pre_num;};queue  Q;int qnum,it;int step[2110];int cnt[2110];int BFS(int n){    for (int i = 0; i < 2110; i ++){        step[i] = 1 << 30;        cnt[i] = 0;    }    while(!Q.empty())        Q.pop();    Queue tmp;    tmp.num = 1;    tmp.time = 0;    tmp.pre_num = 0;    tmp.pre[tmp.pre_num ++] = 1;    Q.push(tmp);    step[1] = 1;    while(!Q.empty()){        Queue tmp = Q.front();        if (tmp.num == n){//            int p = it;//            while(p != 0){//                p = Q[p].pre;//                cout << Q[p].num << endl;//            }            return tmp.time;        }        step[tmp.num] = tmp.time;        for (int i = 0; i < tmp.pre_num; i ++){            for (int j = -1; j <= 1; j += 2){                Queue p = tmp;                p.num = p.num + p.pre[i] * j;                p.time ++;                if (p.num > 1 && p.num <= 2000){                    if(step[p.num] > p.time){                        step[p.num] = p.time;                        cnt[p.num] = 1;                        p.pre[p.pre_num ++] = p.num;                        Q.push(p);                    }                    else if (step[p.num] == p.time){                        if (cnt[p.num] <= 10){                            p.pre[p.pre_num ++] = p.num;                            Q.push(p);                            cnt[p.num] ++;                        }                    }                }            }        }        Q.pop();    }}int main(){    int n;    while(cin >> n, n){        cout << BFS(n) << endl;    }    return 0;}
 

转载于:https://www.cnblogs.com/AbandonZHANG/archive/2013/01/27/4113991.html

你可能感兴趣的文章
java并发编程:并发容器之CopyOnWriteArrayList(转)
查看>>
python基础——面向对象进阶下
查看>>
Linux vi 命令详解
查看>>
本地如何搭建IPv6环境测试你的APP
查看>>
C++ NULL与nullptr的区别
查看>>
Discretized Streams, 离散化的流数据处理
查看>>
Spark源码分析 – SchedulerBackend
查看>>
python字符串处理
查看>>
live555学习笔记4-计划任务(TaskScheduler)深入探讨
查看>>
Python虚拟机函数机制之名字空间(二)
查看>>
线段树
查看>>
SharePoint2010联合搜索——Google、百度
查看>>
php静态
查看>>
python基础之文件操作
查看>>
在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因...
查看>>
个人github链接及git学习心得总结
查看>>
c++ 计算器 带括号 代码实现
查看>>
objective -c初写
查看>>
C#中如何设置窗体的默认按钮和取消按钮
查看>>
[Swift]LeetCode276. 粉刷栅栏 $ Paint Fence
查看>>