山东省第九届省赛G题game

Posted rign

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了山东省第九届省赛G题game相关的知识,希望对你有一定的参考价值。

题目是一个很像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
",ans);
49         
50     }
51     return 0;
52 }

 

以上是关于山东省第九届省赛G题game的主要内容,如果未能解决你的问题,请参考以下文章

2018山东第九届省赛总结与反思

第九届省赛嵌入式设计与开发(客观题)解析(上)

蓝桥杯单片机第九届省赛客观题(深夜学习——单片机)

第九届省赛程序设计题--彩灯控制器蓝桥杯真题—02

总结2018年山东省第九届ACM大学生程序设计竞赛

蓝桥日记②2018第九届省赛(软件类)JavaA组★答案解析