首页 > 代码库 > hdu 1536 NIM博弈 (模板)

hdu 1536 NIM博弈 (模板)

推荐文章

博弈论初步:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561002.html

博弈解决思想:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561005.html

NIM游戏:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561008.html

关于SG函数:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561007.html

 

技术分享
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip>10 #include<climits>11 #include<string.h>12 #include<stdlib.h>13 #define INF 1e1114 #define MAXN 6015 using namespace std;16 17 int k, a[100], f[10001];18 int mex(int p)19 {20     int i, t;21     bool g[101] = { 0 };22     for (i = 0; i<k; i++)23     {24         t = p - a[i];25         if (t<0)    break;26         if (f[t] == -1)27             f[t] = mex(t);28         g[f[t]] = 1;29     }30     for (i = 0;; i++)31     {32         if (!g[i])33             return i;34     }35 }36 37 int main()38 { 39     int n, i, m, t, s;40     while (scanf("%d", &k), k) {41         for (i = 0; i<k; i++)42             scanf("%d", &a[i]);43         sort(a, a + k);44         memset(f, -1, sizeof(f));45         f[0] = 0;46         scanf("%d", &n);47         while (n--){48             scanf("%d", &m);49             s = 0;50             while (m--) {51                 scanf("%d", &t);52                 if (f[t] == -1)  f[t] = mex(t);53                 s = s^f[t]; 54             }55             if (s == 0)56                 printf("L");57             else58                 printf("W"); 59         }60         printf("\n");61     }62     return 0;63 }
递归版

 

技术分享
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #include<queue> 7 #include<algorithm> 8 #include<map> 9 #include<iomanip>10 #include<climits>11 #include<string.h>12 #include<stdlib.h>13 #define INF 1e1114 #define MAXN 6015 using namespace std;16 17 18 19 int sg[10010];20 int k, knum[110];21 int flag[110];22 23 24 int met(int n)25 {26     int i, ans = 0;27     memset(flag, 0, sizeof(flag));28     for (i = 0; i < k; i++)29         if (n - knum[i] >= 0)30             flag[sg[n - knum[i]]] = 1;31     for (i = 0; i <= 101; i++)32         if (flag[i] == 0) return i;33 }34 35 36 void Sprague_Grundy()37 {38     int i;39     for (i = 1; i <= 10000; i++)40         sg[i] = met(i);41 }42 43 44 int main()45 {46     int i, n, l, num, ans;47     while (~scanf("%d", &k) && k)48     {49         for (i = 0; i < k; i++)50             scanf("%d", &knum[i]);51         Sprague_Grundy();52         scanf("%d", &n);53         while (n--)54         {55             ans = 0;56             scanf("%d", &l);57             while (l--)58             {59                 scanf("%d", &num);60                 ans ^= sg[num];61             }62             printf(ans == 0 ? "L" : "W");63         }64         printf("\n");65     }66     return 0;67 }
循环版

 

hdu 1536 NIM博弈 (模板)