摘要:
HDU_4348 用可持久化线段树就可以实现O(1)的back操作,同时如果想效率比较高的话,推荐用单点修改+区间查询的模式替代下传标记的区间修改+区间查询的模式来完成对区间和的查询。 至于如何不下传标记就能完成区间修改和区间求和可以参考ZKW的《统计的力量--线段树》的第59~60页。#include<stdio.h>#include<string.h>#define MAXD 100010typedef long long LL;int N, M, node, T[MAXD], np[MAXD];LL A[MAXD];struct SegTree{ int ls, 阅读全文
摘要:
ZOJ_2112 之前用线段树套平衡树写这个题目,现在发现那样写弱爆了……再次写这个题就是为了学习“主席树”,其实也就是可持久化数据结构的思想,思想来自于这篇博客:http://seter.is-programmer.com/posts/31907.html,写法来自于那个博主的代码:http://ideone.com/2Jp5W。 由于刚刚接触“主席树”就不再额外发表言论了。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXM 10010#define MAXD 60010#d 阅读全文
摘要:
HDU_3647 一开始不知道暴力搜就能过,后来看别人的题解说直接暴搜加回溯,于是自己也就直接写了个回溯,基本都是写好一段之后直接不停地cpoy、改参数,所以导致代码比较搓……#include<stdio.h>#include<string.h>int N, M;char a[15];void init(){ for(int i = 0; i < 10; i ++) scanf("%s", a + i);}int dfs(int cur, int *H){ if(cur == 10) return 1; int i, h[40]; memcpy 阅读全文
摘要:
HDU_3475 由于每个灯的状态有可能控制周围八个灯的状态,这样在dp的时候就要记录至少两行灯的状态的信息,通过枚举对当前行的操作使上一行的灯全部熄灭来完成状态的转移。 如果裸着做的话必然超时,因此要对dp进行优化。 首先,虽然至多有2^10*2^10种不同的状态,但这些状态绝大多数是不合法的,因此我们在dp的过程中可以用一个哈希表记录下来当前拓展出的所有合法的状态,每次只取哈希表中的状态进行决策、转移,这样无论是在空间上还是时间上都优化了很多。 尽管用哈希表解决了空间上的问题,也优化掉了很多无用的状态,但还是会超时,因为对于每一个状态,如果我们都枚举当前行的所有操作的话,那么每次都相当于乘 阅读全文
摘要:
HDU_2269 唉,一开是理解错了这句话,WA到死……“Then m line follows ,each line contains several things ,which means if these things stay together without the farmer,some thing will been eaten.”这句话的意思是每一行中的若干个东西在农夫不在的时候,不能同时待在一起,而不是说这些东西中任意两者都不能待在一起。 可以用各个二进制位的0、1分别表示每个物品在哪个岸上,再用一个二进制位表示一下农夫现在在哪里,这样总状态并不多,所以直接广搜就行了。#in 阅读全文
摘要:
HDU_2442 如果用递推形式的dp的话,需要记录两行轮廓线的状态,然后根据状态逐格dp,逐一讨论每个图形是否能够嵌入到当前状态中。 由于写搓了,直接交的时候TLE了,所以就干脆先将所有状态预处理出来了,然后每次O(1)输出正确结果。#include<stdio.h>#include<string.h>#include<algorithm>#define MAXN 110#define MAXM 6#define ST 4096int N, M, D, f[MAXN][MAXM][ST], dp[MAXN][MAXM];void prepare(int N 阅读全文
摘要:
HDU_1400 借用了一下插头dp中轮廓线的思想,用1表示轮廓线上对应位置是空的,0表示对应位置已经放上了东西,然后逐格进行dp。 如果递推到当前格子时,上方格子是1,那么这个格子和上一个格子就必须一起放一块竖着的骨牌,否则接下来上面那个格子就不会再填上骨牌了。 如果递推到当前格子时,上方格子是0,这时看左边的格子,如果是0的话,那么当前这个格子就只能空着了,如果是1的话,那么当前这个格子可以空着,也可以和左边的格子一起放一块横着的骨牌。#include<stdio.h>#include<string.h>#include<algorithm>#defin 阅读全文
摘要:
HDU_3001 相比于普通的TSP问题,这个题加了“每个点之多经过两次”的限制,因此改用三进制表示每个点的状态就可以了。#include<stdio.h>#include<string.h>#include<algorithm>#define INF 0x3f3f3f3f#define MAXD 15#define ST 59049int N, M, D, g[MAXD][MAXD], f[ST][MAXD], ANS;int bit[] = {1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049};voi 阅读全文
摘要:
HDU_3559 如果定义终态为不能再继续传递Frost Chain的状态,那么终态的概率和应该是1。每个人死亡的概率就是他的血量为0的各个终态的概率和,于是dp出各个终态出现的概率即可。#include<stdio.h>#include<string.h>#define MAXD 7776double f[MAXD][5], a[MAXD];int vis[MAXD][5];int N, D, limit[5], code[5], q[5];const int M = 7776;struct Point{ int x, y;}p[5];int sqr(int x){ 阅读全文
摘要:
HDU_3620 设f[i][x][y]表示第i个动作结束之后位置在(x,y)的最大步数,那么f[i][x][y]=std::max{f[i-1][x'][y']+distance((x,y),(x',y'))},然后根据第i个动作的行走方向来遍历数组并进行dp就可以了。但是由于每个动作可以向前行走的最大步数为200,如果再加一维循环表示这个动作走了多少步的话就会超时,不过可以用单调队列优化掉这一维,使得每次的决策都是O(1)的。 此外,每次移动的步数可以是0,也就是不移动。#include<stdio.h>#include<string.h& 阅读全文