uvalive 3667(dfs)
2015-03-26 23:32
337 查看
题意:有n个长度需要测量,有一个刻度尺上有m个刻度,现在要所有的长度可以在刻度尺上直接测量出来,问在保证尺子长度尽量短的情况下m最小是多少,并输出这m个刻度。
题解:因为题目中提到m最大为7,可以暴力,首先为了让保证尺子长度最短,所以最后一个刻度一定是最大长度,把d数组排序去重,然后m * (m + 1) / 2 = n 中m是可能的最小的m,所以从这个m开始拿去暴力求解,然后枚举出一个值(vis[number] = 1)后,把剩下d中可以通过刚才枚举的值直接测量的都剔除掉(vis[number] = 1),继续递归,刻度数量达到当前m,如果所有d都可以直接测量(vis[number]
== 1),返回true。
#include <stdio.h>
#include <queue>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 55;
int n, d
, res
, pos[1000005], len, vis
;
bool dfs(int cnt) {
if (cnt == len) {
for (int i = 1; i <= n - 1; i++)
if (!vis[i])
return false;
return true;
}
for (int i = 1; i <= cnt - 1; i++)
for (int j = 1; j <= n - 1; j++) {
if (!vis[j]) {
int temp = res[i] + d[j];
if (temp >= d
|| temp <= res[cnt - 1])
continue;
res[cnt] = temp;
queue<int> q;
for (int k = 1; k <= cnt - 1; k++) {
temp = res[cnt] - res[k];
if (pos[temp] && !vis[pos[temp]]) {
vis[pos[temp]] = 1;
q.push(pos[temp]);
}
}
temp = d
- res[cnt];
if (pos[temp] && !vis[pos[temp]]) {
vis[pos[temp]] = 1;
q.push(pos[temp]);
}
if (dfs(cnt + 1))
return true;
while (!q.empty()) {
vis[q.front()] = 0;
q.pop();
}
}
}
return false;
}
int main() {
int cas = 1;
while (scanf("%d", &n) == 1 && n) {
memset(vis, 0, sizeof(vis));
memset(pos, 0, sizeof(pos));
for (int i = 1; i <= n; i++)
scanf("%d", &d[i]);
sort(d + 1, d + 1 + n);
n = unique(d + 1, d + 1 + n) - d - 1;
for (int i = 1; i <= n; i++)
pos[d[i]] = i;
len = sqrt(2 * n) - 1;
res[1] = 0;
while (!dfs(2))
len++;
res[len] = d
;
printf("Case %d:\n", cas++);
printf("%d\n", len);
for (int i = 1; i <= len; i++)
printf("%d ", res[i]);
printf("\n");
}
return 0;
}
题解:因为题目中提到m最大为7,可以暴力,首先为了让保证尺子长度最短,所以最后一个刻度一定是最大长度,把d数组排序去重,然后m * (m + 1) / 2 = n 中m是可能的最小的m,所以从这个m开始拿去暴力求解,然后枚举出一个值(vis[number] = 1)后,把剩下d中可以通过刚才枚举的值直接测量的都剔除掉(vis[number] = 1),继续递归,刻度数量达到当前m,如果所有d都可以直接测量(vis[number]
== 1),返回true。
#include <stdio.h>
#include <queue>
#include <math.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 55;
int n, d
, res
, pos[1000005], len, vis
;
bool dfs(int cnt) {
if (cnt == len) {
for (int i = 1; i <= n - 1; i++)
if (!vis[i])
return false;
return true;
}
for (int i = 1; i <= cnt - 1; i++)
for (int j = 1; j <= n - 1; j++) {
if (!vis[j]) {
int temp = res[i] + d[j];
if (temp >= d
|| temp <= res[cnt - 1])
continue;
res[cnt] = temp;
queue<int> q;
for (int k = 1; k <= cnt - 1; k++) {
temp = res[cnt] - res[k];
if (pos[temp] && !vis[pos[temp]]) {
vis[pos[temp]] = 1;
q.push(pos[temp]);
}
}
temp = d
- res[cnt];
if (pos[temp] && !vis[pos[temp]]) {
vis[pos[temp]] = 1;
q.push(pos[temp]);
}
if (dfs(cnt + 1))
return true;
while (!q.empty()) {
vis[q.front()] = 0;
q.pop();
}
}
}
return false;
}
int main() {
int cas = 1;
while (scanf("%d", &n) == 1 && n) {
memset(vis, 0, sizeof(vis));
memset(pos, 0, sizeof(pos));
for (int i = 1; i <= n; i++)
scanf("%d", &d[i]);
sort(d + 1, d + 1 + n);
n = unique(d + 1, d + 1 + n) - d - 1;
for (int i = 1; i <= n; i++)
pos[d[i]] = i;
len = sqrt(2 * n) - 1;
res[1] = 0;
while (!dfs(2))
len++;
res[len] = d
;
printf("Case %d:\n", cas++);
printf("%d\n", len);
for (int i = 1; i <= len; i++)
printf("%d ", res[i]);
printf("\n");
}
return 0;
}
相关文章推荐
- [dfs] UVALive 3667 Ruler
- UVALive 3667 dfs
- [dfs] UVALive 3667 Ruler
- uvalive3667(深搜)
- UVALive 6432 In uence(枚举+dfs或记忆化搜索+bitset)
- UVALive - 3667 Ruler
- UVALive - 6800 The Mountain of Gold?(Bellman-ford找负权回路,dfs)
- UVALive 7009 Secret Binary Tree(二分查找、dfs)
- UVALive - 6455 Stealing Harry Potter's Precious (bfs+dfs)
- UVALive 7272 Promotions 超详细题解(拓扑、dfs)
- UVALive 5107 dfs暴力搜索
- UVALive 7334 Kernel Knights (dfs)
- UVALive 6257 Chemist's vows --一道题的三种解法(模拟,DFS,DP)
- [UVALive 6663 Count the Regions] (dfs + 离散化)
- UVALive 4126 (LA 4126) Password Suspects AC自动机 + DP + 剪枝dfs
- 文章标题 UVALive 6432 Influence(dfs)
- UVALive3902 Network[贪心 DFS&&BFS]
- 【二项式定理】【DFS】UVALive - 7639 - Extreme XOR Sum
- DFS染色解决区域分块问题UVALive 6663
- UVALive 6432 Influence // 暴力dfs