暴力\(DP \)
暴力考える\(DP \)を、我々は設定\(F_ {I、J} \) を表し、現在のオーバーレイ長\(Iは\) 、第1の折り長さ\(J \)プログラムの数。
列挙は、折り畳まれた長さ転送する必要が\(K \)(\ (K \ GE J \)で)次のように、転写式です:
\ [F_ {I + 2K-J、K} + = F_ {I、J} \]
左右の場合は、初期設定に応じて、\(DP \)二回。
列挙側は時間統計計算の長さをカバーします。
最適化\(DP \)
実際に、我々は使用することができ、\(DP \)二つの配列は、左の点のための1つに分割(X \)\桁の実施形態では、他の右端が表す\(Y \)桁スキーム。
転送は、比較的単純な方程式である場合には:
\ [A_ {X + I} + = A_X、B_ {X + 2I} + = A_X \]
コード
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 10000
#define X 998244353
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
using namespace std;
int n,l,r;
class Dper
{
private:
int f[N+5],g[N+5],p[N+5];
public:
I void Solve()
{
#define DP(s,x,y) for(p[0]=i=1,t=n-y;i<=n;++i) p[i]=0;\
for(i=x;2*i<=t;++i) for(j=0;2*i+j<=t;++j) Inc(p[i+j],p[j]),Inc(s[2*i+j],p[j]);++s[x];//用#define简洁表示两次DP
RI i,j,t,ans=0;DP(f,l,r);DP(g,r,l);//DP预处理
for(i=l;i<=n-r;++i) ans=(1LL*f[i]*g[n-i]+ans)%X,Inc(f[i+1],f[i]);printf("%d",ans);//统计答案
}
}D;
int main()
{
freopen("fold.in","r",stdin),freopen("fold.out","w",stdout);
return scanf("%d%d%d",&n,&l,&r),D.Solve(),0;
}