Join The Future (剪枝 + 状态压缩)
一道暴力搜索的恶心剪枝题目。
先处理好某个点确定之后其他点的也确定的是谁,还有分别为什么情况,分别用vis,sta来记录。当然可以直接使用一个3进制数来表示,但是这里需要额外写一个三进制数求值的函数较为麻烦。然后写完就是搜索的问题了,搜索方向就是给点为0,1一直下去,如果没有剪枝,时间复杂度应该是O(240),显然TLE,题意给出的限制很大,我们依据它来剪枝就好了。然后就是求最小的字典序,其实只需要传进最上面那个数据就可以了,因为你已经确定了01情况,剩下的就是选择每个数的最小或者次小的数。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL; const int maxn = ;
const int mod = 1e9 + ;
const int inf = 0x3f3f3f3f;
vector<pair<int, int> >cnst[maxn];
int T,n,m,aa,bb,cc;
int l[maxn], r[maxn], trodi[maxn], vis[maxn];
LL b[maxn], odd[maxn][], cnt[maxn][], con[maxn], dans[maxn][], ans; ///求字典序最小的
void update(LL vis, LL sta){
LL pre = ;
bool better = false;
for(int i = ; i <= n; i ++){
int now;
if(vis & b[i]) now = l[i] + ((l[i] & ) != ((sta >> i & ) ^ pre));
else now = l[i];
if(better) trodi[i] = now;
else{
if(now > trodi[i]) return ;
if(now < trodi[i]) better = true, trodi[i] = now;
}
pre = pre ^ (now & );
}
} ///搜索所有01情况、剪枝、求总量
void dfs(int step, LL vis, LL sta){
if(step > n){
LL tmp = 0LL;
for(int i = ; i < ; i ++){
if((vis&b[n]) && (sta >> n & ) != i) continue;
tmp = (tmp + dans[n][i]) % mod;
}
if(tmp){
update(vis, sta);
ans = (ans + tmp) % mod;
}
return ;
}
dans[step][] = dans[step][] = ;
///(0, 1) * (0, 1) 的四种结果,求出当前节点为0,1的个数
for(int i = ; i < ; i ++){
if((vis&b[step]) && (sta >> step & ) != i) continue;
for(int j = ; j < ; j ++){
if((vis&b[step - ]) && (sta >>step - & ) != j) continue;
dans[step][i] = (dans[step][i] + dans[step - ][j] * cnt[step][i ^ j]% mod) % mod;
}
}
if(cnst[step].empty()) dfs(step + , vis, sta);
else
for(int i =; i < ; i ++) if(dans[step][i])
dfs(step + , vis | con[step], sta | odd[step][i]);
} void solve(){
///求出某个点确定了之后其他的限制情况,当某点确定之后奇偶情况其他点为奇数的点
for(int i = ; i <= n; i ++){
odd[i][] = odd[i][] = con[i] = ;
memset(vis, -, sizeof(vis));
queue<int>que;while(!que.empty())que.pop();
vis[i] = ;que.push(i);
while(!que.empty()){
int u = que.front();que.pop();
con[i] |= b[u];
odd[i][vis[u]] |= b[u];
for(auto x : cnst[u]){
int v = x.first, w = x.second;
if(~vis[v]){
if((vis[u] ^ vis[v] != w)){
printf("0\n-1\n");return ;
}
}else{
vis[v] = vis[u] ^ w;
que.push(v);
}
}
}
}
memset(trodi, inf, sizeof(trodi));
ans = 0LL; dans[][] = ;
dfs(, con[], odd[][]);
if(trodi[] == inf) printf("0\n-1\n");
else{
printf("%lld\n",ans);
for(int i = ; i <= n; i ++)
printf("%d%c", trodi[i], " \n"[i == n]);
}
} int main(){
scanf("%d",&T);
for(int i = ; i < maxn; i ++) b[i] = 1ll << i;
while(T --){
scanf("%d%d",&n,&m);
for(int i = ; i <= n; i ++){
scanf("%d%d", &l[i], &r[i]);
cnt[i][l[i]&] = (r[i] - l[i]) / + ;
cnt[i][(l[i]&)^] = r[i] - l[i] + - cnt[i][l[i]&];
}
for(int i = ; i <= n; i ++) cnst[i].clear();
for(int i = ; i < m; i ++){
scanf("%d%d%d",&aa, &bb, &cc);
cnst[aa - ].push_back(make_pair(bb, cc));
cnst[bb].push_back(make_pair(aa - , cc));
}
solve();
}
return ;
}
Join The Future (剪枝 + 状态压缩)的更多相关文章
- Sudoku (剪枝+状态压缩+预处理)
[题目描述] In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. ...
- POJ2688状态压缩(可以+DFS剪枝)
题意: 给你一个n*m的格子,然后给你一个起点,让你遍历所有的垃圾,就是终点不唯一,问你最小路径是多少? 思路: 水题,方法比较多,最省事的就是直接就一个BFS状态压缩暴搜就行 ...
- ACM/ICPC 之 BFS+状态压缩(POJ1324(ZOJ1361))
求一条蛇到(1,1)的最短路长,题目不简单,状态较多,需要考虑状态压缩,ZOJ的数据似乎比POj弱一些 POJ1324(ZOJ1361)-Holedox Moving 题意:一条已知初始状态的蛇,求其 ...
- UVALive 3956 Key Task (bfs+状态压缩)
Key Task 题目链接: http://acm.hust.edu.cn/vjudge/contest/129733#problem/D Description The Czech Technica ...
- HDOJ 1429 胜利大逃亡(续) (bfs+状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 思路分析:题目要求找出最短的逃亡路径,但是与一般的问题不同,该问题增加了门与钥匙约束条件: 考虑 ...
- 状态压缩 - LeetCode #464 Can I Win
动态规划是一种top-down求解模式,关键在于分解和求解子问题,然后根据子问题的解不断向上递推,得出最终解 因此dp涉及到保存每个计算过的子问题的解,这样当遇到同样的子问题时就不用继续向下求解而直接 ...
- uva10160(dfs+状态压缩)
题意:给出n个点,以及m条边,这些边代表着这些点相连,修一个电力站,若在某一点修一个站,那么与这个点相连的点都可以通电,问所有的点都通电的话至少要修多少个电力站........ 思路:最多给出的是35 ...
- 状态压缩---UVA6625 - Diagrams & Tableaux
比赛的时候刷出来的第一个状态DP.(期间有点没有把握是状态DP呢.) 题意:题意还是简单的.K行的方格.之后输入L1~LK 代表每一行方格数.在这些往左紧挨的方格子里填上1~N的数字. 其中右边格子的 ...
- dp状态压缩
dp状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...
随机推荐
- Orchard Core 模块化
在上一篇文章谈到如何搭好一个基础的Orchard Core项目. 今天要尝试Orchard Core的模块化. 我自己的理解:一个系统可以分成一个个模块,这一个个模块是由一个个类库去实现的. 首先,在 ...
- 洛谷P3722 影魔 [AH2017/HNOI2017] 线段树+扫描线
正解:线段树+扫描线 解题报告: 传送门! 先理解一下这道题,大概是这样儿的: 对于一个点对,如果他们的两端是这段区间的最大值和次大值,那么他们会有p1的贡献 如果他们的两端是最大值和一个非次大值,那 ...
- es分页搜索
1.es分页语法GET /_search?from=起始数&size=页面显示条数例如:GET /test_index/test_type/_search?from=0&size=3 ...
- 【Linux】阿里云服务器部署--禅道
Xshell部署环境 回到Xshell界面,连上阿里云服务器,参考上一篇[linux学习1-Xshell连接阿里云ECS服务器](https://www.cnblogs.com/yoyoketang/ ...
- apache在mac下403问题
症状:在mac下使用xampp环境,httpd.conf权限,但访问网站报403错误. 解决方案:将对应文件目录权限改为755 修改后,Thinkphp访问提示Application不可写,无法创建内 ...
- 经典的js返回(退个页面)
<a href="javascript:history.back()">返回</a> <a href="javascript:window. ...
- 万恶之源 - Python迭代器
函数名的使用以及第一类对象 函数名的运用 函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量 1.函数名的内存地址 def func(): print("呵呵" ...
- 调用run与调用start的区别
调用start的结果 package TestException; public class test1 { public static void main(String[] args) { // 3 ...
- eclipse中安装maven,配置本地仓库和镜像
1.安装maven,配置MAVEN_HOME 首先:下载免安装版解压配置MAVEN_HOME(和配置JAVA_HOME一样) 然后按照下面的配置,主要第3步,指定settings.xml文件的位置(在 ...
- Python几种数据结构内置方法的时间复杂度
参考:https://blog.csdn.net/baoli1008/article/details/48059623 注:下文中,’n’代表容器中元素的数量,’k’代表参数的值,或者参数的数量. 1 ...