算法:IDDFS
思路
- 筛出所有可行的线路;
- 限制搜索深度
d
e
p
dep
dep从
1
1
1开始,搜索不同的路线组合尝试覆盖所有的公交车
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100005;
int bus[maxn],ans[maxn];
int n,tot,dep;
struct node
{
int st,inter,num;
}path[maxn];
inline bool cmp(node a,node b)
{
return a.num>b.num;
}
inline int read()
{
int st=0,f=1;
char c=getchar();
while (c<'0'||c>'9')
{
if (c=='-')
{
f=-1;
}
c=getchar();
}
while (c>='0'&&c<='9')
{
st=(st<<1)+(st<<3)+c-'0';
c=getchar();
}
return st*f;
}
inline void write(int x)
{
if (x<0)
{
x=~(x-1);
putchar('-');
}
if (x>9)
{
write(x/10);
}
putchar(x%10+'0');
}
inline bool check(int s,int t)
{
for (int i=s;i<60;i+=t)
{
if (!bus[i])
{
return false;
}
}
return true;
}
inline bool dfs(int cur,int pa,int cov)
{
if (cur==dep)
{
if (cov>=n)
{
return true;
}
return false;
}
if (cov+(dep-cur)*path[pa].num<n)
{
return false;
}
for (int i=pa;i<=tot;i++)
{
if (check(path[i].st,path[i].inter))
{
int s=path[i].st,t=path[i].inter;
for (int j=s;j<=59;j+=t)
{
bus[j]--;
}
if (dfs(cur+1,i,cov+path[i].num)==true)
{
return true;
}
for (int j=s;j<=59;j+=t)
{
bus[j]++;
}
}
}
return false;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)
{
int x=read();
bus[x]++;
}
tot=0;
for (int i=0;i<=29;i++)
{
if (bus[i]==0)
{
continue;
}
for (int j=i+1;j<=59-i;j++)
{
if (check(i,j))
{
path[++tot].st=i;
path[tot].inter=j;
path[tot].num=1+(59-i)/j;
}
}
}
sort(path+1,path+tot+1,cmp);
while (dfs(0,1,0)==false)
{
dep++;
}
cout<<dep<<endl;
return 0;
}