比赛
题目: http://www.lydsy.com/JudgeOnline/problem.php?id=3139
题解:
3$\le$N$\le$10,比较明显是一个搜索题,一开始我是直接搜了,没有记忆化,如果先枚举每一队可以的胜负平,加上合法性判断,再进行枚举,那么是可以拿到70分的,这里有一个重要的剪枝,在枚举了每一队的情况后一定要判断胜场+负场是否相等,这里有20分。。
以下正解:
在爆搜的时候我们每一队每一队去枚举,我们尝试着记忆化。
首先我们发现,对于一组数据,得分序列(读入序列)的顺序和答案是无关的,那么我们记忆当还有x个队没有处理时,每一队的剩余得分为$a_{n - x + 1}$,$a_{n - x + 2}$,......,$a_{n}$ 这个状态对答案的贡献,通过对这个数组的排序,我们可以大量去重,甚至不需要加太多的优化都可以AC。
1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #define REP(i, a, b) for (int i = a; i < b; i++) 5 #define mp make_pair 6 #define pb push_back 7 #define clr(x) memset(x, 0, sizeof(x)) 8 #define xx first 9 #define yy second 10 using namespace std; 11 typedef long long i64; 12 typedef pair<int, int> pii; 13 const int inf = 0x3f3f3f3f; 14 const i64 INF = 0x3f3f3f3f3f3f3f3fll; 15 template <typename T> void Max(T &a, T b) { if (a < b) a = b; } 16 template <typename T> void Min(T &a, T b) { if (a > b) a = b; } 17 //*************************************************************** 18 19 int n; 20 struct Conditions { 21 int a[11]; 22 inline long long hash() { 23 long long ret = 0; 24 rep(i, 0, n) ret = ret * 28 + a[i]; 25 return ret; 26 } 27 inline void Sort() { sort(a + n - a[0] + 1, a + 1 + n); } 28 } start, bound; 29 map <i64, i64> M; 30 const int mod = 1e9 + 8; 31 long long dfs(int step, Conditions now) { 32 if (now.a[0] == 1) return M[now.hash()]; 33 if (now.a[n - now.a[0] + 1] > 3 * (n + 1 - step)) return -1; 34 if (step > n) { 35 now.a[0]--; 36 now.Sort(); 37 if (M[now.hash()]) return M[now.hash()]; 38 return M[now.hash()] = dfs(n - now.a[0] + 2, now); 39 } 40 long long res = 0, tmp; 41 int idx = n - now.a[0] + 1; 42 if (now.a[idx] >= 3) { 43 now.a[idx] -= 3; 44 tmp = dfs(step + 1, now); 45 if (tmp != -1) (res += tmp) %= mod; 46 now.a[idx] += 3; 47 } 48 if (now.a[idx] >= 1 && now.a[step] >= 1) { 49 now.a[idx] -= 1, now.a[step] -= 1; 50 tmp = dfs(step + 1, now); 51 if (tmp != -1) (res += tmp) %= mod; 52 now.a[idx] += 1, now.a[step] += 1; 53 } 54 if (now.a[step] >= 3) { 55 now.a[step] -= 3; 56 tmp = dfs(step + 1, now); 57 if (tmp != -1) (res += tmp) %= mod; 58 now.a[idx] += 1; 59 now.a[step] += 3; 60 } 61 res = res ? res : -1; 62 return res; 63 } 64 int main() { 65 scanf("%d", &n); 66 start.a[0] = n; 67 rep(i, 1, n) scanf("%d", &start.a[i]); 68 start.Sort(); 69 bound.a[0] = 1, bound.a[n] = 0; M[bound.hash()] = 1; 70 printf("%lld\n", dfs(2, start)); 71 return 0; 72 }