zoukankan      html  css  js  c++  java
  • BZOJ 1801 AHOI2009 中国象棋 递归

    标题效果:给定一个棋盘。放置一些枪。它需要随机两支枪不能互相攻击,评估的数目p模值

    首先,两炮不攻击对方自由地等同于一条线最多可有只有两个枪

    直形压力DP话是50分

    考虑到每个列是等效 然后我们就可以直接递归

    令f[i][j][k]为前i行有j列有一个炮 k列有两个炮

    那么讨论

    这行不放炮 方案数为f[i-1][j][k]

    在原先没有炮的列放炮 方案数为f[i-1][j-1][k]*(n-j-k+1)

    在原先有一个炮的列放炮 方案数为f[i-1][j+1][k-1]*(j+1)

    在原先没有炮的两列放炮 方案数为f[i-1][j-2][k]*C(n-j-k+2,2)

    分别在原先没有炮和原先有炮的两列放炮 方案数为f[i-1][j][k-1]*(n-j-k+1)*j

    在原来有一个炮的两列放炮 方案数为f[i-1][j+2][k-2]*C(j+2,2)

    然后就过了……这递推式真让人不敢写啊

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define M 110
    #define MOD 9999973
    using namespace std;
    int m,n,ans;
    long long f[M][M][M];
    inline int C(int x,int y)
    {
    	return x*(x-1)>>1;
    }
    int main()
    {
    	int i,j,k;
    	cin>>m>>n;
    	f[0][0][0]=1;
    	for(i=1;i<=m;i++)
    		for(j=0;j<=n;j++)
    			for(k=0;j+k<=n;k++)
    			{
    				f[i][j][k]=f[i-1][j][k];
    				if(j>=1) f[i][j][k]+=f[i-1][j-1][k]*(n-j-k+1),f[i][j][k]%=MOD;
    				if(k>=1) f[i][j][k]+=f[i-1][j+1][k-1]*(j+1),f[i][j][k]%=MOD;
    				if(j>=2) f[i][j][k]+=f[i-1][j-2][k]*C(n-j-k+2,2),f[i][j][k]%=MOD;
    				if(k>=1) f[i][j][k]+=f[i-1][j][k-1]*(n-j-k+1)*j,f[i][j][k]%=MOD;
    				if(k>=2) f[i][j][k]+=f[i-1][j+2][k-2]*C(j+2,2),f[i][j][k]%=MOD;
    			}
    	for(j=0;j<=n;j++)
    		for(k=0;j+k<=n;k++)
    			ans+=f[m][j][k],ans%=MOD;
    	cout<<ans<<endl;
    }
    


    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    Longest Palindromic Substring问题
    twosum问题
    longest substring问题
    特殊的ARP
    【转】人肉搜索技巧
    ARP攻击
    Linux kali安装及常用命令收集
    【转】ICMP协议
    SpringBoot集成Mybatis-XML方式通用Mapper
    springMVC的controller中insert()多次,记优惠券被多次领取
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4915008.html
Copyright © 2011-2022 走看看