题目描述

小宇从历史书上了解到一个古老的文明。这个文明在各个方面高度发达,交通方面也不例外。 
考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n。m条道路连接在这些城市之间,每条道路将两个城市连接起来,使得两地的居民可以方便地来往。 
一对城市之间可能存在多条道路。 据史料记载,这个文明的交通网络满足两个奇怪的特征。 
首先,这个文明崇拜数字K,所以对于任何一条道路,设它连接的两个城市分别为u和v,则必定满足1 <=|u - v| <= K。此外,任何一个城市都与恰好偶数条道路相连(0也被认为是偶数)。 
不过,由于时间过于久远,具体的交通网络我们已经无法得知了。 
小宇很好奇这n个城市之间究竟有多少种可能的连接方法,于是她向你求助。  
方法数可能很大,你只需要输出方法数模1000000007后的结果。

100%的数据满足1 <= n <= 30, 0 <= m <= 30, 1 <= K <= 8.

简化版题意:n个点m条边,满足条件:

  1. 每个点的度为偶数。
  2. 每条边连接的顶点u,v编号之差不超过K且没有自环。

求方案数%1000000007后的值。

思路

  挺神的一道状压$DP$题。难点在于状态量的表示。首先我们分析数据范围,发现$K<=8$,那么很显然状态压缩的那一维和K有关,也是我们直接想到状压$DP$的一个原因。

  那么有$f[i][j][s]$表示前$i$个点,连了$j条边,编号为i-k->i$的点的状态为$s$,那么显然$s$表示的是这些点度数的奇偶性。

  然后快乐的开始推。考虑加入一条边的状态转移。然后,就没有然后了。。。。。。(本人做此题也就到此为止了)

  怎么加边?以$i$为一个端点,另一个呢?很显然这个状态不足以满足$DP$转移,我们需要再加一维,表示当前的$i$向哪个点连边。又因为顶点编号之差$<=k$,我们只需要考虑$i向区间[i-k,i-1]$的连边就可以了。那么有$f[i][j][s][l]表示前i个点,连了j条边,[i-k,i]的状态为s,处理当前点i和i-k+l$之间的连边。

  转移不是特别难(这里采用刷表):

  1. $i和i-k+l不连边,有f[i][j][s][l+1]+=f[i][j][s][l]$
  2. $i和i-k+l$连边,有$f[i][j+1][s$ $ \oplus$ $1<<k$ $\oplus$ $1<<l][l]+=f[i][j][s][l]$
  3. 考虑增加一个点,那么必须有:编号为$i-k$的点度数为偶数,$[i-k,i-1]$区间的点和i已经全部转移

  答案就是$f[n][m][0][k]$前$n$个点连接了$m$条边,当且处理的是$n-k+k=n$,即$[n-k,n-1]$全部处理完的情况。

code

#include<bits/stdc++.h>
using namespace std;
const int p=;
const int S=<<;
int f[][][S][];
int n,m,k; int main()
{
scanf("%d%d%d",&n,&m,&k);
f[][][][]=;//初始化,1,2间没有连边也是一种方案
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
for(int s=;s<(<<k+);s++)//枚举状态
{
for(int l=;l<k;l++)//枚举i-k+l
{
f[i][j][s][l+]+=f[i][j][s][l]%=p;//不连边
if(i-k+l>&&j<m)f[i][j+][s^(<<l)^(<<k)][l]+=f[i][j][s][l]%=p;//连边
}
if(!(s&))f[i+][j][s>>][]+=f[i][j][s][k]%=p;//把i-k删去,加入i+1
}
cout<<f[n][m][][k];
}

奇怪的道路——状压DP的更多相关文章

  1. 【BZOJ3195】[Jxoi2012]奇怪的道路 状压DP

    [BZOJ3195][Jxoi2012]奇怪的道路 Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座 ...

  2. BZOJ 3195 [Jxoi2012]奇怪的道路 | 状压DP

    传送门 BZOJ 3195 题解 这是一道画风正常的状压DP题. 可以想到,\(dp[i][j][k]\)表示到第\(i\)个点.已经连了\(j\)条边,当前\([i - K, i]\)区间内的点的度 ...

  3. 【BZOJ-3195】奇怪的道路 状压DP (好题!)

    3195: [Jxoi2012]奇怪的道路 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 305  Solved: 184[Submit][Statu ...

  4. bzoj 3195 奇怪的道路 状压dp

    看范围,状压没毛病 但是如果随便连的话给开1<<16,乘上n,m就爆了 所以规定转移时只向回连边 于是想状态数组:f[i][j]表示到i这里i前K位的状态为j(表示奇偶) 发现有条数限制, ...

  5. bzoj3195 [Jxoi2012]奇怪的道路——状压DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3195 看到数据范围就应该想到状压呢... 题解(原来是这样):https://www.cnb ...

  6. 【BZOJ 3195 】[Jxoi2012]奇怪的道路 装压dp

    受惯性思维的影响自动把二进制状态认为是连与不连......... 我们这里二进制状态表示的是奇偶,这样的话我们f[i][j][k]表示的就是前i个城市用了j个边他前k个城市的奇偶状态,然后想想怎么转移 ...

  7. 【bzoj3195】【 [Jxoi2012]奇怪的道路】另类压缩的状压dp好题

    (上不了p站我要死了) 啊啊,其实想清楚了还是挺简单的. Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期 ...

  8. 算法复习——状压dp

    状压dp的核心在于,当我们不能通过表现单一的对象的状态来达到dp的最优子结构和无后效性原则时,我们可能保存多个元素的有关信息··这时候利用2进制的01来表示每个元素相关状态并将其压缩成2进制数就可以达 ...

  9. 状压dp专题复习

    状压dp专题复习 (有些题过于水,我直接跳了) 技巧总结 : 1.矩阵状压上一行的选择情况 \(n * 2^n\) D [BZOJ2734][HNOI2012]集合选数 蒻得不行的我觉得这是一道比较难 ...

随机推荐

  1. Android 捕捉app系统中未处理的异常

    一:为什么要处理? 其实我们都知道,在开发过程中,自己的app系统或许有许多隐藏的异常,自己没有捕捉到,那么关于异常的捕捉,这是相当重要的,如果系统发生崩溃,那么至少也可以让系统挂在系统之内,不会发现 ...

  2. 创建一个 Laravel 项目

    创建一个 Laravel 项目,首先需要安装 Composer ,如果没有安装的参考 https://docs.phpcomposer.com/00-intro.html 一.安装 Laravel 安 ...

  3. 02-19 k近邻算法(鸢尾花分类)

    [TOC] 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnblogs.com/nickchen121/ ...

  4. B-微积分-Sigmoid函数

    目录 Sigmoid函数 一.Sigmoid函数详解 更新.更全的<机器学习>的更新网站,更有python.go.数据结构与算法.爬虫.人工智能教学等着你:https://www.cnbl ...

  5. Redis 介绍学习

    1.Redis 简介 Redis 是一个支持数据结构更多的键值对数据库.它的值不仅可以是字符串等基本数据 类型,也可以是类对象,更可以是 Set.List.计数器等高级的数据结构. Memcached ...

  6. tesseract 测试样例

    该图片的链接为https://raw.githubusercontent.com/Python3WebSpider/TestTess/master/image.png,可以直接保存或下载. 首先用命令 ...

  7. [LUOGU1868] 饥饿的奶牛 - dp二分

    题目描述 有一条奶牛冲出了围栏,来到了一处圣地(对于奶牛来说),上面用牛语写着一段文字. 现用汉语翻译为: 有N个区间,每个区间x,y表示提供的x~y共y-x+1堆优质牧草.你可以选择任意区间但不能有 ...

  8. tomcat+Apache介绍

    tomcat不是一个完整意义上的Jave EE服务器,它甚至都没有提供对哪怕是一个主要Java EE API的实现:但由于遵守apache开源协议,tomcat却又为众多的java应用程序服务器嵌入自 ...

  9. Js极客之路 - 简化操作

    1.对字符串使用单引号(避免动态添加元素时html会出现的双引号"引起的冲突,方便操作 - 单引号一个键,双引号两个键) // bad var name = "Barrior&qu ...

  10. 学习笔记:flutter项目搭建(mac版)

    什么是flutter Flutter是谷歌的移动UI框架,可以快速在iOS和Android上构建高质量的原生用户界面. Flutter可以与现有的代码一起工作.在全世界,Flutter正在被越来越多的 ...