[BZOJ1306] [CQOI2009] match循环赛 (搜索)
Description
Input
第一行包含一个正整数n,队伍的个数。第二行包含n个非负整数,即每支队伍的得分。
Output
输出仅一行,即可能的分数表数目。保证至少存在一个可能的分数表。
Sample Input
6
5 6 7 7 8 8
5 6 7 7 8 8
Sample Output
121
HINT
N<=8
Source
Solution
搜索,砍树式的剪枝。当某一队算到最后一场比赛时直接算结果,每次递归前判断如果以后几场全赢分数也达不到目标分数就剪枝,如果以后几场全输都超过目标分数也剪枝
代码运行时间刚好10sQAQ
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, a[10], cur[10], ans, d[4] = {3, 1, 0, 0}; 4 5 void DFS(int u, int v) 6 { 7 if(cur[u] > a[u] || cur[v] > a[v]) return; 8 if(a[u] - cur[u] > 3 * (n - v + 1)) return; 9 if(a[v] - cur[v] > 3 * (n - u + 1)) return; 10 if(u == n) 11 { 12 ans++; 13 return; 14 } 15 if(v == n) 16 { 17 int i = a[u] - cur[u]; 18 if(i > 3 || i == 2) return; 19 cur[u] += i, cur[v] += d[i]; 20 DFS(u + 1, u + 2); 21 cur[u] -= i, cur[v] -= d[i]; 22 return; 23 } 24 cur[u] += 3, DFS(u, v + 1), cur[u] -= 3; 25 cur[u]++, cur[v]++, DFS(u, v + 1), cur[u]--, cur[v]--; 26 cur[v] += 3, DFS(u, v + 1), cur[v] -= 3; 27 } 28 29 int main() 30 { 31 cin >> n; 32 for(int i = 1; i <= n; i++) 33 cin >> a[i]; 34 DFS(1, 2); 35 cout << ans << endl; 36 return 0; 37 }