2017 Multi-University Training Contest - Team 4 :Wavel Sequence
題目鏈接
題目翻譯:
給出長度為n的序列a,
給出長度為m的序列b.
挑選一些下標f,
挑選一些下表g,
并且這兩組下標都是升序排列的。
然后在選出Af == Bg,這些數,組成題目中所要求的波浪,求組成符合題目要求的波浪的序列數,最后答案模上一個數。
題目波浪的形式是:波谷,波峰,波谷,波峰。。。。。。所以波浪開頭必須要是波谷。
動態規劃題目,我的動態規律狠狠狠渣,現在還是個迷糊蛋。
設置dp[i][j][2].
dp[i][j][0]?以a[i],b[i]為結尾且作為波谷的方案數。
dp[i][j][1]?以a[i],b[i]為結尾且作為波峰的方案數。
由于每次可以固定序列a中的一個數,然后遍歷整個b,序列,因此可以把三維的dp優化成二維,
dp[j][2].?因為a[i]每次固定,則二維dp已經默認第一維就是a[i].
sum[j][0]代表以a[i],b[i]為結尾的且作為波谷的方案的總數。
sum[j][1]代表以a[i],b[i]為結尾的且作為波峰的方案的總數。
固定當前a[i]。與序列中的各個值比較。
如果a[i] == b[j] ,則,把a[i]作為波峰,波谷的方案數直接給dp[j][1]和dp[j][0],就可以了。這些方案數是由下面
的操作統計而來的。
如果a[i] > b[j]。因為固定a[i]的時候,我們是從a數組從前往后遍歷的,那么a數組中的前i-1個數,已經
完成了與b數組中各個數字的比較,只要前數組a中前i-1個有與b[j]相等的數,假如這個數為a[k] {1<=k<i},
則一定已經存在以a[k],b[j]為結尾作為波峰和波谷的方案了,由于當前a[i]>b[j],則a[i]對于b[j]來說,只能
做波峰,繼續往后比較如果存在b[t]==a[i] (j<t<=m),那么a[i]就可以加在b[j]作為波谷結尾的后面,做波峰,
則,a[i]做波峰的方案數,就應該在加上b[j]做為波谷的方案數。
同理a[i] < b[j]的時候,a[i]就可以做為波谷,則a[i]左為波谷的方案數,需要加上b[j]作為波峰結尾的方案數。
AC代碼:
#include <iostream> #include <stdio.h> #include <string.h>using namespace std;const int mod = 998244353; const int maxn = 2010; int sa[maxn]; ///序列a int sb[maxn]; ///序列b int dp[maxn][2]; ///dp[i][j][0]代表以a[i],b[j]為結尾,作為波谷的方案數,dp[i][j][1]代表以a[i],b[j]為結尾,作為波峰的方案數。 ///因為可以每次固定a[i],然后遍歷b數組,這樣的話,就自動默認第一維,可以把上面的數組變成二維的。 int sum[maxn][2]; ///sum[i][j][0]代表當前以a[i],b[j]結尾作為波谷的總方案數,sum[i][j][1]代表當前以a[i],b[j]結尾作為波峰的總方案數 int main() {int t,n,m;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i = 1; i <= n; i++)scanf("%d",&sa[i]);for(int i = 1; i <= m; i++)scanf("%d",&sb[i]);memset(dp,0,sizeof(dp));memset(sum,0,sizeof(sum));long long ans = 0;for(int i = 1; i <= n; i++){int waveBottom = 1,waveTop = 0;/**wavebottom為波谷,wavetop為波峰,由于題目說了波浪是從波谷開始的,所以只要單獨的一列序列是一定能做波谷的,所以波谷初始化1.**/for(int j = 1; j <= m; j++) ///每次固定sa[i],遍歷sequence b。{dp[j][0] = dp[j][1] = 0;if(sa[i]==sb[j]) ///兩個序列的相同的數值,才能做波峰和波谷{dp[j][0] = waveBottom;dp[j][1] = waveTop;ans = (ans + waveBottom + waveTop)%mod;}else if(sa[i]<sb[j]){waveBottom = (waveBottom + sum[j][1])%mod;}else ///sa[i]>sb[j],sa[i]可以作為以sb[j]為波谷結尾的序列的波峰{waveTop = (waveTop + sum[j][0])%mod;}}///更新以a[i],b[j]作為波峰波谷結尾的總方案數for(int j = 1; j <= m; j++){if(sa[i] == sb[j]){sum[j][0] = (sum[j][0] + dp[j][0])%mod;sum[j][1] = (sum[j][1] + dp[j][1])%mod;}}}printf("%lld\n",ans);}return 0; }
總結
以上是生活随笔為你收集整理的2017 Multi-University Training Contest - Team 4 :Wavel Sequence的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图文结合带你搞懂InnoDB MVCC
- 下一篇: 15条技巧提高你的写作技巧