• POJ 3460 Booksort


    题目链接:http://poj.org/problem?id=3460

    题意:有一些高度不等的书,可以一次取出一摞相对顺序不变的书插入任意位置,问最少多少次操作才能使书的高度递增有序。

    IDA*,刘汝佳黑书P169的例题,经典题目,启发函数的设计十分巧妙。

    以“h(s)=后继书本高度正确的书本个数”为估价函数,假设每次把一摞书本S从P1后面移动到P2后面,只有P1,S1的最后一本,P2三本书的后继有变化,h每次最多减少3,令h'=h(s)/3作为估价函数值,则每次h最多减少1。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 
     6 const int MAXN = 20;
     7 
     8 int N, limit;
     9 int book[MAXN];
    10 bool find;
    11 
    12 int min( int a, int b )
    13 {
    14     return a < b ? a : b;
    15 }
    16 
    17 int h( int *a )
    18 {
    19     int cnt = 0;
    20     if ( a[0] != 1 ) ++cnt;
    21     if ( a[N - 1] != N ) ++cnt;
    22     for ( int i = 1; i < N - 1; ++i )
    23             if ( a[i] + 1 != a[i + 1] ) ++cnt;
    24     return ceil( cnt / 3.0 );
    25 }
    26 
    27 void chuli( int st, int mid, int ed )
    28 {
    29     int temp[MAXN];
    30     for ( int i = mid + 1; i <= ed; ++i )
    31         temp[i] = book[i];
    32     for ( int i = mid, j = ed; i >= st; --i, --j )
    33         book[j] = book[i];
    34     for ( int i = st, j = mid + 1; j <= ed; ++i, ++j )
    35         book[i] = temp[j];
    36     return;
    37 }
    38 
    39 int DFS( int dv )
    40 {
    41     int temp[MAXN];
    42     int hv = h( book );
    43     if ( hv + dv > limit ) return hv + dv;
    44     if ( hv == 0 )
    45     {
    46         find = true;
    47         return dv;
    48     }
    49 
    50     int next_limit = 1e5;
    51 
    52     for ( int i = 0; i < N - 1; ++i )
    53     for ( int j = i + 1; j < N; ++j )
    54     for ( int k = i; k < j; ++k )
    55     {
    56         for ( int x = 0; x < N; ++x )
    57             temp[x] = book[x];
    58 
    59         chuli( i, k, j );
    60 
    61         int new_limit = DFS( dv + 1 );
    62 
    63         if ( find ) return new_limit;
    64 
    65         next_limit = min( next_limit, new_limit );
    66         for ( int x = 0; x < N; ++x )
    67             book[x] = temp[x];
    68     }
    69 
    70     return next_limit;
    71 }
    72 
    73 void IDA_Star()
    74 {
    75     find = false;
    76     limit = h( book );
    77     while ( !find && limit < 5 )
    78         limit = DFS( 0 );
    79     return;
    80 }
    81 
    82 int main()
    83 {
    84     int T;
    85     scanf( "%d", &T );
    86     while ( T-- )
    87     {
    88         scanf( "%d", &N );
    89         for ( int i = 0; i < N; ++i )
    90             scanf( "%d", &book[i] );
    91 
    92         IDA_Star();
    93         if ( find ) printf( "%d\n", limit );
    94         else puts("5 or more");
    95     }
    96     return 0;
    97 }
  • 相关阅读:
    MySQL CREATE EVENT创建任务计划 定时执行任务
    MYSQL 的一些基本操作
    PHP mktime() 函数
    php格式化数字:位数不足前面加0补足
    浅析大数据量高并发的数据库优化
    使用SquirrelMQ打造一个千万级数据更新量的应用
    MySQL行锁深入研究
    MySQL 学习笔记 一
    利用C#操作配置文件(转)
    每个分类取最新的几条的SQL实现(转载记录)
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3043745.html
Copyright © 2020-2023  润新知