【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; }
This passage is made by MashiroSky.