0%

Sticks

思路 怎么搜dfs(已经复原几根木棍k,上一个木棍的下标last,当前复原木棒的进度s).

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75

#include<bits/stdc++.h>

using namespace std;

const int N = 70;

int n,m; //n木棍数量
int num, len, sum;//len原来的长度,sum目前小木棍长度之和,num = sum / len;
int a[N]; //储存 木棍
bool st[N]; //标记是否用过某一小木棍

bool cmp(int a, int b) { return a > b; }

bool dfs(int k, int last, int s)
{

if (k > num)return true; //所有木棍复原完成

if (s == len)
return dfs(k + 1, 1, 0);//完成当前木棍的复原,进行下一个

int fail = 0;//fail记录的是最近一次尝试拼接的木棍长度。这样再回溯时就不会再尝试相同长度的木棍。 (不是很理解还)

for (int i = last; i <= n; i++)//从last开始
{
if (!st[i]&&a[i]+s<=len&&fail!=a[i])//a[i]+s<=len减去不必要的搜索
{
st[i] = true;//标记
if (dfs(k, i, s + a[i]))return true;
st[i] = false;//复原

fail = a[i];

if (s == 0 || s + a[i] == len)return false;//(菜狗还不是很理解)
}
}
return false;
}

int main()
{
while (cin >> n && n)
{
memset(st, false, sizeof st);
memset(a, 0, sizeof a);
m = num = len = sum = 0;

for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += a[i];
}

sort(a + 1, a + 1 + n, cmp);


for (len = a[1]; len <= sum / 2; len++)//保证整除并且len的长度小于sum/2 若大于则只有一根
{
if (sum % len)continue;

num = sum / len;

if (dfs(1, 1, 0)) {
m = 1;
cout << len << endl;
break;
}
}
if(!m)cout << sum << endl;
}
return 0;
}


-------------本文结束感谢您的阅读-------------

欢迎关注我的其它发布渠道