为什么启发式搜索的题书上说是迭代加深???
思路跟大多数题一样,都是先把原问题进行处理,把处理过的数据再抽象成算法问题,因为原问题不好直接深搜,所以要先处理
注意启发式剪枝的>=ans就剪枝,而不是>才剪枝
注意题目上说了可以有多条线路的时间是一样的(两条线路起点都是3,间隔都是5)
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>
#define INF 0x3f3f3f3f
#define IMAX 2147483646
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
using namespace std;
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <cmath>
#include <stack>
#define INF 0x3f3f3f3f
#define IMAX 2147483646
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
using namespace std;
struct Node {
int beg, l, times;
bool operator<(const Node &b)const {
return times > b.times;
}
}a[3333];
int n, t, cnt[333],tot,ans;
int pd(int beg, int l) {
int ts = 0;
while (beg < 60) {
if (!cnt[beg])return 0;
beg += l;
ts++;
}
return ts;
}
void dfs(int x, int now, int sum) {
if (now == n) {
ans = min(ans, sum);
return;
}
for (int i = x; i < tot; i++) {
if (sum + (n - now) / a[i].times >= ans)break;//启发式剪枝
if (!pd(a[i].beg, a[i].l))continue;//正确性判断
for (int j = a[i].beg; j < 60; j += a[i].l)
cnt[j]--;
dfs(i, now + a[i].times, sum + 1);
for (int j = a[i].beg; j < 60; j += a[i].l)
cnt[j]++;
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%d", &t), cnt[t]++;
for(int i = 0;i<60;i++)
for (int j = i + 1; j < 60 - i; j++)
if (pd(i, j))a[tot].beg = i, a[tot].l = j, a[tot++].times = pd(i, j);
sort(a, a + tot);
ans = 17;
dfs(0, 0, 0);
printf("%d\n", ans);
return 0;
}