bzoj 5449 序列

https://www.lydsy.com/JudgeOnline/problem.php?id=5449

话说很早以前做过。。算是IDA*的板子吧,一个简单的估价函数就可以过去了

 1 %:pragma GCC optimize(2)
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int a[50],n,maxd,T;
 6 bool fl;
 7 inline bool check()
 8 {
 9     for(int i=1;i<n;++i)
10         if(a[i]>a[i+1])
11             return 0;
12     return 1;
13 }
14 //reverse一次,相邻两数绝对值之差大于1的最多减少1个,
15 //因此相邻两数绝对值之差大于1的个数一定小于等于所需reverse次数
16 inline int hh()
17 {
18     int cnt=0;
19     for(int i=1;i<n;++i)
20         if(abs(a[i+1]-a[i])>1)
21             cnt++;
22     return cnt;
23 }
24 inline void reverse1(const int& r)
25 {
26     int i,t;
27     for(i=1;i<=r/2;++i)
28     {
29         t=a[i];a[i]=a[r-i+1];a[r-i+1]=t;
30     }
31 }
32 void dfs(int x,int last)
33 {
34     if(fl)  return;
35     if(x==maxd)
36     {
37         if(check()) fl=1;
38         return;
39     }
40     if(x+hh()>maxd)  return;
41     for(int i=2;i<=n;++i)
42         if(i!=last)
43         {
44             reverse(a+1,a+i+1);
45             dfs(x+1,i);
46             reverse(a+1,a+i+1);
47         }
48 }
49 int main()
50 {
51     int i;
52     scanf("%d",&T);
53     while(T--)
54     {
55         fl=0;
56         scanf("%d",&n);
57         for(i=1;i<=n;++i)
58             scanf("%d",&a[i]);
59         for(maxd=0;maxd<=30;++maxd)
60         {
61             dfs(0,0);
62             if(fl)  break;
63         }
64         printf("%d\n",maxd);
65     }
66     return 0;
67 }
View Code

此题http://210.33.19.103/contest/823/problem/2(序列)同以上题


upd20190222:

根据网上一些高分程序优化了一下估价函数和代码...

 1 %:pragma GCC optimize(2)
 2 #include<cstdio>
 3 #include<algorithm>
 4 using namespace std;
 5 int a[50],n,maxd,T;
 6 bool fl;
 7 inline int abs1(int x){return x>0?x:-x;}
 8 inline int hh()
 9 {
10     int cnt=(a[n]!=n);
11     for(int i=1;i<n;++i)
12         if(abs1(a[i+1]-a[i])>1)
13             ++cnt;
14     return cnt;
15 }
16 void dfs(int x,int last)
17 {
18     int h=hh();
19     if(!h)    {fl=1;return;}
20     if(x+h>maxd)  return;
21     for(int i=2;i<=n;++i)
22         if(i!=last)
23         {
24             reverse(a+1,a+i+1);
25             dfs(x+1,i);
26             if(fl)    return;
27             reverse(a+1,a+i+1);
28         }
29 }
30 int main()
31 {
32     int i;
33     scanf("%d",&T);
34     while(T--)
35     {
36         fl=0;
37         scanf("%d",&n);
38         for(i=1;i<=n;++i)
39             scanf("%d",&a[i]);
40         for(maxd=0;maxd<=40;++maxd)
41         {
42             dfs(0,0);
43             if(fl)  break;
44         }
45         printf("%d\n",maxd);
46     }
47     return 0;
48 }
View Code

 

posted @ 2018-10-23 21:31  hehe_54321  阅读(315)  评论(0编辑  收藏  举报
AmazingCounters.com