P5675-[GZOI2017]取石子游戏【博弈论,dp】
生活随笔
收集整理的這篇文章主要介紹了
P5675-[GZOI2017]取石子游戏【博弈论,dp】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P5675
題目大意
nnn堆石子,第iii堆有aia_iai?個。指定一些石子堆使得先手必勝并指定一個先手第一個取的位置使得先手必敗,求有多少方案數。
解題思路
根據NIMNIMNIM游戲,只要石子數異或和為000則先手必敗。
然后我們考慮枚舉指定先手先去哪一堆石頭,我們要選擇一些石子堆使沒有任何一種方法取走一些石頭使得先手必敗。
我們用fi,jf_{i,j}fi,j?表示在不包括枚舉的石頭堆的情況下,前iii堆石頭有多少種選擇方案使得其異或和為jjj。然后若強制先手選擇第kkk堆石頭那么方案數就是∑i=ak∞fn,i\sum_{i=a_k}^\infty f_{n,i}i=ak?∑∞?fn,i?
時間復雜度O(n3)O(n^3)O(n3)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=210,XJQ=1e9+7; int n,a[N],f[N][256],ans; int main() {scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int k=1;k<=n;k++){f[0][0]=1;for(int i=1;i<=n;i++){if(i==k){for(int j=0;j<256;j++)f[i][j]=f[i-1][j]; }else{for(int j=0;j<256;j++)f[i][j]=(f[i-1][j]+f[i-1][j^a[i]])%XJQ;}}for(int i=a[k];i<256;i++)ans=(ans+f[n][i])%XJQ;}printf("%d",ans); }總結
以上是生活随笔為你收集整理的P5675-[GZOI2017]取石子游戏【博弈论,dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有什么好用的PDF转Word工具分享PD
- 下一篇: 内存占用更少如何降低电脑内存使用率