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 }

 

你可能感兴趣的:(sort)