【bzoj3195】 Jxoi2012—奇怪的道路

http://www.lydsy.com/JudgeOnline/problem.php?id=3195 (题目链接)

题意

  一张$n$个点$m$条边的无向图,每个点度数为偶数,一个点只能向标号与它的差不超过$K$的点连边,问构图方案。

Solution

  三维状态搞了半天的我眼泪掉下来T_T

  $f[i][j][s][l]$表示,前$i$个点,已经连了$m$条边,第$i-K$个点到第$i$个点的状态为$s$,当前讨论$i$与$i-K+l$的连边情况。

  如果$i$与$i-K+l$不连边。$$f[i][j][s][l+1]+=f[i][j][s][l]$$

  如果$i$与$i-K+l$连边。$$f[i][j+1][s*bin[l]*bin[K]][l+1]+=f[i][j][s][l]$$

  跳到下一个$i$,当且仅当$i-K$度数为偶数时可行,因为之后就不会再有节点能够跟$i-K$连边了。$$f[i+1][j][s>>1][0]+=f[i][j][s][K]$$

细节

  边界什么的处理好

代码

// bzoj3195
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf (1ll<<30)
#define MOD 1000000007
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

int f[32][32][1<<9][9],bin[30];
int n,m,K;

int main() {
	scanf("%d%d%d",&n,&m,&K);
	if (n==1 && m==0) {puts("1");return 0;}
	else if (n==1) {puts("0");return 0;}
	bin[0]=1;for (int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
	f[2][0][0][0]=1;
	for (int i=2;i<=n;i++)
		for (int j=0;j<=m;j++)
			for (int k=0;k<bin[K+1];k++) {
				for (int l=0;l<K;l++) if (f[i][j][k][l]) {
						(f[i][j][k][l+1]+=f[i][j][k][l])%=MOD;
						if (j<m && i-K+l>0) (f[i][j+1][k^bin[l]^bin[K]][l]+=f[i][j][k][l])%=MOD;
					}
				if (!(1&k)) (f[i+1][j][k>>1][0]+=f[i][j][k][K])%=MOD;
			}
	printf("%d",f[n+1][m][0][0]);
	return 0;
}
原文地址:https://www.cnblogs.com/MashiroSky/p/6408920.html