BZOJ1187 [HNOI2007]神奇游乐园
<div class="post_brief"><p> 我的第二道插头DP。差不多纠结了一天。</p> 这道题网上的题解都讲的好简略啊。最后还得自己yy。没有用括号序列法让我觉得自己比较厉害。 考虑轮廓线上的m个格子,有3种情况:没有插头,有且只能往一边走,有且要往两边走。对于第二种,要用最多3个不同的值来记录连通性。还要有两个不同的值来表示第一种情况和第三种情况。我比较懒,所以直接用一个八进制数去表示,然后每次二分找编号。 考虑转移,分一堆情况进行讨论。默认从左上朝右下走。 首先是要走当前格子的情况。 如果左边和上面都有插头,那么看它们是否连通。如果不连通则把它们连通,如果已经连通,看是否还有其它插头。没有就更新答案,否则忽略。 如果只有左边有插头,再分类。如果它是第二种,那么这个格子可以新建一个第三种插头,或者把左边格子的插头接过来。如果它是第三种那么它必需把左边格子接过来。 如果只有上面有插头,那么必需把上面的插头接上来。 如果左边和上面都没有插头,那么可以新建一个第三种插头。 然后如果不走这个格子的话,要求上面没有插头,且左边不是第三种插头。 按mhy的话说,插头dp就是写起来很麻烦。的确。不过写出来也还是挺高兴的。 然后代码丑到不能看了。 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 109; const int maxm = 9; const int maxst = 50009; const int inf = 0x3f3f3f3f; #define pow8(x) (1<<(x)<<(x)<<(x)) #define mbit(x,y) ((x)<<(y)<<(y)<<(y)) #define gbit(x,y) (((x)>>(y)>>(y)>>(y))&7) int f[2][maxst], n, m, a[maxn][maxm], ans; int slst[maxst], tots;...