1. 程式人生 > >bzoj3195: [Jxoi2012]奇怪的道路

bzoj3195: [Jxoi2012]奇怪的道路

family con tails ret art ace bzoj 又是 max

又是被錘爛的一天,特別是xgc,天天踩爆我還在我身邊吹比,你們去看看他的blog就知道了(埋頭苦幹)

這道題應該這樣來考慮,每次加入一個點,然後去前面k個點進行連邊

需要考慮的是這個點連出多條邊時,順序不同但是本質相同的問題

我們需要強制對於每個本質不同的方案只被某一種順序產生貢獻一次

改變枚舉順序,先枚舉和當前點連的另一個點,然後再枚舉次數,這樣連接點按小到大的順序了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include
<algorithm> #include<cmath> using namespace std; typedef long long LL; const LL mod=1000000007; LL f[50][50][1100]; int main() { int n,m,k,li; scanf("%d%d%d",&n,&m,&k);k=min(k+1,n),li=(1<<k)-1; memset(f,0,sizeof(f));f[1][0][0]=1; for(int i=1;i<=n;i++) {
for(int u=max(0,k-i);u<k-1;u++) for(int j=0;j<m;j++) for(int zt=0;zt<=li;zt++) if(f[i][j][zt]) { int nt=(zt^(1<<u)^(1<<k-1)); f[i][j+1][nt]=(f[i][j+1][nt]+f[i][j][zt])%mod; }
for(int j=0;j<=m;j++) for(int zt=0;zt<=li;zt++) if(!(zt&1))f[i+1][j][zt>>1]=(f[i+1][j][zt>>1]+f[i][j][zt])%mod; } printf("%lld\n",f[n][m][0]); return 0; }

bzoj3195: [Jxoi2012]奇怪的道路