收获: 尼姆博奕:看了好多博客,开始还是比较容易理解,深层面的较难看懂,尤其是尼姆博奕的变型,还有后面涉及SG打表那一块。总结一下自己的认识,简单的跳过。 先看奇异局势,(s[1],s[2],s[3]…… s[n]
),逐步进行异或运算。 若结果为0:那么先手必败;若不为0,那么先手必胜。(也就是说面对奇异局势的人必输) 若有三堆石子,石子数最多的那堆减去其余两堆石子的异或,可构造奇异局势。
阶梯博弈算法(尼姆博弈进阶):啃了两三天,头都晕了,证明过程也看的迷迷糊糊。 题目形式:一个楼梯上每层都放有一些石子(硬币也可),每回合将i台阶上石子移动到(i-1)阶上,最后无法移动的输,也就是其他阶都为空,移动第一阶得人赢。
公式:所有的奇数阶上的石子进行异或运算>0,则确定是胜方。因为对于败方来说,若移动奇数阶的石子,胜方便有可将奇数阶石子异或为0,成为奇异局势;若移动偶数阶石子,胜方可将败方移动的石子往前移动,对奇数阶石子无影响。
到这里还好,可根据阶梯博弈变化的题目真的很难,看都看不明白。会继续认真看的。 举一个阶梯博弈变化的题目。一个盒子从1到n被标记,满足: (A>B&&(A+B)%2==1&&(A+B)%3==0)
,不能移动盒子的人输。 我的思路:想到了阶梯博弈,可还是不会用,发现条件可转化为(A+B)%6==3
,然后举例了1到15数字的移动情况,不难发现最终都会移动到(1,3,4)这个盒子中。经查阅资料:发现要对所有奇数步盒子的礼品数进行异或运算,而所有满足奇数步盒子都满足*(A+B)%6==0或2或5*
,这一步简直太难想了!!
威佐夫博弈:核心公式:(1.0+sqrt(5.0))/2*(a-b)
大体是两堆石头,要么从一堆中取任意数,要么从两堆中取相同数目,先去玩的获胜。这里的奇异局势和尼姆博弈的很像,但没有尼姆博弈难,毕竟尼姆博弈是从n堆石头中取。 需要注意的点: 1.从一堆中取可能可以得到奇异局势。2.从两堆中取一样的石头也可能得到奇异局势。要根据题目要求灵活改变。
k倍动态减法:这个同样非常难,看了好久都还是很懵,也能看做是斐波那契博弈的变型,只是不再是两倍了。当k=1时,2的i次方都是必败点,将n化为用二进制,每次拿走最后的一个1,而对手不能拿走倒数第二个1,因为他拿的数量不能多于你拿的;当k=2时,斐波那契数列都是必败点;当k>=3时,开两个数组a[n],b[n]
,a[n]存的数字都是必败点,b[t]是a[1到t]所能表示的最大数,最后要使得
b[i]=b[t]+a[i] (a[t]*ka[i])
{
i++;
a[i]=b[i-1]+1;
while(a[j+1]*k>方向上就错了,虽然自己也不太会做。 我的思路:虽然自己没思路,但也想了好久。我发现,替换的情况有很多,肯定是分类讨论。也想到了将字母全变成a或b或c,全变成a去找最大子矩阵(b,c同理),到这里是对的。然后我想直接去找字母见得关系,比如最大子矩阵a,如果左边或上边是a累加1,其实行不通,这只是在记录a的次数而已。 查了题解后,题解都看了好久才懂,很多困扰的难点都有了解释。 1.为了方便记录,用数字代替字母,出现a则标记为1;然后先只考虑纵向上a出现的次数,若a上方也是a,累加1。
2.更妙的是他计算面积的方式。因为在步骤1中考虑了纵向,接下来考虑横向就好。dp[i][j]是第i行第j个字母,所表示的值便是这个子矩阵的高,以它为中心,然后向右取比它大的,向左取比它大的,得到最大宽,计算面积取最大。是之前没见过的查找方式!!!(关键是另外开两个数组)
for(int j=1;j=(a[i]-i)
,所以用数组b[n]存储(a[i]-i)的值,并进行排序。abs(a[i]-b[j])为正在处理第i位时以b[j]为基准最小花费步数,而dp[i][j]为处理到第i位时以b[j]为基准总体上最小花费步数,是需要加上 上一步同样以b[j]为基准总体上最小花费步数,和同样处理到第i位时以b[j-1]为基准最小花费进行比较取最小。 构造状态转移方程:dp[i][j]=min(dp[i][j-1],dp[i-1][j]+abs(b[j]-a[i]));
4.14训练赛: 1.我负责的那道题没有过,因为忽略了一种情况,一直卡住,所以比别人少做一道题,很自责,加油吧!!! 思路:大致都是对的。两端的树就往两边倒,中间的树减去相应距离或加上相应距离不和两端的树相交,然后累加。之所以没过:非要用ans去记录才差值想着方便一点,结果把自己搞晕了,因为ans的值需要不断更新。 2.D题我的思路是找规律,规律已经快出来了,但还需要时间。队友直接模拟,我觉得也很好。卡住我们的难点:要过菜品个数进行排序(保证剩余的的菜品先进行配对,这样才能保证最多,参考样例:2 3 2)。 3.A题我们思路是完全正确的,但是代码实现上有问题,就被搁置了,没想到别人都过了,特别亏。其实代码实现也很简单,一个数找0和8,2个数两重循环枚举遍历,三位数类似。 教训: 1.有些问题是自己想得复杂,不是题目复杂,可能和心态有关,心态要放平。 2.如果确定思路正确,就不要轻易的放弃代码实现,代码是可以慢慢调的。 3.我负责那题就是我把问题复杂化,定义了一个ans记录位置
4.15训练赛: 1.一个代码实现出现了问题,整个队浪费了将近40多分钟。忽略了一个问题,如果这个‘1’是在最后出现的,那么没有一个‘0’去累加这组1的长度。难受了!
**4.16训练赛:**主要两个差距,前半段一直是领先的,后面心态问题特别着急,导致一个简单题目没做出来:另一个是H题,没写出来,和其他组的差距,要努力追赶并超越!!! H题: 两方面原因:1.看题不仔细,看的有点快,没发现输入一栏中的条件 1> C^B=A;
2.‘^’ 的优先级小于 '> , >>处理方式:加上一条常变量const int eps=1e-6;
(放主函数外面)。不然就用double
四:C. Alternating Subsequence 我的思路: 1.首先要保证取得子段最长。将观察发现,如果第一个元素是正,那么最长的便是“+-+-+-+-
”这种形式;如果第一个元素是负,那么最长的便是“-+-+-+-+-+
”这种。 2.之后两种实现方式,第二种更巧妙一些。都是找同符号下最大的元素累加。 关键实现方式:如果找到了正号下最大的元素,那么是在负号语句中加;同理,负号最大的元素在正号语句中加。不然无法实现加和最大,卡了好久。还有最后的和并未加上最后一个找到的同符号最大值。 第二种实现形式:用乘积来判断正负号,如果和前一项同号,乘积为正,然后找最大值;之后再乘积为负的时候加上去。
五.Tetrahedron 做了那么多的dp题目,发现自己根本就不会dp!!!学的好乱,一定要花时间整理。即使本题是一个很水的dp,我都做不出来。有很多零星的想法,代码写不出来,真的会很失落。简要讲一下思路: 首先:确定dp[i][j]表示的含义,第i步时到达某点的最大方案数。 其次:找dp转移方程。因为一个点有三种方式到达,所以要再加一重for循环。
dp[i][j]+=dp[i-1][g] (g表示从除自己所处点之外某个点,表示上一步g点的最大方案数)
六.A. Three Friends 队伍因为着急没过的简单题,三个人都都有能力去解决,但一起做的时候却没做出来。 我的想法:分类讨论,三个点同一位置,输出0;两个点同一位置,第三个人若和他们距离为1,输出0,若大于1,两人和第三个人都相向运动;若三个人位置都不同,两端的人向中间移动。因为之前见到过类似题目,用到了中位数,我便一直想去用它,发现真的不需要,算被经验误导了。 绝佳方法:找到规律,若左边的数加1,右边的数减1,相减如果小于0,则输出0;否则正常计算。 如果这题的时候肯静下心好好找规律,是一道秒杀的题目,而非是困住我们的绊脚石。
七.A. Matrix Game 一道简单的思维题,初看还以为是博弈,但并不是。根据题目要求,只有不和其他“1”共享行和列,才能被标记为1,无法操作的人输。只需要记录全部为0的行和列,去一个最小值即可,若最小值为偶数,则后者赢,否则前者。
虽然每次训练赛因为各种原因都输的很不甘心,但只有不断的完善,找到队伍的问题,总结自身的原因,不断鞭策自己,不断追赶别人,也还不错。但说到底,没有人愿意输,相信一定会追上并超越,不用怕爬的慢,不为给他们看!!!