思路
用结构体\(gap\)来维护每一个时间间隔进行搜索即可,具体看注释吧。
代码
// POJ1167.cpp
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 500;
int n, tmp, siz, ans = 17;
struct gap
{
// gaps: the value of this interval;
// sttime: the start of the circular time;
// stats: the number of the points hit following;
int gaps, sttime, stats;
} ints[maxn];
bool cmp(gap a, gap b)
{
return a.stats > b.stats;
}
int vis[maxn];
// check(start, interval): check if it is valid;
bool check(int start, int interval)
{
for (register int i = start; i < 60; i += interval)
if (!vis[i])
return false;
return true;
}
// dfs(st, dep, remain): search the intervals from ints[st:];
inline void dfs(int st, int dep, int remain)
{
if (remain / ints[st].stats + dep >= ans)
return;
if (!remain)
{
ans = min(ans, dep);
return;
}
for (register int i = st; i <= siz; i++)
if (check(ints[i].sttime, ints[i].gaps))
{
for (register int tim = ints[i].sttime; tim < 60; tim += ints[i].gaps)
// set the times of visiting;
vis[tim]--;
dfs(i, dep + 1, remain - ints[i].stats);
for (register int tim = ints[i].sttime; tim < 60; tim += ints[i].gaps)
// recover the times of visiting;
vis[tim]++;
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &tmp), vis[tmp]++;
for (int i = 0; i < 30; i++)
for (int j = i + 1; i + j < 60; j++)
if (check(i, j))
{
ints[++siz].gaps = j, ints[siz].sttime = i;
// calc the stations upnext;
for (int k = ints[siz].sttime; k < 60; k += ints[siz].gaps)
ints[siz].stats++;
}
sort(ints + 1, ints + 1 + siz, cmp);
dfs(1, 0, n);
printf("%d\n", ans);
return 0;
}