タイトル説明
問題の解決策
ワーム組み合わせ
数日前にはそう精力的に法の外に見て、無菌♂教えられたので、
最初のm-1、[I] [j]がm≤i、リーフノードjの回答を示し、fは設定
また、明らかに転送明らかにO(N ^ 3)の
Fへの長い道のりを演奏した後:
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192
1 1 2 5 13 34 89 233 610 1597 4181 10946 28657 75025 196418
1 1 2 5 14 41 122 365 1094 3281 9842 29525 88574 265721 797162
1 1 2 5 14 42 131 417 1341 4334 14041 45542 147798 479779 1557649
1 1 2 5 14 42 132 428 1416 4744 16016 54320 184736 629280 2145600
1 1 2 5 14 42 132 429 1429 4846 16645 57686 201158 704420 2473785
16778 58598 206516 732825 2613834 132 429 1430 4861 1 1 2 5 14 42
16795 58766 207783 740924 2660139 1 1 2 5 14 42 132 429 1430 4862
1 1 2 5 14 42 132 429 1430 4862 16796 58785 207990 742626 2671892
1 1 2 5 14 42 132 429 1430 4862 16796 58786 208011 742876 2674117
16796 58786 208012 742899 2674414 429 1430 4862 1 1 2 5 14 42 132
16796 58786 208012 742900 2674439 1 1 2 5 14 42 132 429 1430 4862
1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440
1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440
明らかに、i行目I + 1が通常カトレアの数である前に、I + 2からアイテム開始が異なっています
それは見つけることができます:
\(F [1]〜[I] = F [1]〜[I-1] * 1 \)
\(F [2] [I] = F [2] [I-1] * 2 \)
\(F [3] [I] = F [3] [I-1] * 3-F [3] [I-2] * 1 \)
\(F [4] [I] = F [4] [I-1] * 4-F [4] [I-2] * 6 \)
\(F [5] [I] = F [5] [I-1] * 5-F [5] [I-2] * 10 + F [5] [I-3] * 1 \)
推測:
(\ \ {[I] [JK] * [I] [K] F} [I] [J] = \和F)
によって暴力列挙最初の数の後から抜け出すことができます。
1:1
2:2
3:3 -1
4:4 -3
5:5 -6 1
6:6 -10 4
7:7 -15 10 -1
8:8 -21 20 -5
インペリアル\([1 ... M] [0] = 1、[1] [1] = 1、[2] [1] = 2 \) 次に、魔法の式を求めることができます。
\([I] [j]は[I-1]〜[J] + [I-2] = [J-1] \)
放出その後することができる(\ [M])\、次いで解放\(\ [M] F)に
コード
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 998244353
using namespace std;
long long a[5001][5001];
long long f[5001];
int n,m,i,j,k,l;
int main()
{
freopen("ca.in","r",stdin);
freopen("ca.out","w",stdout);
// freopen("a.out","w",stdout);
fo(i,1,5000)
a[i][0]=1;
a[1][1]=1;
a[2][1]=2;
fo(i,3,5000)
{
fo(j,1,5000)
a[i][j]=(a[i-1][j]+a[i-2][j-1])%mod;
}
scanf("%d%d",&m,&n);
--m;
f[1]=1;
fo(i,2,m+1)
{
fo(j,1,i-1)
f[i]=(f[i]+f[j]*f[i-j]%mod)%mod;
}
fo(i,m+2,n)
{
k=1;
fd(j,i-1,1)
{
f[i]=(f[i]+f[j]*a[m][i-j]*k%mod)%mod;
k=-k;
}
}
fo(i,1,n)
printf("%lld\n",(f[i]+mod)%mod);
fclose(stdin);
fclose(stdout);
return 0;
}
公式の説明
実際には、それは難しいことではない、聞かせて\(F [i] [j]は\)私は、現在のポイントにポイントを置く表し、左jにルートから離れてステップする必要があります
だから、\(F [i]の[J ] \) へ行く最後の左に右のポイントに行ってきました彼の左の息子、または息子、それに行くことができます\(F [i]の[J ] - > F [I + 1] [J + 1]、F [I + 1] [J-1] \)
このような注文のDFSで行く移転の性質である、最終的な答えがある\(F [2K-1] [0] \) (最後の点だけ右に行く必要があります)
コード
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define mod 998244353
#define min(a,b) (a<b?a:b)
using namespace std;
int f[10001][5002];
int n,m,i,j,k,l;
int main()
{
freopen("ca.in","r",stdin);
freopen("ca.out","w",stdout);
scanf("%d%d",&m,&n);--m;
f[1][0]=1;
fo(i,1,n+n-2)
{
fd(j,min(m,i-1),0)
if (f[i][j])
{
f[i+1][j+1]=(f[i+1][j+1]+f[i][j])%mod;
if (j>0)
f[i+1][j-1]=(f[i+1][j-1]+f[i][j])%mod;
}
}
for (i=1; i<=n+n-1; i+=2)
printf("%d\n",f[i][0]);
fclose(stdin);
fclose(stdout);
return 0;
}