码迷,mamicode.com
首页 > 其他好文 > 详细

山东省第九届省赛G题game

时间:2019-04-06 11:12:54      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:ios   ring   表示   memset   printf   ++   span   初始   mod   

题目是一个很像NIM博弈的一道dp问题,实际上就是利用了NIM博弈的结论,XOR为0

 

原题目的意思是给定n堆石头,可以取走0-d堆石头,问取走之后后手必胜(实际上就是xor为0的情况)的取法数目

 

就是利用dp,状态表示就是前i堆,取走j堆,xor值为k

 

初始化的的状态就是dp[i,0,0]=1;

转移方程为dp[i,j,k]=dp[i-1,j,k]+dp[i-1,j-1,k^val[i]];

也就是由第i堆不取产生k的情况,和第i堆取走之后前i-1堆k^val[i]的值

 

计算所有堆的抑或值,这样取出来的堆只需要值为sum就相当于取走直接剩下的抑或值为0

最后只需要计算dp[n][i][sum]的值,i∈[0,d],其中i=0的情况等价于sum=0的情况,直接处理

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 const int MOD=(int)1e9+7;
 6 
 7 int dp[1001][12][1030];
 8 int num[1005];
 9 
10 int main(){
11     int T;
12     std::cin>>T;
13     while(T--)
14     {
15         memset(dp,0,sizeof(dp));
16         int n,d;
17         scanf("%d%d",&n,&d);
18         int sum=0;
19         for(int i=1;i<=n;i++)
20         {
21             scanf("%d",&num[i]);
22             sum^=num[i];
23         }
24 
25         for(int i=0;i<=n;i++)
26         {
27             dp[i][0][0]=1;
28         }
29 
30         for(int i=1;i<=n;i++)
31         {
32             for(int j=1;j<=d;j++)
33             {
34                 for(int k=0;k<=1023;k++)
35                 {
36                     dp[i][j][k]=(dp[i-1][j][k]+dp[i-1][j-1][k^num[i]])%MOD;
37                 }
38             }
39         }
40 
41         int ans=0;
42         for(int i=1;i<=d;i++)
43         {
44             ans=(ans+dp[n][i][sum])%MOD;
45         }
46         if(sum==0) ans++;
47 
48         printf("%d\n",ans);
49         
50     }
51     return 0;
52 }

 

山东省第九届省赛G题game

标签:ios   ring   表示   memset   printf   ++   span   初始   mod   

原文地址:https://www.cnblogs.com/rign/p/10661066.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!