[学习笔记]状压dp
状压 \(dp\)
1、[SDOI2009]Bill的挑战
\(f[i][j]\) 表示匹配到字符串的第 \(i\) 位状态为 \(j\) 的方案数
那么方程就很明显了,每次枚举第 \(i\) 位的字母 \(alpha\) 然后 \(O(n)\) 判断就好了
时间复杂度 \(O(26Tlen2^nn)\)
\(Code\ Below:\)
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int p=1e6+3;
int n,k,len,H[20],lg[1<<15],f[51][1<<15];
char s[16][51];inline int read(){register int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return (f==1)?x:-x;
}int main()
{register int T=read(),i,j,k,t,now,l,ans;H[0]=1;for(i=1;i<32768;i++) lg[i]=lg[i>>1]+(i&1);for(i=1;i<20;i++) H[i]=H[i-1]<<1;while(T--){n=read(),k=read();for(i=1;i<=n;i++) scanf("%s",s[i]+1);if(n<k){printf("0\n");continue;}len=strlen(s[1]+1);memset(f,0,sizeof(f));f[0][H[n]-1]=1;for(i=1;i<=len;i++)for(j=0;j<H[n];j++)if(f[i-1][j]&&lg[j]>=k){for(t=0;t<26;t++){now=0;for(l=1;l<=n;l++)if((j&H[l-1])&&(s[l][i]=='?'||s[l][i]==t+'a')) now|=H[l-1];f[i][now]=(f[i][now]+f[i-1][j])%p;}}ans=0;for(int i=0;i<H[n];i++) if(lg[i]==k) ans=(ans+f[len][i])%p;printf("%d\n",ans);}return 0;
}
2、[SDOI2009]学校食堂
状压 \(dp\) 好题!
首先 \(a\ or\ b - a\ and\ b = a\ xor\ b\)
\(f[i][j][k]\) 表示到第 \(i\) 个人状态为 \(j\) 最后一个打饭的编号为 \(i+k\) 的方案数
那么就可以转移了
if(j&1) chkmin(f[i+1][j>>1][k+7],f[i][j][k+8]);
else {int lim=inf;for(int l=0;l<=7;l++){if(!(j&(1<<l))){if(i+l>lim) break;chkmin(lim,i+l+B[i+l]);chkmin(f[i][j|(1<<l)][l+8],f[i][j][k+8]+(i+k?T[i+k]^T[i+l]:0));}}
}
\(Code\ Below:\)
#include <bits/stdc++.h>
using namespace std;
const int maxn=1000+10;
const int inf=0x3f3f3f3f;
int n,T[maxn],B[maxn],f[maxn][1<<8][16];inline int read(){register int x=0,f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}return (f==1)?x:-x;
}inline void chkmin(int &a,int b){a=a<b?a:b;}int main()
{int Case=read();while(Case--){n=read();for(int i=1;i<=n;i++)T[i]=read(),B[i]=read();memset(f,inf,sizeof(f));f[1][0][7]=0;for(int i=1;i<=n;i++)for(int j=0;j<256;j++)for(int k=-8;k<=7;k++){if(j&1) chkmin(f[i+1][j>>1][k+7],f[i][j][k+8]);else {int lim=inf;for(int l=0;l<=7;l++){if(!(j&(1<<l))){if(i+l>lim) break;chkmin(lim,i+l+B[i+l]);chkmin(f[i][j|(1<<l)][l+8],f[i][j][k+8]+(i+k?T[i+k]^T[i+l]:0));}}} }int ans=inf;for(int i=0;i<=8;i++)chkmin(ans,f[n+1][0][i]);printf("%d\n",ans);}return 0;
}
3、[CQOI2018]解锁屏幕
\(check\) 好麻烦啊
\(Code\ Below\):
#include <bits/stdc++.h>
#define res register int
using namespace std;
const int p=1e8+7;
int n,x[20],y[20],H[20],a[20][20],dp[1<<20][20],vis[1<<20][20],ans;
int head=1,tail=0,q[(1<<20)*20*2+10];int check(int k,int f,int j){if(k==f||k==j) return 0;if(x[f]==x[k]||x[f]==x[j]){if(x[f]==x[k]&&x[f]==x[j]&&(y[f]<=y[k])==(y[k]<=y[j])) return 1;if(y[f]==y[k]&&y[f]==y[j]&&(x[f]<=x[k])==(x[k]<=x[j])) return 1;return 0;}if((x[f]<=x[k])==(x[k]<=x[j])&&(y[f]<=y[k])==(y[k]<=y[j])&&(y[f]-y[k])*(x[f]-x[j])==(y[f]-y[j])*(x[f]-x[k])) return 1;return 0;
}void add(res &x,const res &y){x=x+y<p?x+y:x+y-p;
}int main()
{scanf("%d",&n);res i,j,f,st;H[0]=1;for(i=1;i<=20;i++) H[i]=H[i-1]<<1;for(i=0;i<n;i++) scanf("%d%d",&x[i],&y[i]);for(f=0;f<n;f++)for(j=0;j<n;j++){if(f==j) continue;for(i=0;i<n;i++) if(check(i,f,j)) a[f][j]+=1<<i;}for(i=0;i<n;i++) dp[H[i]][i]=vis[H[i]][i]=1,q[++tail]=H[i],q[++tail]=i;while(head<=tail){i=q[head++];f=q[head++];st=__builtin_popcount(i);if(st>=4) add(ans,dp[i][f]);for(j=0;j<n;j++){if(i&H[j]||!((a[f][j]&i)==a[f][j])) continue;add(dp[i|H[j]][j],dp[i][f]);if(!vis[i|H[j]][j]) vis[i|H[j]][j]=1,q[++tail]=i|H[j],q[++tail]=j;}}printf("%d\n",ans);return 0;
}
转载于:https://www.cnblogs.com/owencodeisking/p/9978769.html
[学习笔记]状压dp相关推荐
- 【算法竞赛学习笔记】状压DP
title : 状压DP date : 2022-3-5 tags : ACM,图论,动态规划 author : Linno 状压DP 状态压缩,是利用二进制数的性质对问题进行优化的一种算法,经常与搜 ...
- 状压DP学习总结 (详解,适合没状压dp基础的人学习,还在更新中,,,,)
本次博客,主要是给学弟学妹们讲解一下状压dp,不适合有基础的同学观看,可能会浪费时间,因为偏基础 先来最简单的一个吧 http://acm.hdu.edu.cn/showproblem.php?p ...
- CH0103最短Hamilton路径 poj2288 Islands and Brigdes【状压DP】
虐狗宝典学习笔记: 取出整数\(n\)在二进制表示下的第\(k\)位 \((n >> ...
- Codeforces Gym 100676G Training Camp 状压dp
http://codeforces.com/gym/100676 题目大意是告诉你要修n门课,每门课有一个权值w[i], 在第k天修该课程讲获得k*w[i]的学习点数,给出了课程与先修课程的关系,要修 ...
- POJ 1321 棋盘问题(DFS 状压DP)
用DFS写当然很简单了,8!的复杂度,16MS搞定. 在Discuss里看到有同学用状态压缩DP来写,就学习了一下,果然很精妙呀. 状态转移分两种,当前行不加棋子,和加棋子.dp[i][j]中,i代表 ...
- 状压DP UVA 10817 Headmaster's Headache
题目传送门 1 /* 2 题意:学校有在任的老师和应聘的老师,选择一些应聘老师,使得每门科目至少两个老师教,问最少花费多少 3 状压DP:一看到数据那么小,肯定是状压了.这个状态不好想,dp[s1][ ...
- 【动态规划】状压dp:蓝桥2020补给(旅行商问题)
问题可以转换为: 从0出发途径每个城市至少一次返回0求最短路径: 解法:动态规划(状压dp)+Floyd预处理最短路径(从一个城市到另一个城市走最短路即可,不需考虑途径什么城市) [动态规划笔记]状压 ...
- ACM-ICPC 2018 南京赛区网络预赛 E AC Challenge(状压dp)
Dlsj is competing in a contest with n (0 < n \le 20)n(0<n≤20) problems. And he knows the answe ...
- 涂抹果酱(三进制状压dp)
涂抹果酱(状压dp) 题目描述 输入描述: 输出描述: 示例 输入 输出 说明 备注: 题目思路: 代码 欢迎关注微信公众号:Java后台开发 题目描述 Tyvj两周年庆典要到了,Sam想为Tyvj做 ...
最新文章
- 备份与恢复oracle,oracle 备份与恢复
- 【MySQL】基础知识
- HighLight selected features
- 西雅图SQL PASS之旅
- Xcode 中的IOS工程模板
- SpringBoot集成Thymeleaf
- 适用于MongoDB和Mongometer的SpiderMonkey至V8
- Maven的资源坐标
- Swift 反射 API 及用法
- qregularexpression和qregexp的区别
- python语句和语法结构
- paip.提高用户体验----增添开始菜单类似360小助手按钮总结
- 【Oozie】CDH集群的oozie手把手快速入门
- JAVA开源协同过滤算法,推荐算法:协同过滤算法的介绍
- Winform实现确认取消框
- 16进制颜色代码#FF000000 (css颜色值)
- 句子成分分析(C++)
- python音频 降噪_python - 使用pyaudio对音频播放进行降噪 - 堆栈内存溢出
- windows7交互式服务检测如何禁用?
- 神经系统位置图高清,中枢神经系统位置图
热门文章
- STM32通用定时器输出PWM控制舵机 —— 重装载值、比较值、当前值
- 数据结构——链式队列解析(C语言版)
- 数学教师计算机能力提升,深度融合信息技术,提升数学课堂魅力
- mysql语录错误1300_mysql 语句常见错误 汇总(持续更新中)
- 网络技巧:WiFi越用越慢,到底是什么原因,看完你就明白了!
- 还在用 Notepad++吗? 盘点五款更好用的文本编辑器
- 软件测试人员:如何优秀的提Bug?
- 前端必备知识点—SVG
- linux看缺省的编译器,修改Linux系统默认编辑器
- 将mysql服务移除_怎么将mysql服务移除?