【ARC102E】ストップ。そうでなければ...

タイトル

問題の意味:指定された\(N- \)番目の差がない\(K \)のため、ダイスを両面\(私は[2,2K]で\ \)は、 どのように多くのダイ配列は、任意の2つのダイスと判定されたとない\(I \)

一点制限のために検討\(iは\)にポイントを使用する場合、(J \)\次いでする指し、サイコロを(\ IJ)を\ダイスを使用することができません

だから、制限のために\(私は\) 我々はできる(1 \)を\する(K \)\ポイントを\(j個\)クラスについてのポイント

  • \(J \ NEQ IJ、IJ \ [1、K] \) すなわち\(J \)\(IJ \)二つの異なる法的点、2点がある唯一の出現であります

  • \([1、K] \ notin \のIJ) すなわち\(Jは\)限定されるものではなく、このような点を生じます

  • \(IJ = J \) すなわち、\(I = 2J \) 今回はポイント数\(jは\は)一度だけ表示されます

我々は異なるためにことがわかった\(私は\)場合に限り、3つのカテゴリーに分類することができ、そして第三のカテゴリーに表示されます\(私は\)場合でも数

だから我々は、最初の2つのケースについて議論することができます

私たちは、最初のケースを覚え持っているポイントを\(CNT1 \)のための第二ケースポイントがきた\(CNT2 \)

我々は、2つのアレイがあると\(dp_ {I、J} \) 以下で表される\(Iは\)ミューテックスCouchuを指すように\(J \)どのように多くの状況の数を、\(F_ {I 、J} \)で表され、(私は\)\補うためにポイントの種類\(J \)私たちの答えはどのように多くの場合、数を

\ [\ sum_ {J = 0} ^ {ndp_ CNT1、J}回F_ {CNT2、NJ} \ \]

場合(私は\)\必要追加する場合でもある(\ \ sum_ {jは0回F_ {CNT2、N-1-J} \} ^ {N-1} dp_ {CNT1、J}を\) 、すなわち数$のうち空する
の\ FRAC {2}} I {$条件をしてください。

考えてみましょう\(F、DPの\)の入手方法

\(F \)より良好な需要、明らかに\(F_ {I、J} = \ sum_ {K = 0} ^ jf_ {I-1、K} \)最初のために、すなわち、\(Iは\)種は、ピースを指しそれはどのように多く選んだ何のため

\(DP \)意味ミューテックスに数を表し、その後ペアにミューテックス数、2点のいずれかが発生する可能性があり、そう\(dp_ {I、J} = dp_ {I-1、J} +2 \タイムズの\ sum_ {0} = ^ {K-K-I 1} {dp_。1、K} \) すなわち、両方のため、多数の列挙から選択された点の対を充填することができるので、取る\(2 \を)

コード

#include<bits/stdc++.h>
#define re register
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
inline int read() {
    char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int mod=998244353;
const int maxn=2005;
int n,m,a[maxn];
int dp[maxn][maxn],f[maxn][maxn];
inline int qm(int x) {return x>=mod?x-mod:x;}
inline int dqm(int x) {return x<0?x+mod:x;}
inline int calc(int n,int a,int b) {
    int now=0;
    for(re int j=0;j<=n;j++)
        now=qm(now+1ll*dp[a][j]*f[b][n-j]%mod);
    return now;
}
int main() {
    scanf("%d%d",&m,&n);
    a[0]=1;dp[0][0]=1;for(re int i=1;i<=m;i++) dp[i][0]=1;
    for(re int i=1;i<=m;i++) {
        for(re int j=1;j<=n;j++)
            a[j]=qm(a[j-1]+dp[i-1][j]);
        for(re int j=1;j<=n;j++)
            dp[i][j]=qm(2ll*a[j-1]%mod+dp[i-1][j]);
    }
    for(re int i=0;i<=m;i++) f[i][0]=1;
    for(re int i=1;i<=m;i++)
        for(re int j=1;j<=n;j++)
            f[i][j]=qm(f[i][j-1]+f[i-1][j]);
    int cnt1=0,cnt2=0,ans=0;
    for(re int i=2;i<=2*m;++i) {
        cnt1=cnt2=0;
        for(re int j=1;j<=m;j++) {
            if(i-j==j) continue;
            if(i-j>=1&&i-j<=m) {
                if(j<i-j) ++cnt1;
            }
            else ++cnt2;
        }
        ans=calc(n,cnt1,cnt2);
        if(!(i&1)) ans=qm(ans+calc(n-1,cnt1,cnt2));
        printf("%d\n",ans);
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/asuldb/p/11620967.html