洛谷P3230 比赛
emmmmmm,这个之前讲课的原题居然出到比赛里了。
我怒肝2h+然后A了此题,结果还是被某高一巨佬吊打......
题意:n个球队两两比赛,胜得3分,败得0分,平得1分。
现有一个总分表,求问可能的比赛情况。
解:
发现答案与球队的顺序无关,于是按照分数排序。
然后发现可能搜到重复状态,可以记忆化吗?可以拿hash记忆化......(毒瘤)。
然后枚举当前第一队与其他队的胜负情况,这里我又写了个DFS(毒瘤 << 1)。
然后没了......注意这道题实现起来满满的毒瘤。
1 #include <cstdio> 2 #include <algorithm> 3 4 const int N = 12, B = 31, OM = 1000000, MO = 1e9 + 7; 5 6 struct Node { 7 int t, a[N], h, nex, ans; 8 inline void geth() { 9 h = 0; 10 for(int i = 1; i <= t; i++) { 11 h = h * B % OM + a[i]; 12 while(h >= OM) { 13 h -= OM; 14 } 15 } 16 return; 17 } 18 inline bool operator ==(const Node &d) const { 19 if(t != d.t) { 20 return 0; 21 } 22 for(int i = 1; i <= t; i++) { 23 if(a[i] != d.a[i]) { 24 return 0; 25 } 26 } 27 return 1; 28 } 29 inline void st() { 30 std::sort(a + 1, a + t + 1); 31 std::reverse(a + 1, a + t + 1); 32 /*while(!a[t] && t) { 33 t--; 34 }*/ 35 return; 36 } 37 inline void out() { 38 for(int i = 1; i <= t; i++) { 39 printf("%d ", a[i]); 40 } 41 puts(""); 42 return; 43 } 44 }node[1500000], temp; int top; 45 46 int head[OM]; 47 48 inline int find(Node x) { 49 int h = x.h; 50 for(int i = head[h]; i; i = node[i].nex) { 51 if(node[i] == x) { 52 return node[i].ans; 53 } 54 } 55 return -1; 56 } 57 58 inline void insert(Node sta) { 59 int h = sta.h; 60 node[++top] = sta; 61 node[top].nex = head[h]; 62 head[h] = top; 63 return; 64 } 65 66 int DFS(Node, int); 67 68 int DFSp(Node sta, int k, int lw) { // a[1] -> a[k] ing 69 70 if(k > sta.t) { 71 if(sta.a[1]) { 72 return 0; 73 } 74 std::swap(sta.a[1], sta.a[sta.t]); 75 sta.t--; 76 return DFS(sta, lw); 77 } 78 if((sta.t - k + 1) * 3 < sta.a[1]) { 79 return 0; 80 } 81 82 int ans = 0; 83 if(sta.a[k] >= 3) { // 1 lose 84 sta.a[k] -= 3; 85 ans += DFSp(sta, k + 1, lw - 1); 86 ans %= MO; 87 sta.a[k] += 3; 88 } 89 if(sta.a[1] >= 3) { // 1 win 90 sta.a[1] -= 3; 91 ans += DFSp(sta, k + 1, lw - 1); 92 ans %= MO; 93 sta.a[1] += 3; 94 } 95 if(sta.a[1] >= 1 && sta.a[k] >= 1) { // both 96 sta.a[1] -= 1; 97 sta.a[k] -= 1; 98 ans += DFSp(sta, k + 1, lw); 99 ans %= MO; 100 } 101 return ans; 102 } 103 104 int DFS(Node sta, int last) { 105 106 sta.st(); 107 if(sta.t == 1) { 108 if(!last && !sta.a[1]) { 109 return 1; 110 } 111 return 0; 112 } 113 114 sta.geth(); 115 int t = find(sta); 116 if(t > -1) { 117 return t; 118 } 119 120 int ans = DFSp(sta, 2, last); 121 122 sta.ans = ans; 123 insert(sta); 124 125 return ans; 126 } 127 128 int main() { 129 130 int n, tot = 0; 131 scanf("%d", &n); 132 for(int i = 1; i <= n; i++) { 133 scanf("%d", &temp.a[i]); 134 tot += temp.a[i]; 135 } 136 137 temp.t = n; 138 int ans = DFS(temp, tot - (n - 1) * n); 139 140 printf("%d", ans); 141 142 return 0; 143 }
注意到洛谷rank1的搜索方法和我大同小异,但是速度吊打我14.75倍(毒瘤)。他以为这个东西可以用LL装下(真TM的可以!!!我是沙雕!),然后我就SB的又存又传了一大堆数组......