bzoj3195[Jxoi2012]奇怪的道路
题意:
n座城市。m条道路连接在这些城市之间,一对城市之间可能存在多条道路。对于任何一条道路,设它连接的两个城市分别为u和v,必定满足1 <=|u - v| <= K。此外,任何一个城市都与恰好偶数条道路相连(0也被认为是偶数)。这n个城市之间究竟有多少种可能的连接方法模1000000007后的结果。n,m≤30,m≤8
题解:
dp。f[i][j][S][l]表示现在处理第i个点,已经练了第j条边,与i相差≤k的点度数奇偶性状态S,正在处理的要和i连边的l。实现挺复杂的,具体看代码。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for(int i=j;i<=k;i++) 5 #define ll long long 6 #define mod 1000000007 7 using namespace std; 8 9 int n,m,kk; ll f[40][40][1<<9][10]; 10 int main(){ 11 scanf("%d%d%d",&n,&m,&kk); 12 f[2][0][0][0]=1; 13 inc(i,2,n)inc(j,0,m)inc(k,0,(1<<kk+1)-1){ 14 inc(l,0,kk-1){ 15 f[i][j][k][l+1]=(f[i][j][k][l+1]+f[i][j][k][l])%mod; 16 if(j<m&&i-kk+l>0) 17 f[i][j+1][k^(1<<kk)^(1<<l)][l]=(f[i][j+1][k^(1<<kk)^(1<<l)][l]+f[i][j][k][l])%mod; 18 } 19 if(!(k&1)&&f[i][j][k][kk])f[i+1][j][k>>1][0]=f[i][j][k][kk]; 20 } 21 printf("%lld",f[n+1][m][0][0]); 22 }
20160702