BZOJ 1801 [Ahoi2009]chess 中国象棋 递推

题意: 考虑一个n*m的棋盘,(n,m<=100),往棋盘上摆炮并且炮之间不会互相攻击的方案数。 解析: 一眼状压,但是100开不下,,所以一定不是状压,考虑DP 但是感觉是递推,然而我并不会推! 状态怎么设?不会! 所以只好看别人设的状态了。 设f[i][j][k]表示前i行有j列有1个炮,有k列有2个炮的方案数。 至于为什么这么设状态,因为一行或者一列至多有两个炮,所以才会这么考虑,但是0个炮再开1维的话绝壁爆炸,所以只好只开俩,0个炮直接用m减即可。 然后就是推转移了。 MD这个转移推的我想哭。 首先明确一行至多放2个。 不放的情况,直接赋过去即可。 放1个,可以是增加一个j,也可以是减少一个j增加一个k。 放2个,可以是增加2个j,也可以是减少两个j增加两个k。 但是这并没有完! 因为还可以先放1个增加1个j,再放一个减少一个j增加一个k。 从一坨里面选一个增加其实就是组合数乘一下就好了。 代码:

using namespace std;typedef long long ll; ll n,m;ll f[N][N][N];int main(){f[0][0][0]=1;scanf(“%lld%lld”,&n,&m);ll ans=0;for(int i=1;i<=n;i++){for(int j=0;j<=m;j++){for(int k=0;k<=m-j;k++){f[i][j][k]=f[i-1][j][k];if(j>=1)f[i][j][k]=(f[i][j][k]+(f[i-1][j-1][k]*(m-j+1ll-k))%mod)%mod;if(k>=1&&j+1<=m)f[i][j][k]=(f[i][j][k]+(f[i-1][j+1][k-1]*(j+1ll))%mod)%mod;if(j>=2)f[i][j][k]=(f[i][j][k]+(f[i-1][j-2][k]*((m-j+2ll-k)*(m-j+1ll-k)/2)%mod)%mod)%mod;if(k>=2&&j+2<=m)f[i][j][k]=(f[i][j][k]+(f[i-1][j+2][k-2]*((ll)(j+2ll)*(ll)(j+1ll)/2)%mod)%mod)%mod;-j-k+1)%mod)%mod)%mod;if(i==n)ans=(ans+f[i][j][k])%mod;}}}printf(“%lld\n”,ans);}

总结失败的原因能够让人越来越谨慎。

BZOJ 1801 [Ahoi2009]chess 中国象棋 递推

相关文章:

  • 【算法】直接插入排序C语言实现
  • 你感兴趣的文章:

    标签云:

    亚洲高清电影在线, 免费高清电影, 八戒影院夜间, 八戒电影最新大片, 出轨在线电影, 午夜电影院, 在线影院a1166, 在线电影院, 在线观看美剧下载, 日本爱情电影, 日韩高清电影在线, 电影天堂网, 直播盒子app, 聚合直播, 高清美剧, 高清美剧在线观看 EhViewer-E站, E站, E站绿色版, qqmulu.com, qq目录网, qq网站目录,