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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

HDU 5745 La Vie en rose(DP+bitset优化)

發(fā)布時間:2023/12/20 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 5745 La Vie en rose(DP+bitset优化) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

[題目鏈接]

[題意]
給定模式串和主串,模式串可以交換相鄰位子的字符,且可以交換多個位子,但每個字符只能被交換一次。問模式串能否通過該變換與主串匹配?輸出主串中每個位子的匹配結(jié)果,1為可匹配,0為不可匹配。

[分析]
賽上被這道題坑哭了,看到那么多隊過自己卻沒有思路,好不容易想到個方法把樣例過了卻T了。最后走投無路寫了個暴力就A了,1500ms,嚇死。
不過賽后貌似加強了數(shù)據(jù),卡了暴力,喪病。
不過趁機學習了下bitset優(yōu)化的方法,還不錯

dp公式很容易得到
設主串為s,模式串為t,dp[i][j][k]表示主串到i,模式串到j,模式串當前位置的狀態(tài)為k(0:不動,1:與前面交換,2:與后面交換)是否匹配,則:
dp[i][j][0] = (dp[i-1][j-1][0] || dp[i-1][j-1][1] ) && (s[i] == t[j])
dp[i][j][1] = (dp[i-1][j-1][2] ) && ( s[i-1] == t[j] )
dp[i][j][2] = (dp[i-1][j-1][0] || dp[i-1][j-1][1] )&& (s[i+1] == t[j] )

優(yōu)化1:
第二維j實際上只與j-1有關(guān),可以滾動
優(yōu)化2:
所有值都是bool類型,可以用bitset壓位,通過bitset之間的位運算,常數(shù)優(yōu)化

其實聽了這些對不會玩bitset的來說還是一臉懵逼(比如我
所以具體一點吧

bitset<N> dp[2][3] , ch[26] ;

首先需要這些bitset,前者當然是存dp值,2用于滾動,3存三種狀態(tài);后者對應26個字母是否在主串中的某個位子出現(xiàn),比如ch[0][5]表示字母a是否出現(xiàn)在主串中的第5個位子

dp[cur][1] = (dp[cur^1][2] << 1) & ch[t[i-1]-'a'] ;

轉(zhuǎn)移的時候這樣搞,這里只列出了k=1的轉(zhuǎn)移寫法
由于兩個bitset可以直接進行位運算,相當于一次運算直接把1-n的所有dp值全部算出,復雜度卻只有O(n/w)(w是機器的字節(jié)長)
所以預處理每個字符是否在每個位子出現(xiàn),保存在bitset中,就是為了這里的操作
還有一個疑問,為何要<<1?
很簡單,因為i由i-1推得,所以左移1使得對應的位對齊,再運算
這樣寫剛好卡過

[代碼]

#include <bits/stdc++.h> using namespace std ; const int N = 100000 + 5 ; typedef long long LL ;int T , n , m ; char s[N] , t[N] ; bitset<N> dp[2][3] , ch[26] ;int main() {scanf( "%d" , &T ) ;while( T-- ){scanf( "%d%d" , &n , &m ) ;scanf( "%s%s" , s+1 , t+1 ) ;for( int i = 0 ; i < 26 ; i++ )ch[i].reset() ;for( int i = 1 ; i <= n ; i++ )ch[s[i]-'a'].set(i) ;int cur = 0 ;dp[cur][0].set() ;dp[cur][1].reset() ;dp[cur][2].reset() ;for( int i = 1 ; i <= m ; i++ ){cur ^= 1 ;for( int j = 0 ; j < 3 ; j++ )dp[cur][j].reset() ;dp[cur][0] = ((dp[cur^1][0] | dp[cur^1][1]) << 1) & ch[t[i]-'a'] ;if( i > 1 )dp[cur][1] = (dp[cur^1][2] << 1) & ch[t[i-1]-'a'] ;if( i < m )dp[cur][2] = ((dp[cur^1][1] | dp[cur^1][0]) << 1) & ch[t[i+1]-'a'] ;}for( int i = m ; i <= n ; i++ )s[i-m] = '0' + (dp[cur][0][i] | dp[cur][1][i]) ;for( int i = n-m+1 ; i < n ; i++ )s[i] = '0' ;s[n] = 0 ;puts(s) ;}return 0 ; }

總結(jié)

以上是生活随笔為你收集整理的HDU 5745 La Vie en rose(DP+bitset优化)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。