#計數,記憶化搜尋#C 連邊方案
阿新 • • 發佈:2020-12-02
分析
設\(dp[i][j][k][l]\)表示處理到\([i-l+1,i]\)的連邊,二進位制狀態(奇點還是偶點)為\(k\)的方案數,
最後一維是為了避免算重,那麼如果第\(i-l+1\)位是偶點可以轉移到\(i+1\),否則列舉連邊即可
程式碼
#include <cstdio> #include <cstring> #include <algorithm> #define rr register using namespace std; const int mod=1000000007; int nn,mm,k,dp[32][32][511][10]; inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;} inline signed dfs(int n,int m,int S,int now){ if (~dp[n][m][S][now]) return dp[n][m][S][now]; if (n==nn+1) return m==mm; rr int ans=0; if (!(S&1)) ans=mo(ans,dfs(n+1,m,S>>1,1)); if (m<mm){ rr int lim=min(k,nn-n); for (rr int i=now;i<=lim;++i) ans=mo(ans,dfs(n,m+1,S^1^(1<<i),i)); } return dp[n][m][S][now]=ans; } signed main(){ freopen("graph.in","r",stdin); freopen("graph.out","w",stdout); scanf("%d%d%d",&nn,&mm,&k); memset(dp,-1,sizeof(dp)); return !printf("%d",dfs(1,0,0,1)); }