Boapath

   :: 首页  :: 新随笔  ::  ::  :: 管理

题意:有n堆,2个人,每次可以从某1堆中取出任意个(至少1个),或者把一堆分成2个小堆。

题目分析:

  一开始看到把1堆分成很多堆,我还有点小激动啊!可是刚准备写就发现,每一堆的可能石子数居然那么大(2^31-1)!坑爹啊!记忆化搜索肯定不行,数组都开不下。

  ……然后悲催的我,在昨天的停电+证明的摧残下又继续想了想。

  (╯°Д°)╯( ┻━┻) !想不出来怎么换一种算法了! 然后我又去看解题报告了!!! T T……

  最后居然是打表啊!打表啊!(╯°Д°)╯( ┻━┻(又是打表!还让不让人活了!))!

  然后我苦逼地打了一张表……

  贴出打的表吧……

  

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<iostream>
 5 using namespace std;
 6 const int N = 999;
 7 int sg[1001];
 8 int dfs(int x){
 9     if(sg[x] != -1)return sg[x];
10     bool g[1001] = {0};
11     int tp = dfs(x-1);
12      for(int i=1;i<=x;i++){
13         dfs(x-i);
14         g[sg[x-i]]=1;
15     }
16 
17     for(int i = 1;i<(x)/2+1;i++){
18         int t = dfs(i)^dfs(x-i);
19         g[t] = 1;
20     }
21     for(int i = 0;;i++){
22         if(!g[i])return sg[x] = i;
23     }
24 }
25 int main()
26 {
27 #ifdef LOCALL
28     //freopen("in2.txt","r",stdin);
29     freopen("out.txt","w",stdout);
30 #endif
31     memset(sg,-1,sizeof sg);
32     dfs(N);
33     for(int i = 0;i<N;i++){
34         cout<<sg[i]<<endl;
35     }
36 
37     return 0;
38 }
HDU 3032打表代码

 

  然后打出表如下:只列了20组——规律还是很明显的……从1开始,4个为一个循环节,第三个和第四个对调一下……

  sg[0]:0
  sg[1]:1
  sg[2]:2
  sg[3]:4
  sg[4]:3
  sg[5]:5
  sg[6]:6
  sg[7]:8
  sg[8]:7
  sg[9]:9
  sg[10]:10
  sg[11]:12
  sg[12]:11
  sg[13]:13
  sg[14]:14
  sg[15]:16
  sg[16]:15
  sg[17]:17
  sg[18]:18
  sg[19]:20
  sg[20]:19

   ……

 

  总之,以后如果数据太大,可以尝试打表(嘛……反正也暂时想不到其他方法)看有没有规律……

  不过最后要说cxlove下面的评论简直让我有点欣慰……想不到啊想不到!如果不打表死也做不出来啊!谁知道要打表啊!丧心病狂!

  

番外:

  窝:唉……还是意识不够……

  Big窝:(╯°Д°)╯( ┻━┻(你以为LOL呢!还意识!))

  窝:……T T 

posted on 2014-01-18 14:47  Boapath  阅读(707)  评论(0编辑  收藏  举报