题目链接:找兔子

n的范围是[1, 15],可以用0 到 (1<<n)-1 的数表示全部状态,用dp[i] = t表示到达状态i的最少时间是t,对于每个点,如果它能到达的所有点在t秒时都已经确定了会不会有兔纸,那这个点就确定了在(t+1)s会不会有兔纸。对于每个时刻,可以询问<=2个点,所以由初始状态可以搜到最后确定能不能找到兔纸。

我没有想到找不到兔纸的数据...

关键是dp的思想==很巧妙。

附代码:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#define maxn 16
#define inf 10000000
using namespace std; int edge[maxn]; // 储存每个点的边的信息
int dp[1<<maxn]; // dp[i]表示到达i状态的最少时间,一共有1<<n个状态 i的二进制中1表示已经确定了该点,0表示还没有 int main() {
int t;
cin >> t;
while(t--) {
int n, m;
memset(edge, 0, sizeof(edge));
cin >> n >> m;
for (int i=0; i<=(1<<n); ++i) {
dp[i] = inf;
} for (int i=0; i<m; ++i) {
int x, y;
cin >> x >> y;
x--, y--;
edge[x] |= (1<<y);
edge[y] |= (1<<x);
} for (int i=0; i<n; ++i) {
if (!edge[i]) edge[i] |= (1<<i);
} queue<int>que;
dp[0] = 0;
que.push(0); while(!que.empty()) {
int now = que.front();
que.pop();
int nxt = 0; for (int i=0; i<n; ++i) {
if ((now&edge[i]) == edge[i]) {
nxt |= (1<<i); // 所有当前已经确定的点(不是状态)都保存在了nxt中。
}
} for (int i=0; i<n; ++i) {
for (int j=i+1; j<n; ++j) {
int nxtstu = (nxt|(1<<i)|(1<<j)); //可以确定状态nxtstu 时间选择min
if (dp[nxtstu] > dp[now] + 1) {
dp[nxtstu] = dp[now] + 1;
que.push(nxtstu);// 如果当前状态更新 加入队列以更新它可以到达的状态
}
}
}
} int tot = (1<<n)-1;
int ans = dp[tot]; //全部点都确定的一个状态 for (int i=0; i<n; ++i) {
int stu = (tot^(1<<i)); //每个还有一个点没确定的状态
ans = min(ans, dp[stu]);
} if (ans == inf) {
cout << "-1\n";
}
else cout << ans << endl;
}
return 0;
}

  

FZU 2093 找兔子 状压DP的更多相关文章

  1. 没有找零 状压dp

    没有找零 状压dp 约翰到商场购物,他的钱包里有K(1 <= K <= 16)个硬币,面值的范围是1..100,000,000.约翰想按顺序买 N个物品(1 <= N <= 1 ...

  2. [BZOJ3312][USACO]不找零(状压DP)

    Description 约翰带着 N 头奶牛在超市买东西,现在他们正在排队付钱,排在第 i 个位置的奶牛需要支付 Ci元.今天说好所有东西都是约翰请客的,但直到付账的时候,约翰才意识到自己没带钱,身上 ...

  3. Codeforces 1383C - String Transformation 2(找性质+状压 dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神奇的强迫症效应,一场只要 AC 了 A.B.D.E.F,就一定会把 C 补掉( 感觉这个 C 难度比 D 难度高啊-- 首先考虑对问题进 ...

  4. FZU 1025 状压dp 摆砖块

    云峰菌曾经提到过的黄老师过去讲课时的摆砖块 那时百度了一下题目 想了想并没有想好怎么dp 就扔了 这两天想补动态规划知识 就去FZU做专题 然后又碰到了 就认真的想并且去做了 dp思想都在代码注释里 ...

  5. FZU - 2218 Simple String Problem 状压dp

    FZU - 2218Simple String Problem 题目大意:给一个长度为n含有k个不同字母的串,从中挑选出两个连续的子串,要求两个子串中含有不同的字符,问这样的两个子串长度乘积最大是多少 ...

  6. Codeforces 1225G - To Make 1(bitset+状压 dp+找性质)

    Codeforces 题目传送门 & 洛谷题目传送门 还是做题做太少了啊--碰到这种题一点感觉都没有-- 首先我们来证明一件事情,那就是存在一种合并方式 \(\Leftrightarrow\) ...

  7. FZU - 2218 Simple String Problem(状压dp)

    Simple String Problem Recently, you have found your interest in string theory. Here is an interestin ...

  8. [luoguP3092] [USACO13NOV]没有找零No Change(状压DP + 二分)

    传送门 先通过二分预处理出来,每个硬币在每个商品处最多能往后买多少个商品 直接状压DP即可 f[i]就为,所有比状态i少一个硬币j的状态所能达到的最远距离,在加上硬币j在当前位置所能达到的距离,所有的 ...

  9. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...

随机推荐

  1. 详解.NET异步

    在说到异步前,先来理一下几个容易混淆的概念,并行.多线程.异步. 并行,一般指并行计算,是说同一时刻有多条指令同时被执行,这些指令可能执行于同一CPU的多核上,或者多个CPU上,或者多个物理主机甚至多 ...

  2. NYOJ214

    单调递增子序列(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 给定一整型数列{a1,a2...,an}(0<n<=100000),找出单调递增最长 ...

  3. 【FFT-快速傅立叶变换】

    HDU-1402 A * B Problem Plus 题意:给定两个整数,整数的长度最多能达到50000位,输出两个整数的乘积. 分析:题意非常的明了,一个惊世骇俗的想法是使用两个数组将整数保留起来 ...

  4. MyEclipse中文乱码解决方法

    在Myeclipse导入一个项目,有中文乱码问题,解决方法如下: 一.将整个project设置编码UTF-8(UTF-8可以最大的支持国际化) windows->Preferences-> ...

  5. hibernate对象关系实现(三)多对多实现

    单向n-n:(catogory-item)一个类别对应多个条目,一个条目对应多个类别 a.以类别类中有条目的集合的引用为例: b.数据库中的体现:建立一个新表,以类别和条目的主键关联的外键做新表的联合 ...

  6. Nexus4_屏幕截图目录

    1. /sdcard/Pictures/Screenshots/ 2. 3.

  7. Promise A 规范的一个简单的浏览器端实现

    简单的实现了一个promise 的规范,留着接下来模块使用.感觉还有很多能优化的地方,有时间看看源码,或者其他大神的代码 主要是Then 函数.回调有点绕人. !(function(win) { fu ...

  8. POJ2676,HDU4069解决数独的两种实现:DFS、DLX

    搜索实现:解决数独有两种思考策略,一种是枚举当前格能填的数字的种数,这里有一优化策略就是先搜索能填入种数小的格子:另一种是考虑处理某一行(列.宫)时,对于某一个没用过的数字,若该行(列.宫)只有一个可 ...

  9. Oracle 逐条和批量插入数据方式对比

    创建测试表 create table base_users ( userid         varchar2(16), username  varchar2(32), passwd      var ...

  10. CentOS7静默安装oracle11g

    操作系统: [root@docker ~]# uname -m x86_64 [root@docker ~]# cat /etc/redhat-release CentOS Linux release ...