上一页 1 ··· 25 26 27 28 29 30 31 32 33 ··· 85 下一页
  2012年4月26日
摘要: FZU_1692 首先感觉输入数据里面的L和R应该反过来读取即先读入R再读入L,要不然样例算不出来,不知道是不是我理解错题意了。 矩阵不难构造,但这个题让进一步注意到了矩阵运算中的常熟优化: ①由于递推关系的矩阵各行是循环同构的,而两个这样的循环同构的矩阵的乘积依然是循环同构的,所以在用二分矩阵的方法计算的时候,可以先用O(N^2)的时间计算出第一行,再用O(N^2)的时间平移出下面各行的结果,这样每次做乘法的复杂度就由O(N^3)减少到了O(N^2)。 ②矩阵乘法的multiply的函数最好使用引用传递传参,如果直接传参的话每次相当于把矩阵复制一遍,这样效率就比较低了。#include< 阅读全文
posted @ 2012-04-26 10:44 Staginner 阅读(239) 评论(0) 推荐(0) 编辑
  2012年4月25日
摘要: HDU_2276 这个题让我联想到了最近刚学的数电的时序逻辑电路…… 当前这个灯的状态取决于上一时刻左边的灯的状态以及自己的状态,枚举情况之后就会得到00->?0,01->?1,10->?1,11->?0,如果我们设f[i][j]表示i时刻第j个灯的状态,1表示亮,那么根据上面4种情况就可以得到f[i][j]=(f[i-1][j-1]+f[i-1][j])%2,这样我们根据递推公式构造矩阵后用二分矩阵的方法就可以快速求出最终的各个灯的状态了。#include<stdio.h>#include<string.h>#define MAXD 110in 阅读全文
posted @ 2012-04-25 23:37 Staginner 阅读(153) 评论(0) 推荐(0) 编辑
摘要: HDU_2294 我们可以用f[i][j]表示珠子长度为i的时候一共有j种颜色的方案数,那么就有f[i][j]=j*f[i-1][j]+(K-j+1)*f[i-1][j-1],最后的结果就是f[1][K]+f[2][K]+…+f[N][K]。 但由于N比较大,我们不能直接计算,但有了递推方程以后发现是可以构造出K*K的矩阵后用二分矩阵的方法去快速计算f[i][K]的,但对于f[1][K]+f[2][K]+…+f[N][K]这个表达式该如何求解呢? 如果我们将构造出的递推关系的矩阵看成矩阵A,然后就可以用POJ_3233的方法先求A+A^2+A^3+…+A^K,然后就比较容易得到结果了。 或.. 阅读全文
posted @ 2012-04-25 22:04 Staginner 阅读(228) 评论(0) 推荐(0) 编辑
  2012年4月24日
摘要: HDU_2256 这个题目用快速幂+fmod是AC不了的,应该是浮点数精度的原因,推导的过程都体现在图上了,剩下的工作就是二分矩阵求解了。 此外,在计算完x[n]和y[n]之后不能直接用(x[n]+(int)(y[n]*sqrt(6.0)))%1024来得到最后的结果的,先取整再模和先模再取整的结果是不一样的这一点举个例子就比较容易看出来了。 比如(2000*1.372)%1000,这样先乘再取模得到的结果就是744,如果先把2000模1000,显然最后结果就是0了。 #include<stdio.h>#include<string.h>#include<math 阅读全文
posted @ 2012-04-24 17:09 Staginner 阅读(368) 评论(0) 推荐(0) 编辑
摘要: HDU_2604 由于L比较大,我们可以设法得到E-queues的递推式后用二分矩阵的方法简化运算。 接下来我们要考虑递推到n时新生成的E-queues,显然只考虑n-1时E-queues的最后两位的情况即可。不妨设a[n]表示结尾为fm的数量,b[n]为结尾为ff的数量,c[n]为结尾为mf的数量,d[n]为结尾为mm的数量,那么就有a[n]=b[n-1]+c[n-1],b[n]=c[n-1],c[n]=d[n-1],d[n]=a[n-1]+d[n-1],写成矩阵形式就是下图。进而就可以得到矩阵形式的通项公式了,然后二分矩阵就可以了,最后的结果就是a[n]+b[n]+c[n]+d[n],.. 阅读全文
posted @ 2012-04-24 11:33 Staginner 阅读(278) 评论(0) 推荐(0) 编辑
  2012年4月23日
摘要: POJ_3233 如果我们把S(k)写成递推式的话,就是S(k)=A*S(k-1)+A,这样就可以将S(k)表示成矩阵的形式,从而应用二分矩阵来快速求解S(k)了。 此外,在计算中间结果的时候尽量少取模,因为取模运算的效率确实很低。 #include<stdio.h>#include<string.h>#define MAXD 70int N, K, M, cnt;struct Matrix{ int a[MAXD][MAXD]; void init() { memset(a, 0, sizeof(a)); }}mat[510];int multiply(... 阅读全文
posted @ 2012-04-23 14:20 Staginner 阅读(254) 评论(0) 推荐(0) 编辑
  2012年4月22日
摘要: SGU_224 这个题目由于状态总数很大,但最后的结果又比较小,所以相比用状态压缩dp就很难搞定了,还是直接用dfs比较好。 由于皇后每行只能放一个,我们不妨逐行递推。受Matrix67的启发,其实不必开数组去记录哪一条斜线上已经放了皇后,我们可以直接用一个变量比如ls来表示前面放置的皇后的左下斜线覆盖了当前这行的哪些位置(ls的某个二进制位为1表示这个位置被覆盖了,为0表示没有被覆盖),这样如果这行不放皇后的话,下一行的ls就是ls<<1,如果放置皇后的话也是类似的。这样用三个变量就可以描述前面放置的皇后的列、左斜线、右斜线覆盖了这行的哪些位置,进而能够很方便的知道这行上还有哪些 阅读全文
posted @ 2012-04-22 22:48 Staginner 阅读(383) 评论(0) 推荐(0) 编辑
  2012年4月21日
摘要: SGU_225由于在dp的时候需要记录上面两行放置马的状态,以及马的数量,这样状态数就相当多了,直接交写完的dp就TLE了。暂时没有想到好的办法,所以拿自己dp的程序打了个表交上去AC了。// 注意:这个程序是用来打表的,并不是可以直接提交的程序。#include<stdio.h>#include<string.h>#define MAXD 20#define HASH 100007#define SIZE 2000010int N, K, ucode[MAXD], dcode[MAXD], ncode[MAXD], num;struct Hashmap{ int he 阅读全文
posted @ 2012-04-21 20:29 Staginner 阅读(350) 评论(0) 推荐(0) 编辑
摘要: SGU_223最近刚学了插头dp,所以就用插头dp那个模式写了这个题。如果逐格递推的话实际上只有这个格子左边、左上方、上方、右上方的格子会影响当前这个格子是否能够放king,所以在记录状态的时候可以把轮廓线上有无king作为一个状态,同时单记录轮廓线上的king没办法知道最后有多少个king,所以再在状态中留出7个二进制位记录一下已经放了几个king即可。#include<stdio.h>#include<string.h>#define HASH 30007#define SIZE 1000010#define MAXD 15int N, K, code[MAXD], 阅读全文
posted @ 2012-04-21 17:35 Staginner 阅读(292) 评论(0) 推荐(0) 编辑
摘要: SGU_222最近刚学了插头dp,所以就用插头dp那个模式写了这个题。可以用f[i][j][st]表示推到第i行第j列时,行和列上rook的状态为st时方案的种数。#include<stdio.h>#include<string.h>#define HASH 30007#define SIZE 1000010int N, K, rst, cst;struct Hashmap{ int head[HASH], next[SIZE], state[SIZE], size; long long f[SIZE]; void init() { memset(head... 阅读全文
posted @ 2012-04-21 16:36 Staginner 阅读(316) 评论(0) 推荐(0) 编辑
上一页 1 ··· 25 26 27 28 29 30 31 32 33 ··· 85 下一页