标签:插头 bin val 笔记 ins b1 b2 zt DP
(供复习使用)
插头,其实就是一条线的端点
特别的,左边对应左插头,右边对应右插头
插头DP其实就是一类状压
\(1\) 代表该位置为左插头
\(2\) 代表为右插头
\(0\) 表示无插头
图就不画了,很多题解都画得很好,
这里只解释一下转移
(此时枚举的状态为 zt 方案数为 val b1 为台阶的侧边 b2 为台阶的上端)
if(!mp[i][j]) { if(!b1&&!b2) { ins(zt,val); } }
如果该点不能放点,左上为零才合法
if(!b1&&!b2) { if(mp[i+1][j]&&mp[i][j+1]) { ins(zt+bin[j-1]+2*bin[j],val); } }
如果左上为零,那只有联通右下才合法
f(!b1&&b2) {
if(mp[i][j+1]) ins(zt,val);
if(mp[i+1][j]) ins(zt+b2*bin[j-1]-b2*bin[j],val);
}
if(b1&&!b2) {
if(mp[i][j+1]) ins(zt+b1*bin[j]-b1*bin[j-1],val);
if(mp[i+1][j]) ins(zt,val);
}
如果只有左零或上零,考虑另一端端的连接方向即可
if(b1==1&&b2==1) {
int kl=1;
for(re int t=j+1;t<=m;t++) {
if((zt>>(t*2))%4==1) kl++;
if((zt>>(t*2))%4==2) kl--;
if(!kl) { ins(zt-bin[j]-bin[j-1]-bin[t],val); break; }
}
}
if(b1==2&&b2==2) {
int kl=1;
for(re int t=j-2;t>=0;t--) {
if((zt>>(t*2))%4==1) kl--;
if((zt>>(t*2))%4==2) kl++;
if(!kl) { ins(zt-2*bin[j]-2*bin[j-1]+bin[t],val); break; }
}
}
如果左上相等,连接变值即可
if(b1==2&&b2==1) ins(zt-2*bin[j-1]-bin[j],val);
if(i==e1&&j==e2) ans+=val;
两种连值,其中 \(e1\) 和 \(e2\) 为最后枚举到的可放点
标签:插头,bin,val,笔记,ins,b1,b2,zt,DP
来源: https://www.cnblogs.com/zjxlm/p/15394925.html
本站声明:
1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。