题目大意
给定n和刻度d,设计一个拥有m个刻度的尺子,使得每个d都可以直接的量出来,要求在m尽量小的情况下保证尺子的总长度尽量短.
分析
此题目应该采用迭代深搜
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#define maxd 1000000+10
#define maxn 50+5
using namespace std;
bool vis[maxn];
int hav[maxd], dist[8],d[maxn];
int n;
int ans;
bool dfs(int cur)
{
if (cur == ans) {
for (int i = 1; i < n; i++)
if (!vis[i]) return false;
return true;
}
for (int j = 1; j <n; j++) {
if(!vis[j])
for (int i = 1; i < cur; i++) {
int dd = dist[i] + d[j];
if (dd <= dist[cur - 1]) continue;
if (dd >= d[n]) continue;
dist[cur] = dd;
queue<int>q;
for (int k = 1; k < cur; k++) {
int val = dist[cur] - dist[k];
if (hav[val] && !vis[hav[val]]) {
q.push(hav[val]);
vis[hav[val]] = true;
}
}
int val = d[n] - dist[cur];
if (hav[val] && !vis[hav[val]]) {
q.push(hav[val]);
vis[hav[val]] = true;
}
if (dfs(cur + 1)) return true;
while (!q.empty()) {
int p = q.front();
q.pop();
vis[p] = false;
}
}
}
return false;
}
int main()
{
int kase = 0;
while (cin >> n && n) {
for (int i = 1; i <= n; i++)
cin >> d[i];
sort(d + 1, d + n + 1);
n = unique(d + 1, d + n + 1) - d - 1;
memset(hav, 0, sizeof(hav));
for (int i = 1; i <= n; i++)
hav[d[i]] = i;
dist[1] = 0;
memset(vis, 0, sizeof(vis));
for (ans = 2;; ans++) //迭代深搜
if (dfs(2)) break;
printf("Case %d:\n%d\n", ++kase, ans);
for (int i = 1; i <ans; i++)
cout << dist[i] << " ";
cout << d[n];
putchar('\n');
}
return 0;
}