洛谷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 }
AC代码

注意到洛谷rank1的搜索方法和我大同小异,但是速度吊打我14.75倍(毒瘤)。他以为这个东西可以用LL装下(真TM的可以!!!我是沙雕!),然后我就SB的又存又传了一大堆数组......

posted @ 2018-10-17 16:09  huyufeifei  阅读(172)  评论(0编辑  收藏  举报
试着放一个广告栏(虽然没有一分钱广告费)

『Flyable Heart 応援中!』 HHG 高苗京铃 闪十PSS 双六 電動伝奇堂 章鱼罐头制作组 はきか 祝姬 星降夜