JZOJ.5230【NOIP2017模拟8.5】队伍统计
n<=20,显然要状压DP,将排队的状态压成一个数来表示
对于一个队伍状态S,令F[S][k]表示S状态违反了k条矛盾的合法方案数,则有
F[S|2i-1][k+num(S&power[i])]=F[S|2i-1][k+num(S&power[i])]+F[S][k]
其中i表示某个不在队伍的人,num(i)表示i在二进制下1的个数,power[i]表示必须排在i后面的人的情况。
(实际操作中发现power[i]储存排在i后面的人的情况的时候运行速度远不及power[i]储存排在i前面的情况)

1 #include<cstdio> 2 using namespace std; 3 const int qaq=1000000007; 4 int f[1<<20][21],power[21],n,m,t; 5 int main(){ 6 freopen("count.in","r",stdin); 7 freopen("count.out","w",stdout); 8 scanf("%d%d%d",&n,&m,&t); 9 int u,v; 10 for (int i=1;i<=m;i++){ 11 scanf("%d%d",&u,&v); 12 power[u]|=1<<(v-1); //power[v]|=1<<(u-1); 13 } 14 f[0][0]=1; 15 for (int i=0;i<(1<<n);i++) 16 for (int j=0;j<=t;j++) 17 if (f[i][j]) 18 for (int k=1;k<=n;k++) 19 if ((i&(1<<(k-1)))==0){ 20 int qwq=power[k]&i; //int qwq=power[k]^(power[k]&i); 21 int sum=0; 22 while (qwq){ 23 sum++; 24 qwq&=(qwq-1); 25 } 26 if (j+sum<=t){ 27 f[i|(1<<(k-1))][j+sum]+=f[i][j]; 28 if (f[i|(1<<(k-1))][j+sum]>=qaq) 29 f[i|(1<<(k-1))][j+sum]%=qaq; 30 } 31 } 32 int ans=0; 33 for (int i=0;i<=t;i++) 34 ans=(ans+f[(1<<n)-1][i])%qaq; 35 printf("%d\n",ans); 36 return 0; 37 }
注意运算优先级,注意运算优先级,注意运算优先级!!!
本文作者:~Lanly~
本文链接:https://www.cnblogs.com/Lanly/p/7291379.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现