插头DP总结
从跳楼到蒙B。。。插头DP,电源插头DP,工业插头DP,插座DP。。。额我们先将一些技能的,比如说hash表,这年头连hash表都不会打,简直就是yasi。hash使用一个表头加链表的结构实现数组的使用。比如说要统计值域到1e9的一列数出现次数,显然我们就把一列数压一下,比如模一个质数同余的放在一起,然后把第一个挂在表头,其它的用前向星或者链表连一下,存一下信息,一般情况还是很快的。查询就是从表头一个一个比。大概是这样,重载中括号,查询+插入,使用和数组相同,学长的代码就是帅的一批
struct hashmap { long long val[mod]; int fr[mod],tt; node s[mod]; void clear() { memset(val,0,sizeof(val));memset(s,0,sizeof(s)); tt=0;memset(fr,0,sizeof(fr)); } long long &operator [](const int st) { int i; for(i=fr[st%mod];i&&s[i].st!=st;i=s[i].pr); if(!i) { s[++tt].st=st;s[tt].pr=fr[st%mod]; fr[st%mod]=tt; i=tt; } return val[i]; } }f[2];
当然这是一篇总结,并不是用来学习的,这里粘一个学长的学习博客。
首先满怀信心打开专题。。。T1,水题啊,等等一个回路,等等障碍???好吧是我水了。在码完分类之后,差不多过样例就交了,T60然后各种卡常换质数,最后还是Lrefrain告诉我不是考虑这一个合不合法而是考虑下一个能不能转移,????令人摸不到头脑,为啥,先不管,稍作改动就A了,听说不考虑下一个的回多出很多错状态,然后hash表就死了。。。然后letongWA90来找我,我看她跟我一样只考虑当前,然后稍加改动又A了。。。。WTF,好吧看来我对插头DP的理解如同狗屎一般。。。。我就点开了上边学长博客看到了,一句话叫
然后一直疯狂理解,读了不下十几遍,最终发现了我的错误之处,
我粘了两份丑陋的代码,上边是死掉的,我们相当与没有考虑当前是否合法,首先我们要明白状态定义是什么,这个题是省掉一维,最原始的状态应该是,处理完i行j列轮廓线上插头状态为s的方案数,那么我们可以发现这个状态是从我没处理这个块,到了我处理完这个块进行转移的,于是就以为插头状态和这一样,但是。。。。。只能说插头和方案数不是同步的,也就是说当我这个块插头确定时,我方案数还没算出来,我现在要算,但是插头、即联通性已经确定,我们之所以叫它插头估计就是因为它穿越了轮廓线。我们重新yy一下转移过程,我先拿到一个块,它的联通性确定,如果它只有一个插头,但是下边和右边都是不能走的砖,那么它的方案数应该是0,如果他能向下走或向右走一种,那么它的方案数就加一遍,如果都能走,那就加两遍,当然插头状态要改变一下。即:一个块能不能承接之前的方案,不是看他有没有插头,而是看它能不能连出去,或者说他有没有前途,像只有一个插头并且下右都是砖的,在我之前的代码中会被计算,然而它理论上应该是0。好吧以上都是个人见解,有错请在评论区留言。。。。