题解 P4063 【[JXOI2017]数列】
发一个不一样的做法~~~~
考虑送后往前构造
最后两个:
然后发现
因为必须满足
同理
同理
当从后向前选至
设
因为
但有一种特殊情况即
记忆化搜索实际上没那么多状态
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int p=998244353;
const int N=52,R=152;
int d[R][R][N][2],r[N];
int dp(int bt,int tp,int cur,int o){
if(cur==0) return 1;
int bot=min(r[cur]+1,bt);
int &ans=d[bt][tp][cur][o];
if(ans>-1) return ans;
ans=0;
int k=0;
if(bt==tp&&o){
k=1,o=0; //k=1时tp-1或bt+1就没有把tp或bt包含在不可取范围
if(bt<=r[cur]) ans=(ans+dp(bt,tp,cur-1,1))%p;
}
for(int i=1;i<bot;i++) ans=(ans+dp(i,tp-k,cur-1,o))%p;
for(int i=tp+1;i<=r[cur];i++) ans=(ans+dp(bt+k,i,cur-1,o))%p;
return ans;
}
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&r[i]);
memset(d,-1,sizeof(d));
int ans=0;
for(int i=1;i<=r[n];i++){
for(int j=1;j<=r[n-1];j++){
int k=ans;
if(i==j) ans=(ans+dp(i,j,n-2,1))%p;
else if(i<j) ans=(ans+dp(i+1,j,n-2,0))%p;
else if(i>j) ans=(ans+dp(j,i-1,n-2,0))%p;//i+1或i-1就没有把A[n]包含在不可取范围
}
}
printf("%d\n",ans);
return 0;
}