日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

牛客网 【每日一题】5月29日 管道取珠

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客网 【每日一题】5月29日 管道取珠 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

鏈接:

文章目錄

    • 題目描述
    • 題意:
    • 題解:
    • 代碼:

時間限制:C/C++ 2秒,其他語言4秒 空間限制:C/C++ 524288K,其他語言1048576K 64bit IO Format: %lld

題目描述

管道取珠是小X很喜歡的一款游戲。在本題中,我們將考慮該游戲的一個簡單改版。游戲畫面如圖1所示:

游戲初始時,左側上下兩個管道分別有一定數量的小球(有深色球和淺色球兩種類型),而右側輸出管道為空。每一次操作,可以從左側選擇一個管道,并將該管道中最右側的球推入右邊輸出管道。

例如,我們首先從下管道中移一個球到輸出管道中,將得到圖2所示的情況。

假設上管道中有n個球,下管道中有m個球,則整個游戲過程需要進行n+m次操作,即將所有左側管道中的球移入輸出管道。最終n
+m個球在輸出管道中從右到左形成輸出序列。

愛好數學的小X知道,他共有C(n+m, n)種不同的操作方式,而不同的操作方式可能導致相同的輸出序列。舉個例子,對于圖3所示的游戲情形:

我們用A表示淺色球,B表示深色球。并設移動上管道右側球的操作為U,移動下管道右側球的操作為D,則共有C(2+1,1)=3種不同的操作方式,分別為UUD,
UDU, DUU;最終在輸出管道中形成的輸出序列(從右到左)分別為BAB,BBA,BBA。可以發現后兩種操作方式將得到同樣的輸出序列。

假設最終可能產生的不同種類的輸出序列共有K種,其中第i種輸出序列的產生方式(即不同的操作方式數目)有ai個。聰明的小X早已知道,

因此,小X希望計算得到

你能幫助他計算這個值么?由于這個值可能很大,因此只需要輸出該值對1024523的取模即可(即除以1024523的余數)。

說明:文中C(n+m,n)表示組合數。組合數C(a,b)等價于在a個不同的物品中選取b個的選取方案數。

輸入描述:

第一行包含兩個整數n,m,分別表示上下兩個管道中球的數目。

第二行為一個AB字符串,長度為n,表示上管道中從左到右球的類型。其中A表示淺色球,B表示深色球。

第三行為一個AB字符串,長度為m,表示下管道中的情形。

輸出描述:

僅包含一行,即為除以1024523的余數

示例1
輸入

2 1 AB B

輸出

5

題意:

總結下題目意思:
上下兩個管道,上管道有n個球,下管道有m個球,每次在上下取出一個球,球有黑有紅,取出會形成不同的系列,序列數為k,而同一種序列可能有不同取法,第i種序列,取法為a[i],
那會得到:所有取法的式子
問:

題解:

乍一看毫無思路,給了我們ai求和的公式,讓我們求ai2 求和的公式,這咋整。
注意,題目又臭又長給我們設定一個背景,是為了告訴我們所給的式子是具有物理含義的,題目中ai表示第i種序列的取法,ai求和是一個管道系統中所有取法的和。那ai2表示什么?不就表示兩個完全相同的管道系統,獨立取出小球,所得兩個管道系統序列相同的方案數量
這樣能想明白,接下來就好整
dp[k][i][j]表示兩個管道都取了k個球,第一個管道系統的第一個管道(上管道)取了i個球,自然第二個管道(第一個管道系統的下管道)取了k-i個球
同理:第二個管道系統的第一個管道取了j個球,第二個管道取了k-j個球
我們要得到相同序列,就要使得每次兩側取出的球都相同
然后轉移方程可得:
(圖中對四個管道進行標號)

a[]表示上管道球的顏色
b[]表示下管道球的顏色
dp[0][0][0]=1
有四種情況:
上A = = 上B (a[i] = = b[j]) dp [ k ] [ i ] [ j ]+=dp [ k-1 ] [ i - 1 ] [ j - 1 ] (同時在兩個的上管道取一個,這樣取出來就是相同序列)
上A = = 下B (a[i] = = b[k-j])dp[k][i][j]+=dp[k-1][i-1][j] (同時在第一個管道系統的上管道和第二個管道系統的下管道取一個球。第二個管道系統下管道取球,上管道不變,所以還是j)
下A = = 上B(b[k-i] = = a[j])dp[i][j][k]+=dp[k-1][i][j-1]
下A = = 下B (b[k-i] = = b[k-j]) dp[i][j][k]+=dp[k-1][i][j]
(其實就是兩邊管道當相同時自由組合)
我這樣講應該夠仔細了
對了,數組空間會超,所以用滾動數組來優化,降低復雜度

代碼:

狀態壓縮代碼參考

#include <bits/stdc++.h> using namespace std; const int maxn = 500 + 5; const int mod = 1024523; int dp[3][maxn][maxn]; int n, m; char a[maxn], b[maxn];int main() {cin >> n >> m;cin >> a + 1 ;cin >> b + 1;dp[0][0][0] = 1;for(int k = 1; k <= n + m; k++) {memset(dp[k&1], 0, sizeof dp[k&1]);for(int i = 0; i <= n; i++) {if(k - i < 0 || k - i > m) continue;for(int j = 0; j <= n; j++) {if(k - j < 0 || k - j > m) continue;if(i && j && a[i] == a[j])dp[k & 1][i][j]=(dp[k & 1][i][j]+dp[!(k & 1)][i - 1][j - 1])%mod;if(i && k - j && a[i] == b[k - j])dp[k & 1][i][j] =(dp[k & 1][i][j]+ dp[!(k & 1)][i - 1][j])%mod;if(k - i && j && b[k - i] == a[j])dp[k & 1][i][j]=(dp[k & 1][i][j] + dp[!(k & 1)][i][j - 1])%mod;if(k - i && k - j && b[k - i] == b[k-j])dp[k & 1][i][j]=(dp[k & 1][i][j] + dp[!(k & 1)][i][j])%mod;}}}cout << dp[(n + m) & 1][n][n] << endl;return 0; }

總結

以上是生活随笔為你收集整理的牛客网 【每日一题】5月29日 管道取珠的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。