zoukankan      html  css  js  c++  java
  • 【bzoj1801】[AHOI2009]中国象棋 [动态规划]

    2051 [AHOI2009]中国象棋

    开始瓜想状压 发现n≤100压个P

    分情况来讨论 利用乘法原理和加法原理

    f[i][j][k]放第i行当前只有一个棋子的有j列 有两个棋子的有k列

    #include<bits/stdc++.h>
    using namespace std;
    #define Max(x,y) (x)<(y)?(y):(x)
    #define Min(x,y) (x)<(y)?(x):(y)
    #define ll long long
    #define rg register
    const int N=100+5,M=1000000+5,inf=0x3f3f3f3f,P=9999973;
    ll n,m,ans=0,f[N][N][N];
    template <class t>void rd(t &x){
        x=0;int w=0;char ch=0;
        while(!isdigit(ch)) w|=ch=='-',ch=getchar();
        while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
        x=w?-x:x;
    }
    
    //72 89
    int main(){
    //    freopen("in.txt","r",stdin);
        rd(n),rd(m);
        memset(f,0,sizeof(f)); 
        f[0][0][0]=1;
        for(int i=0;i<n;++i)
        for(int j=0;j<=m;++j)//放1 
        for(int k=0;k<=m-j;++k){//放俩 
            f[i+1][j][k]=(f[i+1][j][k]+f[i][j][k])%P;
            if(j) f[i+1][j-1][k+1]=(f[i+1][j-1][k+1]+f[i][j][k]*j)%P;//放一个在有一个棋子
            if(j>=2) f[i+1][j-2][k+2]=(f[i+1][j-2][k+2]+f[i][j][k]*((j-1)*j/2))%P;//放在两个有一个的列上
            if(j+k+1<=m) f[i+1][j+1][k]=(f[i+1][j+1][k]+f[i][j][k]*(m-j-k))%P;//在没有棋子的放一个 
            if(j+k+2<=m) f[i+1][j+2][k]=(f[i+1][j+2][k]+f[i][j][k]*((m-j-k-1)*(m-j-k)/2))%P;//俩没有棋子的各放一个 
            if(j&&j+k+1<=m) f[i+1][j][k+1]=(f[i+1][j][k+1]+f[i][j][k]*(m-j-k)*j)%P;//一个在有一个 一个在无
        }
        for(int i=0;i<=m;++i)
        for(int j=0;j<=m-i;++j) ans=(ans+f[n][i][j])%P;
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    关于换行
    WebService
    C#操作XML的通用方法总结
    19个必须知道的Visual Studio快捷键
    Asp.net C# 把 Datatable转换成JSON 字符串
    C#中的多态性
    virtual和abstract
    DataTable的过滤需要的数据
    自定义控件之瀑布流与水波纹实现
    反转链表
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11204882.html
Copyright © 2011-2022 走看看