[NOIP10.4模拟赛]2.y题解--折半搜索+状压计数
题目链接:
咕
闲扯:
这题暴力分似乎挺多,但是一些奇奇怪怪的细节没注意RE了,还是太菜了
分析:
首先我们考虑最naiive的状压DP ,\(f[u][v][state]\)表示u开头,v结尾是否存在一条表示为state的路径,这个好转移不讲了,但是由于d的范围时间复杂度过大,于是考虑折半搜索
我们把一条最终路径的路径分成两部分\(p=(d+1)/2\)(其实就是上取整),\(q=d-p\),显然\(p>=q\)
于是我们可以把一条路径长度看成两部分,一条从1开始,长度为p的路径,另一条以某点为开头,长度为q,终点恰好与第一条路径接上.
然后这时候我们就用\(ff[state][x]\)表示是否存在一条以x为开头,表示为state的路径,这个DP数组怎么得到呢?
我们枚举起点\(st\),再用一个数组\(f[state][x]\)表示是否存在一条st开头,x结尾,状态为state的路径,这个非常好转移我们从小到达枚举状态再根据两点之间是否连边转移
于是如果\(f[state]\)中存在一个值为1的元素,那么\(ff[state][st]=1\)
由于是折半路径,我们只需要将路径状态压为一个p位二进制数就好了
注意最后路径是从1开始,我们方便起见倒着枚举起点,最后枚举长度为p的前一半状态,和长度为q的后一半状态,如果存在一点v,\(ff[state_1][v]\)&\(f[state_2][v]==1\),那么方案数加1
同时预防前导0还需要特殊处理
还发现DP数组都是0/1序列,使用bitset减少操作时间复杂度
代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cctype>
#include <iostream>
#include <bitset>
#define ll long long
#define ri register int
using std::min;
using std::bitset;
using std::max;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=95;
const int inf=0x7fffffff;
const int N=1<<20-1;
bitset <maxn> g0[maxn],g1[maxn],f[N],ff[N];
int p,q;
inline void clear(){
for(ri i=0;i<N;i++)f[i].reset();
return ;
}
ll ans=0;
int n,m,d;
int main(){
int x,y,z;
#ifdef Luogu
freopen("y2.in","r",stdin);
freopen("y2.out","w",stdout);
#endif
read(n),read(m),read(d);
int p=(d+1)/2,q=d-p;
int o=1<<p,oo=1<<q;
for(ri i=1;i<=m;i++){
read(x),read(y),read(z);
if(z==1)g1[x][y]=g1[y][x]=1;
else g0[x][y]=g0[y][x]=1;
}
for(ri now=n;now>=1;now--){
clear();
f[1][now]=1;//避免前导0
for(ri i=1;i<o;i++){
for(ri j=1;j<=n;j++){
if(f[i][j]){//now循环中,f[state][v]表示now开头,v结尾状态为state的路径是否存在
f[i<<1]|=g0[j],f[i<<1|1]|=g1[j];
}
}
}//ff[state][u]表示从u开头,是否能走出一条状态为state的路径
for(ri i=0;i<o;i++)ff[i][now]=f[o|i].any();
}
for(ri i=0;i<o;i++){
for(ri j=0;j<oo;j++){
if((ff[i]&f[oo|j]).any())ans++;
}
//若存在点x f[state_1][x]=1并且ff[state_2][x]=1
//说明从x开头能走出一条state_2的路径
//从1开头,x结尾,又能走出一条state_1的路径,这样就能连起来成为一条合法的路径
}
printf("%lld\n",ans);
return 0;
}
[NOIP10.4模拟赛]2.y题解--折半搜索+状压计数的更多相关文章
- [NOIP10.6模拟赛]2.equation题解--DFS序+线段树
题目链接: 咕 闲扯: 终于在集训中敲出正解(虽然与正解不完全相同),开心QAQ 首先比较巧,这题是\(Ebola\)出的一场模拟赛的一道题的树上强化版,当时还口胡出了那题的题解 然而考场上只得了86 ...
- 20190716NOIP模拟赛T1 礼物(概率dp+状压)
题目描述 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物. 商店里一共有种礼物.夏川每得到一种礼物,就会获得相应喜悦值Wi(每种 礼物的喜悦值不能重复获得). 每次,店员会 ...
- [NOIP10.4模拟赛]3.z题解--思维
题目链接: 咕咕 闲扯: 哈哈这道T3考场上又敲了5个namespace,300+行,有了前车之鉴还对拍过,本以为子任务分稳了 结果只有30分哈哈,明明用极限数据对拍过不知怎么回事最后数据又是读不全, ...
- [NOIP10.3模拟赛]3.w题解--神奇树形DP
题目链接: 咕 闲扯: 这题考场上把子任务都敲满了,5个namespace,400行11k 结果爆0了哈哈,因为写了个假快读只能读入一位数,所以手测数据都过了,交上去全TLE了 把边分成三类:0. 需 ...
- [NOIP10.5模拟赛]3.c题解--思维
题目链接 这次不咕了 https://www.luogu.org/problemnew/show/AT2389 闲扯 考场20分爆搜走人 \cy 话说这几天T3都很考验思维啊 分析 我们先钦定一只鸡( ...
- [NOIP10.6模拟赛]1.merchant题解--思维+二分
题目链接: while(1)gugu(while(1)) 闲扯 考场上怕T2正解写挂其他两题没管只打了暴力,晚上发现这题思维挺妙的 同时想吐槽出题人似乎热衷卡常...我的巨大常数现在显露无疑QAQ 分 ...
- [NOIP10.5模拟赛]1.a题解--离散化+异或线段树
题目链接: 咕咕咕 https://www.luogu.org/problemnew/show/CF817F 闲扯 在Yali经历几天折磨后信心摧残,T1数据结构裸题考场上连暴力都TM没打满 分析 观 ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP2017 宝藏 题解报告【状压dp】
题目描述 参与考古挖掘的小明得到了一份藏宝图,藏宝图上标出了 n 个深埋在地下的宝藏屋, 也给出了这 n 个宝藏屋之间可供开发的 m 条道路和它们的长度. 小明决心亲自前往挖掘所有宝藏屋中的宝藏.但是 ...
随机推荐
- vue 自定义 提示框(Toast)组件
1.自定义 提示框 组件 src / components / Toast / index.js /** * 自定义 提示框( Toast )组件 */ var Toast = {}; var sho ...
- ubuntu 切换默认python版本
现在的python项目都是基于python3的了,再用ubuntu的时候默认的版本是py2的,所以想切换到py3上: 打开终端: sudo update-alternatives --install ...
- java dom4j 解析xml使用实践
参考:https://dom4j.github.io/ http://www.cnblogs.com/liuling/archive/2013/02/05/dom4jxml.html 常用api: 1 ...
- 阶段5 3.微服务项目【学成在线】_day04 页面静态化_24-页面预览-页面预览测试
通过nginx转发到预览的地址 重启nginx 添加页面预览按钮 调整下列表的列的宽度
- Java NIO 学习笔记 缓冲区补充
1.缓冲区分配 方法 以 ByteBuffer 为例 (1)使用静态方法 ByteBuffer buffer = ByteBuffer.allocate( 500 ); allocate() 方法 ...
- 安装flask_mysqldb出现报错问题解析
安装 mysqldb (pip3 install Flask-MySQLdb)报错 EnvironmentError: mysql_config not found ERROR: Command er ...
- CF1183E/H Subsequences
思路: dp好题,dp[i][j]表示到前i个字符为止并且以s[i]为结尾,共有多少个长度为j的不同的子序列. 实现: #include <bits/stdc++.h> using nam ...
- vue 结构赋值
- shell 监控
#!/bin/shsource /etc/profileserverName=$1dingDingName=$2 #获取内存情况memory=(`free | awk 'NR==2{print $2, ...
- 学习笔记:CentOS7学习之二十四:expect-正则表达式-sed-cut的使用
目录 学习笔记:CentOS7学习之二十四:expect-正则表达式-sed-cut的使用 24.1 expect实现无交互登录 24.1.1 安装和使用expect 24.2 正则表达式的使用 24 ...