2018.09.25 poj2068 Nim(博弈论+dp)】的更多相关文章

传送门 题意简述:m个石子,有两个队每队n个人循环取,每个人每次取石子有数量限制,取最后一块的输,问先手能否获胜. 博弈论+dp. 我们令f[i][j]f[i][j]f[i][j]表示当前第i个人取石子,石子还剩下j个时能否获胜. 显然如果有取法让轮到第(i+1)(i+1)(i+1) modmodmod 2n2n2n 个人有必败状态,那么的当前就是必胜状态. 再令k=(i+1)k=(i+1)k=(i+1) modmodmod 2n2n2n 于是f[i][j]=f[k][j−1]∣f[k][j−2…
http://poj.org/problem?id=2068 博弈论的动态规划,依然是根据必胜点和必输点的定义,才明白过来博弈论的dp和sg函数差不多完全是两个概念(前者包含后者),sg函数只是mex操作处理多个博弈游戏的一种方法,mdzz要改以前的标签了. f [ i ] [ j ] [ k ] 表示: i队伍在第j个队员取前还剩下k个石头的状态为i队伍必胜还是必输. 代码 #include<cstdio> #include<cstring> #include<algori…
传送门 又一道虚树入门题. 这个dp更简单啊. 直接记录每个点到1的距离,简单转移就行了. 代码: #include<bits/stdc++.h> #define N 250005 #define ll long long #define min(a,b) (a<b?a:b) using namespace std; inline ll read(){ ll ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); while(…
传送门 虚树入门题? 好难啊. 在学习别人的写法之后终于过了. 这道题dp方程很好想. 主要是不好写. 简要说说思路吧. 显然最优值只能够从子树和父亲转移过来. 于是我们先dfs一遍用儿子更新父亲,然后再dfs一遍用父亲更新儿子. 这样搞完之后可以统计出每个点所属的管辖点. 然后统计. 但这样单次跑是O(n)O(n)O(n)的不优秀. 考虑优化算法的时间复杂度. 注意到所有管辖点加起来只有O(n)O(n)O(n)个. 因此我们每次只把跟管辖点有关的点连起来建出一棵虚树. 然后每次就在上面跑带边权…
传送门 dp好题. 我认为原题的描述已经很清楚了: 你有一个大小为n的背包,你有n种物品,第i种物品的大小为i,且有i个,求装满这个背包的方案数有多少. 两种方案不同当且仅当存在至少一个数i满足第i种物品使用的数量不同. 然而我只会O(n2)O(n^2)O(n2)的做法. 然后通过搜题解学会了O(n∗sqrt(n))O(n*sqrt(n))O(n∗sqrt(n))的做法. 简单讲讲. 首先我们需要分布考虑. 对于大于sqrt(n)sqrt(n)sqrt(n)的物品是选不完的,相当于没有数量限制.…
传送门 概率dp简单题. 设f[i][j]表示前i轮j获胜的概率. 如果j,k能够刚好在第i轮相遇,找规律可以发现j,k满足: (j−1)>>(i−1)" role="presentation" style="position: relative;">(j−1)>>(i−1)(j−1)>>(i−1)^1==(k−1)>>(i−1)" role="presentation"…
描述 给定一颗树(边权为1),选取一个节点子集,使得该集合中任意两个节点之间的距离都大于K.求这个集合节点最多是多少 输入 第一行是两个整数N,K 接下来是N-1行,每行2个整数x,y,表示x与y有一条边 输出 1个整数表示最多的节点数 样例输入 3 1 1 2 1 3 样例输出 2 提示 测试点 N的上限 K 特征 1 15 1 2 1000 1 链 3 1000 1 4 100000 1 链 5 100000 1 6 15 2 7 1000 2 链 8 1000 2 9 100000 2 链…
传送门 如果有n==m的条件就是卡特兰数. 但现在n不一定等于m. 我们可以考虑用求卡特兰数一样的方法来求答案. 我们知道有一种求卡特兰数的方法是转到二维平面求答案. 这道题就可以这样做. 我们将这个序列映射到二维平面上. 相当于从(0,0)(0,0)(0,0)出发,每次只能向右上方或者向右下方走对应着选1/0,最后应该停在(n+m,n−m)(n+m,n-m)(n+m,n−m). 但这样会出现非法状态. 如何排除? 我们发现如果出现非法状态一定会穿过直线y=−1y=-1y=−1,这样我们把图像关…
传送门 毒瘤细节题. 首先考虑不合法的情况. 先把相同的值配对,这样就构成了一些区间. 那么如果这些区间有相交的话,就不合法了. 如何判断?DZYO安利了一波st表,我觉得很不错. 接着考虑两个相同的值,它们中间一定只有奇数个数. 然后剩下不合法的情况可以在接下来处理时判断. 接下来还原序列的问题是可以拆分成子问题的. 考虑这两个相同的值夹住的区间. 显然这个区间里是没有值相同的. 对于区间里两个相邻且不全为0的数. 如果是形如0xy0xy0xy的话,我们把0改成y可以变成一个可行解yxyyxy…
传送门 矩阵快速幂板题,写一道来练练手. 这一次在poj做题总算没忘了改万能库. 代码: #include<iostream> #include<cstdio> #define mod 10000 #define A a[0][0] #define B a[0][1] #define C a[1][0] #define D a[1][1] using namespace std; int n; struct Matrix{int a[2][2];Matrix(){A=0,B=C=D…