jzoj6343-[NOIP2019模拟2019.9.7]Medium Counting【记忆化dfs,dp】
生活随笔
收集整理的這篇文章主要介紹了
jzoj6343-[NOIP2019模拟2019.9.7]Medium Counting【记忆化dfs,dp】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目大意
給出nnn個字符串SiS_iSi?,然后有些???號可以進行隨便填字母。
然后要求Si<Si+1S_i<S_{i+1}Si?<Si+1?的情況下求方案數。
解題思路
定義fl,r,p,cf_{l,r,p,c}fl,r,p,c?表示只考慮l~rl\sim rl~r的字符串,只考慮ppp往后的字符,且第ppp個至少為ccc時的方案數。
我們有
fl,r,p,c=fl,r,p,c+1+∑mid=lrfl,mid,p+1,0+fmid+1,r,p,cf_{l,r,p,c}=f_{l,r,p,c+1}+\sum_{mid=l}^r f_{l,mid,p+1,0}+f_{mid+1,r,p,c}fl,r,p,c?=fl,r,p,c+1?+mid=l∑r?fl,mid,p+1,0?+fmid+1,r,p,c?
然后用dfsdfsdfs進行轉移即可。
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=55,XJQ=990804011; int n,L,a[N][N],f[N][N][N][N]; char s[N]; int solve(int l,int r,int p,int c) {int &dp=f[l][r][p][c];if(~dp) return dp;if(l>r) return dp=1;if(p>L) return dp=(l==r);if(c>26) return dp=0;dp=solve(l,r,p,c+1);for(int i=l;i<=r;i++)if(a[i][p]==c||(a[i][p]==233&&c))dp=(dp+1ll*solve(l,i,p+1,0)*solve(i+1,r,p,c+1)%XJQ)%XJQ;else break; return dp; } int main() {freopen("b.in","r",stdin);freopen("b.out","w",stdout);scanf("%d",&n);memset(f,-1,sizeof(f));for(int i=1;i<=n;i++){scanf("%s",s+1);int z=0;L=max(L,z=strlen(s+1));for(int j=1;j<=z;j++)a[i][j]=(s[j]=='?'?233:s[j]-'a'+1);}printf("%d",solve(1,n,1,0)); }總結
以上是生活随笔為你收集整理的jzoj6343-[NOIP2019模拟2019.9.7]Medium Counting【记忆化dfs,dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 比亚迪在韩国首次推出 9 米纯电公交 e
- 下一篇: 怎么查上升星座 方法如下