vijos p1526——超级汉诺塔

描述

在YYHS有一种奇异的汉诺塔,在汉诺塔中存放的圆盘式上大下小的,且在同一塔上的相邻两个圆盘大小之和,恰为一个质数,现有N根汉诺塔,问最多能将大小从1开始连续的圆盘放入这N个汉诺塔中。注意放入的顺序必须是从1~N。

格式

输入格式

一个整数N(1<=N<=15).

输出格式

输出最多能放的圆盘数目。

样例1

样例输入1

2

样例输出1

7


样例解释:
4
3  7
2  6
1  5

限制

各个测试点1s

 
 
由于要求是从1到N连续的数放进汉诺塔中,所以设i,j∈[1,N]且i<j
因为小于15,所以可以用二分法找N,然后看是否成立。
算法:二分+匈牙利。x集和y集都∈[1,N],x匹配大于他的标号的点,最后若得到的最大匹配与N的差值为塔的个数,
则表示成立。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2005;
 4 int map[maxn][maxn];
 5 int match[maxn];
 6 bool prime[maxn];
 7 bool vis[maxn];
 8 int n;int ggg;
 9 inline bool ok(int x)
10 {
11     for(int i=2;i<=sqrt(x+0.5);i++)
12     if(x%i==0)return false;
13     return true;
14 }
15 inline void gg()
16 {
17     scanf("%d",&n);
18     for(int i=2;i<=2000;i++)
19     if(ok(i))prime[i]=true;
20     return ;
21 }
22 bool dfs(int x)
23 {
24     for(int i=x+1;i<=ggg;i++)
25     {
26         if(prime[x+i]==true&&vis[i]==false)
27         {
28             vis[i]=true;
29             if(match[i]==-1||dfs(match[i]))
30             {
31                 match[i]=x;
32                 return true;
33             }
34         }
35     }
36     return false;
37 }
38 inline int hungary(int x)
39 {
40     int count=0;ggg=x;
41     memset(match,-1,sizeof(match));
42     for(int i=1;i<=x;i++)
43     {
44         memset(vis,false,sizeof(vis));
45         if(dfs(i))count++;
46     }
47     return count;
48 }
49 int main()
50 {
51      gg();
52     int left=1,right=2000;
53     while(left<=right)
54     {
55         int mid=(left+right)>>1;
56         if(mid-hungary(mid)<=n)left=mid+1;
57         else right=mid-1;
58     }
59     printf("%d",right);
60     return 0;
61 }

 

posted @ 2016-11-09 17:27  deadshotz  阅读(636)  评论(0编辑  收藏  举报