列表

详情


NC20234. [JXOI2012]奇怪的道路

描述

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

输入描述

输入共一行,为3个整数n,m,K。

输出描述

输出1个整数,表示方案数模1000000007后的结果。

示例1

输入:

3 4 1

输出:

3

示例2

输入:

4 3 3

输出:

4

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 30ms, 内存消耗: 19320K, 提交时间: 2020-10-08 17:49:22

#include<cstdio>
#include<iostream>
const int p=1e9+7;
using namespace std;
 
int n,m,k;
const int N=40,S=522;
int f[N][N][S][10];
 
int main()
{
	scanf("%d %d %d",&n,&m,&k);
	
	f[2][0][0][0]=1;
	for(int i=2;i<=n;i++)
		for(int j=0;j<=m;j++)
			for(int s=0;s<(1<<(k+1));s++)
			{
				for(int l=0;l<k;l++)
				{
					f[i][j][s][l+1]+=f[i][j][s][l];
					f[i][j][s][l+1]%=p;
					if(i-k+l>0&&j<m)
						f[i][j+1][s^(1<<k)^(1<<l)][l]+=f[i][j][s][l],
						f[i][j+1][s^(1<<k)^(1<<l)][l]%=p;
				}
				if(!(s&1))
					f[i+1][j][s>>1][0]+=f[i][j][s][k],
					f[i+1][j][s>>1][0]%=p;
			}
		
	printf("%d\n",f[n+1][m][0][0]);//不用算sum了
	return 0;
}
 

C++ 解法, 执行用时: 40ms, 内存消耗: 22392K, 提交时间: 2022-07-24 20:54:24

#include <bits/stdc++.h>
const int MOD = 1e9+7;
using namespace std;
 
int n, m, k;
int f[44][44][555][11];
 
signed main() {
    cin >> n >> m >> k;
	f[2][0][0][0]=1;
	for (int i=2;i<=n;i++)
		for (int j=0;j<=m;j++)
			for (int s=0;s<(1<<(k+1));s++) {
				for (int l=0;l<k;l++){
					f[i][j][s][l+1]+=f[i][j][s][l];
					f[i][j][s][l+1]%=MOD;
					if(i-k+l>0&&j<m)
						f[i][j+1][s^(1<<k)^(1<<l)][l]+=f[i][j][s][l],
						f[i][j+1][s^(1<<k)^(1<<l)][l]%=MOD;
				}
				if(!(s&1)) {
					f[i+1][j][s>>1][0]+=f[i][j][s][k];
					f[i+1][j][s>>1][0]%=MOD;
                }
			}
	cout << f[n + 1][m][0][0] << endl;
	return 0;
}
 

上一题