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状态压缩 动态规划本来就很抽象,状态的设定和状态的转移都不好把握,而状态压缩的动态规划解决的就是那种状态很多,不容易用一般的方法表示的动态规划问题,这个就更加的难于把握了.难点在于以下几个方面:状 ...
随机推荐
- navicat连接oracle失败
正常是成功的,失败的话,就是oci.dll的问题 在这边下载: https://www.oracle.com/technetwork/topics/winsoft-085727.html 然后找到对应 ...
- CloudStack和OpenStack该如何选择(如果准备选择OpenStack,请做好hack的准备。CloudStack的底层功能已经做的很完善了,更适合商用)
国内做云计算的目前基本会在OpenStack和CloudStack中做一个选择.CloudStack 和OpenStack选哪一个,要根据自己的业务模式和研发力量来定. 作者:来源:cloudstac ...
- StringDemo
package cn.sasa.demo2; public class StringDemo { public static void main(String[] args) { //String 底 ...
- TensorFlow安装之后导入报错:libcudnn.so.6:cannot open sharedobject file: No such file or directory
转载自:http://blog.csdn.net/silent56_th/article/details/77587792 系统环境:Ubuntu16.04 + GTX1060 目的:配置一下pyth ...
- python基于django编写api+前端后端分离
有用 https://segmentfault.com/a/1190000016049962#articleHeader2 python的前后端分离(一):django+原生js实现get请求 htt ...
- 在字符编码格式选项里UTF-8(无BOM)
BOM——Byte Order Mark,就是字节序标记 在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE“的字符,它的编码是FEFF.而FFFE在UCS中是不存在的字符 ...
- JavaScript基础学习2
/* 1.把函数作为参数.匿名函数作为参数传递到函数 */ function dogEat(food) { console.log("dog eat " + food); } fu ...
- seller vue配置路径相对路径【组件 只写简单路径】
在[webpack.base.conf.js]配置 'components': path.resolve(__dirname, '../src/components')
- Ext create动态加载分析
主要涉及到Ext.js Inventory.js ClassManager.js Class.js Loader.js Boot.js 在ClasManager.js的Ext.create中 Ext. ...
- koa2的文件上传
使用koa2搭建文件上传服务,后端代码 const os = require('os'); const path = require('path'); const koaBody = require( ...