上一页 1 ··· 34 35 36 37 38 39 40 41 42 ··· 85 下一页
  2012年3月10日
摘要: POJ_1678 如果我们把差在[a,b]的范围内的两个数之间连一条边的话,就会发现实际上取数的过程就是在有向无环图上行走的过程,对于一个点来讲,如果选择了它,并把选择它的人看作先手的话,那么之后的选择形成的先手与后手的分差唯一的,于是我们就可以把选择每个节点看作一个状态并进行记忆化搜索。 于是可以用f[i]表示如果当前选第i个数,并把选择这个数的人看作先手,从这个选择开始后续形成的分差的最大值。同时,在dp的过程中我们要认为后手选择的是最优的情况,所以有f[i]=a[i]-max{f[j]},其中a[i]表示第i个数的值,j为i的后继。#include<stdio.h>#incl 阅读全文
posted @ 2012-03-10 14:34 Staginner 阅读(395) 评论(0) 推荐(0) 编辑
  2012年3月9日
摘要: POJ_2975 假设某堆石子有y个,其余的各堆石子的Nim和为x,由于x^x=0且x^k!=0(k!=x),所以只有当y>x时拿走y-x个石子才能使得整体的Nim和为0。#include<stdio.h>#include<string.h>#define MAXD 1010int N, a[MAXD];void solve(){ int i, j, k, ans = 0, cnt = 0; for(i = 0; i < N; i ++) { scanf("%d", &a[i]); ans ^= a[i]; } for(i = 0 阅读全文
posted @ 2012-03-09 23:19 Staginner 阅读(213) 评论(0) 推荐(0) 编辑
摘要: HDU_1024 可以用f[i][j]表示扫描到第j个元素时且一共选i个区间的最优解,这样可以得到f[i][j]=max{f[i][j-1],f[i-1][k]+A[j]-A[k]}(i-1<=k<j),其中A[]表示前缀和。 如果不加优化的话是O(MN^2)的算法,但实际上我们可以在递推的过程中维护x=f[i-1][k]-A[k]的最大值,那么动态转移方程就改写成了f[i][j]=max{f[i][j-1],x+A[j]},这样就是O(MN)的复杂度。 此外,为了节约空间,可以使用滚动数组。#include<stdio.h>#include<string.h&g 阅读全文
posted @ 2012-03-09 21:50 Staginner 阅读(245) 评论(0) 推荐(0) 编辑
摘要: POJ_3537 对于连成3个X的状态我们是不好表示的,因此我们不妨退一步,看看在连成3个X之前都是什么样的状态,只要避免这样的状态出现就行了。 画一下就会发现,实际上只有X_X和_XX_这样两种类型,其实想到这里就逐渐有眉目了,两个选手一定会避免走出上面的局面。因此当一个选手画了一个X之后,假设局面是12X34,其中数字代表空位,为了避免上面的情况出现,1、2、3、4这4个位置一定不能走,如果走了的话就必输了,因此我们就可以等效成画一个X之后X连同左右两边各两个格子都被拿掉了,这样就变成take and break类型的游戏了,具体的这类游戏的一些模型可以参考《Game Theory》这.. 阅读全文
posted @ 2012-03-09 20:42 Staginner 阅读(684) 评论(1) 推荐(0) 编辑
摘要: POJ_2234 实际上就是Nim游戏。#include<stdio.h>#include<string.h>int N;void solve(){ int i, j, k, ans = 0; for(i = 0; i < N; i ++) { scanf("%d", &k); ans ^= k; } printf("%s\n", ans ? "Yes" : "No");}int main(){ while(scanf("%d", &N) == 1) 阅读全文
posted @ 2012-03-09 18:08 Staginner 阅读(173) 评论(0) 推荐(0) 编辑
摘要: POJ_1704 这个是经典的staircase nim游戏,在王晓珂的《解析一类组合问题》里面有提到过。 如果我们把相邻两个棋子之间以及最左边棋子和墙壁之间的棋子的数量看做每个阶梯上硬币的数目的话,这样就等效成staircase nim游戏,推荐一个讲解得比较清晰的博客:http://blog.sina.com.cn/s/blog_7fc44ee70100t9wr.html。#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXD 1010int a[MAXD], M, N;int 阅读全文
posted @ 2012-03-09 17:55 Staginner 阅读(240) 评论(0) 推荐(0) 编辑
摘要: POJ_3710 一开始学SG函数的时候,还是单纯地认为一个公平组合游戏都很轻松的变成一个有向图上的来回移动几个棋子的游戏,但是这个题我不管怎么化归都化归不过去了。 后来纠结了一段时间之后,把《Game Theory》这篇论文看了一下,才发现这个题目实际算是一个基础的模型,就像那种如果你见过就很简单,没见过就打死也做不出的题。所以自己也突然感觉到SG函数的题目还是很有必要积累一些基础的模型的。 这个题目具体的做法在《Game Theory》上面都有说,所以还是推荐大家阅读一下这篇论文,很多中文的讲SG函数的文章都是翻译的这篇论文里面的内容。这个论文可以在杭电讲博弈的rar文件里面找到,如果你实 阅读全文
posted @ 2012-03-09 16:34 Staginner 阅读(521) 评论(4) 推荐(0) 编辑
  2012年3月8日
摘要: HDU_3547 这个题目是《组合数学》上面的一个例题。 一开始我想的是任意一种旋转操作都可以是看成以沿穿过对面的中轴线的3种旋转操作组合而成的,只和操作的数量有关,而和操作的顺序无关,但后来很快发现了反例,于是如果再顺着这个思路考虑操作的顺序话,运算就相当庞大了。 于是还是不得不只从单一方向的旋转考虑。实际上旋转按旋转轴分类是有4种的: ①原地不动。 ②绕穿过对面的中轴线旋转。 ③绕穿过对棱的中轴线旋转。 ④绕正方体对角线旋转。 这4种情况一共包含了24种旋转操作,都考虑全面之后再应用大数运算就可以了。import java.math.BigInteger;import java.... 阅读全文
posted @ 2012-03-08 23:51 Staginner 阅读(478) 评论(0) 推荐(0) 编辑
摘要: HDU_3923 这个题目可以直接应用polya定理,但最后设计到一个带除法的表达式的取模问题。看了别人的解题报告后发现,应用完polya定理之后,需要计算的表达式就变成了ans/(2*m)%MOD,而2*m和MOD是互质的,所以可以先求出2*m关于模MOD的乘法逆元x,那么就有ans/(2*m)%MOD=ans*x/(2*m*x)%MOD=ans*x%MOD。 暂时还不明白为什么这么做可以,就先当结论记下了。#include<stdio.h>#include<string.h>#define D 1000000007int N, M;long long int pow 阅读全文
posted @ 2012-03-08 16:55 Staginner 阅读(344) 评论(0) 推荐(0) 编辑
摘要: POJ_2154 首先,直接应用polya定理就可以得到ans=(N^gcd(0,N)+N^gcd(1,N)+…+N^gcd(N-1,N))/N,如果直接计算的话,即便应用快速幂,也改变不了循环计算N项和的复杂度。 于是便不得不从gcd的值入手看是否能合并一些项达到化简的目的了。尽管一共有N项,但gcd的值一定到不了N项,因为gcd是N的约数,而一个数的约数是没有那么多的。顺着这个思路想的话,我们有没有办法更快地求得N的所有约数呢?这一点是可以在O(sqrt(N))的时间内办到的。我们只要枚举sqrt(N)以内的能够整除N的整数,就可以找到N所有的约数,如果同时我们可以O(1)的时间求出指.. 阅读全文
posted @ 2012-03-08 12:51 Staginner 阅读(478) 评论(0) 推荐(1) 编辑
上一页 1 ··· 34 35 36 37 38 39 40 41 42 ··· 85 下一页