zoukankan      html  css  js  c++  java
  • poj 3134 && LA 3621 Power Calculus (迭代加深深度优先搜索)

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1622

    3134 -- Power Calculus

      又搞了几天才出一题。

      这题我是用迭代加深深度优先搜索来做的。网上的题解多种多样,大部分都是BFS的,不过好多都是没有证明的方法。表示个人认为迭代加深是一个十分好的正解。

      至于这题为何用迭代加深,个人认为原因是:

    (1)BFS剪枝不容易加上去,即便是加上一两个剪枝也无法剪枝到系统可以接受的时间和空间。(网上有题解说搜索到多少个后停止搜索的方法,可惜没有详细的证明,故认为那是水过的)

    (2)IDDFS与BFS相比,因为是在搜索的过程中直接记录路径,所以相对BFS节省了大量空间。

      除此以外,表示打了好几个版本的代码,IDDFS是相当轻便的一种方法。

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #include <vector>
     6 #include <cmath>
     7 
     8 using namespace std;
     9 
    10 const int N = 1 << 11;
    11 int ep2[15], lg2[N];
    12 #define REP(i, n) for (int i = 0; i < (n); i++)
    13 #define REP_1(i, n) for (int i = 1; i <= (n); i++)
    14 #define DEC(i, a, b) for (int i = (a); i >= (b); i--)
    15 #define PB push_back
    16 #define SZ(x) ((int) (x).size())
    17 
    18 void PRE() {
    19     REP(i, 15) {
    20         ep2[i] =  1 << i;
    21     }
    22     int t = 0;
    23     REP(i, N) {
    24         if (ep2[t + 1] <= i) t++;
    25         lg2[i] = t;
    26     }
    27 //    REP(i, 10) cout << lg2[i] << endl;
    28 }
    29 
    30 int st[20], top;
    31 
    32 bool dfs(int n, int depth) {
    33     if (st[top] == n) return true;
    34     if (top >= depth) return false;
    35     int last = st[top];
    36     if ((last << (depth - top)) < n) return false;
    37     if (st[top] <= 1200) {
    38         DEC(i, top, 0) {
    39             st[++top] = last + st[i];
    40             if (dfs(n, depth)) return true;
    41             top--;
    42         }
    43     }
    44     REP(i, top + 1) {
    45         st[++top] = last - st[i];
    46         if (st[top] > 1) {
    47             if (dfs(n, depth)) return true;
    48         }
    49         top--;
    50     }
    51     return false;
    52 }
    53 
    54 int main() {
    55 //    freopen("out", "w", stdout);
    56     int n;
    57     PRE();
    58 //    REP_1(n, 1000) {
    59 //        int step = lg2[n];
    60 //        while (step <= 12) {
    61 //            st[top = 0] = 1;
    62 //            if (dfs(n, step)) break;
    63 //            step++;
    64 //        }
    65 //        cout << n << ' ' << step << endl;
    66 //    }
    67 //    return 0;
    68     while (cin >> n && n) {
    69         int step = lg2[n];
    70         while (step <= 12) {
    71             st[top = 0] = 1;
    72             if (dfs(n, step)) break;
    73             step++;
    74         }
    75         cout << step << endl;
    76     }
    77     return 0;
    78 }

    ——written by Lyon

  • 相关阅读:
    接水果(fruit)——整体二分+扫描线
    大融合——LCT维护子树信息
    魔卡少女(cardcaptor)——线段树
    而立之年的一些人生感悟
    PHP 输出缓冲控制(Output Control) 学习
    我所了解的cgi
    c语言指针学习
    ubuntu 安装 zend studio
    Zend_Controller_Front 研究
    php autoload 笔记
  • 原文地址:https://www.cnblogs.com/LyonLys/p/poj_3134_LA_3621_Lyon.html
Copyright © 2011-2022 走看看