bzoj3195: [Jxoi2012]奇怪的道路
又是被锤烂的一天,特别是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; }
pain and happy in the cruel world.