[BZOJ1306] [CQOI2009] match循环赛 (搜索)

Description

Input

  第一行包含一个正整数n,队伍的个数。第二行包含n个非负整数,即每支队伍的得分。

Output

  输出仅一行,即可能的分数表数目。保证至少存在一个可能的分数表。

Sample Input

6
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 }
View Code

 

posted @ 2016-04-22 00:45  CtrlCV  阅读(381)  评论(0编辑  收藏  举报