Stones
题目概述
集合 \(A\),小 \(X\) 和小 \(Y\) 选择其中一个数 \(x\),然后将石堆拿走 \(x\) 个,谁不能操作谁输,一开始石堆石头数量为 \(k\).
数据范围:\(1\leq k\leq 10^5,1\leq n\leq 100,1\leq a_i\leq 10^9\)。
分析
设 \(f_i\) 表示到 \(i\) 时若再进行一次操作那他是必胜还是必败。
设后继集合 \(S_i\),有:
\[f_i=[\sum_{x\in S_i}[f_x]]\geq 1
\]
然后没了。
代码
时间复杂度 \(\mathcal{O}(nk)\),代码如下:
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <cstring>
#define int long long
#define N 105
#define K 100005
using namespace std;
int sg[K],n,k,a[N];
signed main(){cin >> n >> k;int mn = 1e18;for (int i = 1;i <= n;i ++) scanf("%lld",&a[i]),mn = min(mn,a[i]);stable_sort(a + 1,a + 1 + n);for (int i = 0;i < mn;i ++) sg[i] = 0;for (int i = mn;i <= k;i ++) {sg[i] = 0;for (int j = 1;j <= n && a[j] <= i;j ++)sg[i] |= sg[i - a[j]] == 0;}if (sg[k]) puts("First");else puts("Second");return 0;
}