# 奇怪的道路 状态压缩DP

奇怪的道路 状态压缩DP


问题:

小宇从历史书上了解到一个古老的文明。这个文明在各个方面高度发达,交通方面也不例外。
考古学家已经知道,这个文明在全盛时期有\(n\)座城市,编号为\(1..n\)\(m\)条道路连接在这些城市之间,每条道路将两个城市连接起来,使得两地的居民可以方便地来往。一对城市之间可能存在多条道路。

据史料记载,这个文明的交通网络满足两个奇怪的特征。首先,这个文明崇拜数字K,所以对于任何一条道路,设它连接的两个城市分别为\(u\)\(v\),则必定满足\(1 <=|u - v| <= K\)。此外,任何一个城市都与恰好偶数条道路相连(\(0\)也被认为是偶数)。
不过,由于时间过于久远,具体的交通网络我们已经无法得知了。小宇很好奇这\(n\)个城市之间究竟有多少种可能的连接方法,于是她向你求助。

方法数可能很大,你只需要输出方法数模\(1000000007\)后的结果。

解:
一看这题的范围\(k\) 这么小比一般状态压缩的题 所以肯定不是一维
对没错 他是的san维d
我们定义\(f[i][j] [k]\)表示前i个城市选前j条道路并且[1,i-k-1]已经满足变为偶数并且[i-k,i]集合为k的方案数
那么决策就是城市 i 的这条边选还是不选

  • 如果选这条边
    假如与s号城市连边
    那状态转移方程\(f[i][j+1][k\)^\((1<<i-s)\)^\(1]+=f[i][j][k];\)
  • 如果它不连边
    只要保证i-k 为0 即可
    $ f[i+1][j][k<<1]+=f[i][j][k];$

话说这个枚举顺序有毒 ....:
code:


#include<bits/stdc++.h> 
using namespace std; 
#define mod 1000000007 
#define maxnn 66666 
#define ll long long 
int n,m,kk; 
ll all; 
ll f[60][60][maxnn]; 
int main() { 
    cin>>n>>m>>kk; 
    all=(1<<kk+1)-1; 
    f[1][0][0]=1; 
    for(int i=1;i<=n;i++)
    {
        for(int p=1;p<=min(kk,i-1);p++)
        {
            for(int j=0;j<m;j++)
            {
                for(int k=0;k<=all;k++)
                {
                    int s=k^(1<<p)^1;
                    f[i][j+1][s]+=f[i][j][k]%mod;
                }
            }
        }
        
        for(int j=0;j<=m;j++)
        {
            for(int k=0;k<=all;k++)
            {
                if(i<n&&(!(k&(1<<kk))))
                {
                    f[i+1][j][k<<1]+=f[i][j][k]%mod;
                }
            }
        }
    }
        cout<<f[n][m][0]%mod; 
}

转载于:https://www.cnblogs.com/OIEREDSION/p/11431605.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值