1 条题解
-
0
自动搬运
来自洛谷,原作者为

VSEJGFB
**搬运于
2025-08-24 21:56:05,当前版本为作者最后更新于2018-04-09 22:18:27,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
发一个不一样的做法~~~~
考虑送后往前构造
最后两个:是可以分别在中任意选.
然后发现不能在与之间 但可以是
因为必须满足或者或三者相等
同理也满足此条件且还不能在与之间(因为上面条件限制所以也不行)。
同理……
当从后向前选至时,不能选的值一定为一个区间。
设为当前选择,不能选的区间为
因为所以若则由或转移过来。(因为不能在与之间。)
但有一种特殊情况即时可以等于或者不等于。若不等于,则 可以等于(比如可以等于)而且此时必定所以bt或tp不在的不可取范围内。
设,时满足这种情况,则不满足。
边界.
状态个,转移 记忆化搜索实际上没那么多状态
#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; }
- 1
信息
- ID
- 3025
- 时间
- 3000ms
- 内存
- 500MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者