• P2051 [AHOI2009]中国象棋[线性DP]


    最近智商有点不在线。其实一直不在线。

    题目


    先是想用$f[i][j][k][0/1/2]$表示摆了i行时有j列空着,k列有了一个炮,且当下摆了0/1/2个的状态,转移方程写的出来但是极其繁琐。于是又设法听取评讲者题解修改状态,最后的012完全可以删去。那么仍可以表示这一行那些列摆过1个,那些列摆过0个的种类。转移时分类即可。

    $f[i][j][k]+=f[i-1][j][k]$ 什么都不摆

    $f[i][j][k]+=(j+1)*f[i-1][j+1][k-1]$  摆1个炮

    $f[i][j][k]+=(k+1)*f[i-1][j][k+1]$  摆1个炮

    $f[i][j][k]+=(j+1)*(j+2)/2*f[i-1][j+2][k-2]$  摆两个炮,下同

    $f[i][j][k]+=(k+1)*(k+2)/2*f[i-1][j][k+2]$  

    $f[i][j][k]+=k*(j+1)*f[i-1][j+1][k]$

    注意边界就行。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef pair<int,int> pii;
     5 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
     6 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
     7 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
     8 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
     9 template<typename T>inline T read(T&x){
    10     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    11     while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();return f?x=-x:x;
    12 }
    13 const int N=100+7,P=9999973;
    14 int n,m,ans,f[N][N][N];
    15 
    16 inline void inc(int&x,int y){(x+=y)>=P?x-=P:1;}
    17 
    18 int main(){//freopen("tmp.in","r",stdin);freopen("tmp.out","w",stdout);
    19     read(n),read(m);if(m<2){printf("%d
    ",1+n+(n)*(n-1)/2);return 0;}
    20     f[1][m][0]=1,f[1][m-1][1]=m,f[1][m-2][2]=m*(m-1)/2;
    21     for(register int i=2;i<=n;++i)
    22         for(register int j=0;j<=m;++j)
    23             for(register int k=0;k<=m-j;++k){
    24                 inc(f[i][j][k],f[i-1][j][k]);
    25                 if(k)inc(f[i][j][k],(j+1)*f[i-1][j+1][k-1]%P);
    26                 inc(f[i][j][k],(k+1)*f[i-1][j][k+1]%P);
    27                 if(k>=2)inc(f[i][j][k],((j+1)*(j+2)>>1)*1ll*f[i-1][j+2][k-2]%P);
    28                 inc(f[i][j][k],((k+1)*(k+2)>>1)*1ll*f[i-1][j][k+2]%P);
    29                 inc(f[i][j][k],1ll*k*(j+1)*f[i-1][j+1][k]%P);
    30             }
    31     for(register int i=0;i<=m;++i)for(register int j=0;j<=m-i;++j)inc(ans,f[n][i][j]);
    32     printf("%d
    ",ans);
    33     return 0;
    34 }
  • 相关阅读:
    数据库从别的数据库查询一张表在插入到新的数据库里面
    html5 学习随笔 1
    .net MVC 学习笔记 (一)
    Html5 本地存储
    .net MVC 学习笔记 (二)
    蝙蝠侠解救罗宾的问题
    求职的第一面Harman
    求职第七面——烽火通讯
    求职的第二面—Samsung
    求职第六面——瑞星微电子
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10358509.html
Copyright © 2020-2023  润新知