bzoj 3195: [Jxoi2012]奇怪的道路 状压dp
来源:互联网 发布:爱上一个中国女人知乎 编辑:程序博客网 时间:2024/06/07 06:23
Description
小宇从历史书上了解到一个古老的文明。这个文明在各个方面高度发达,交通方面也不例外。考古学家已经知道,这个文明在全盛时期有n座城市,编号为1..n。m条道路连接在这些城市之间,每条道路将两个城市连接起来,使得两地的居民可以方便地来往。一对城市之间可能存在多条道路。
据史料记载,这个文明的交通网络满足两个奇怪的特征。首先,这个文明崇拜数字K,所以对于任何一条道路,设它连接的两个城市分别为u和v,则必定满足1 <=|u - v| <= K。此外,任何一个城市都与恰好偶数条道路相连(0也被认为是偶数)。不过,由于时间过于久远,具体的交通网络我们已经无法得知了。小宇很好奇这n个城市之间究竟有多少种可能的连接方法,于是她向你求助。
方法数可能很大,你只需要输出方法数模1000000007后的结果。
Input
输入共一行,为3个整数n,m,K。
Output
输出1个整数,表示方案数模1000000007后的结果。
啊这道题真是道好题啊,推了一个小时看题解看了一个小时,大概能够理解四维的是怎么推的了。
首先考虑状态的定义,由于我们有n个城市,j条路径,所以很容易想到前两维表示第i个城市与存在j条道路,根据一个博客的话来说,所有对立的状态都可以用0,1表示,所以我们第三位state中的0,1表示这条路的度数为奇数还是偶数,由于n非常大,所以这一维需要压缩,因为这和k条路有关,所以可以用一个长度为k+1的01串表示距离当前路k以内的路径的度数以及当前路的度数,不过无脑转移会发生混乱,所有最后还要添加一维l表示考虑转移到了state中的第l个即为考虑到第i-l个。
接着考虑转移,对于每一种情况,我们可以考虑选或不选,如果不选,那么就可以考虑下一条边了,即dp[i][j][state][l-1]+=dp[i][j][state][l];在这里很奇怪的,我们的枚举顺序是for(int l=min(k,i-1);l>=1;l--),取最小值容易理解,因为可能不满k个,但是一个问题困扰了我很久,倒着枚举不是会使一个状态被多个状态计算,这里就要从我们的答案进行计算了,我们倒着枚举,可以起到一种前缀和的效果 ,是的dp[i][j][state][0]的答案是所有该state下的答案之和,不用再麻烦的进行计算了。接着如果选了,那么l与当前i的度数都会是奇边偶,偶变奇,即为dp[i][j+1][state^(1<<l)^1][l]+=dp[i][j][state][l]; 这个就很好理解了。最后,如何转移到下一个点呢,由于i+1的点考虑不到距离它k+1的位置,所以当距离i+1的k+1的点度数为偶数时才能转移,所以如果当前状态的第k个度数为偶数时,就可以转移到i+1与它相同的点了,由于要重新开始考虑连边,所以第四维要变成min(k,i)了。
边界条件就是考虑到第一个点什么都没连答案为1.
答案就是dp[n][m][0][0],n个点m条边考虑完,全为偶数的状态。
下附AC代码。
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;int n,m,k;int dp[35][35][(1<<10)][10];const int mod=1e9+7;int main(){ scanf("%d%d%d",&n,&m,&k); dp[1][0][0][0]=1; for(int i=1;i<=n;i++) { for(int j=0;j<=m;j++) { for(int state=0;state<(1<<(k+1));state++) { for(int l=min(k,i-1);l>=1;l--) { int now=dp[i][j][state][l]; dp[i][j][state][l-1]+=now; if(dp[i][j][state][l-1]>=mod)dp[i][j][state][l-1]-=mod; dp[i][j+1][state^(1<<l)^1][l]+=now; if(dp[i][j+1][state^(1<<l)^1][l]>=mod)dp[i][j+1][state^(1<<l)^1][l]-=mod;}if(((1<<k)&state)==0)dp[i+1][j][state<<1][min(k,i)]+=dp[i][j][state][0];if(dp[i+1][j][state<<1][min(k,i)]>=mod)dp[i+1][j][state<<1][min(k,i)]-=mod;}}}printf("%d\n",dp[n][m][0][0]);}
- BZOJ 3195 JXOI2012 奇怪的道路 状压DP
- bzoj 3195: [Jxoi2012]奇怪的道路 状压dp
- BZOJ 3195: [Jxoi2012]奇怪的道路 状压dp
- bzoj 3195: [Jxoi2012]奇怪的道路 状压dp
- 3195: [Jxoi2012]奇怪的道路 状压DP
- BZOJ 3195 [Jxoi2012]奇怪的道路
- bzoj 3195: [Jxoi2012]奇怪的道路
- 【bzoj3195】【jxoi2012】【奇怪的道路】【状压dp】
- bzoj3195[Jxoi2012]奇怪的道路 状压DP
- bzoj P3195 [Jxoi2012]奇怪的道路
- BZOJ3195: [Jxoi2012]奇怪的道路(状压DP)
- [Jxoi2012]奇怪的道路
- [Jxoi2012]奇怪的道路
- bzoj 3195 奇怪的道路 状压dp
- 【bzoj3195】【 [Jxoi2012]奇怪的道路】另类压缩的状压dp好题
- bzoj 1222 奇怪的dp
- BZOJ 2500 幸福的道路 树形DP+单调队列
- bzoj 1063: [Noi2008]道路设计 树形dp
- 压缩感知重构算法之正则化正交匹配追踪(ROMP)
- tensorflow nan
- NSString 属性更改合集
- 理解OAuth 2.0
- error C1128:字节数超过对象文件格式main.cpp限制:请使用/bigobj进行编译
- bzoj 3195: [Jxoi2012]奇怪的道路 状压dp
- c++函数重载
- 面向对象设计原则
- 函数调用栈 剖析+图解
- javawebday18
- Linux中静态库和共享库的区别
- ASP一句话木马(转)
- tomcat配置字符集防止ajax提交乱码
- Artifact Project3:war exploded: Error during artifact deployment. See server log for details.