hdu 6170 dp
阿新 • • 發佈:2017-08-23
() 動態 clas 題目 color 兩個 nbsp -1 cnblogs
題意:
給出兩個字符串,第一個字符串只包含小寫或者大寫字母,第二個字符串包含小寫或者大寫字母或者特殊字符“.”和“*”,這裏“.”可以替換為任意字符,但是不能變成空。
這裏“a*”可以變成空串,可以變成a,也可以是aa,也可以是aaa,還可以是aaaa.以此類推,不限長度。
問第二個串和第一個串是否能夠完全相等。
題解:
題目給的數據是比較小的,貪心的話數據太小了,直接模擬的話由於”*“的個數可以存在多個 ,有個動態的過程,所以考慮用dp。
對於兩個字符串的dp接觸過一些,最經典的就是公共子序列的問題,這裏定義dp[i][j]為s[0]~s[i]與t[0]~t[j]的匹配情況,0表示不匹配,1表示匹配。
關於狀態轉移方程,比較難處理的還是‘*’的情況。具體解釋看代碼:
ac代碼:
#include <iostream> #include <cstdio> #include <cstring> #include <string> using namespace std; int dp[2501][2501]; int main() { int t; cin>>t; while(t--) { char s[2510],t[2510]; scanf("%s",s+1);// 給空串留一個位置scanf("%s",t+1); memset(dp,0,sizeof(dp)); dp[0][0]=1; // 空串當然為1 // cout<<s<<‘ ‘<<t<<endl; int slen=strlen(s+1); int tlen=strlen(t+1); // cout<<slen<<‘ ‘<<tlen<<endl; for(int i=1;i<=slen;i++) {for(int j=1;j<=tlen;j++) { if(j==2 && t[j]==‘*‘) dp[0][j]=1; // 特殊情況要註意一下 給個樣例 a b*a* 輸出yes if(t[j]==‘.‘) dp[i][j]=dp[i-1][j-1]; else if(t[j]!=‘*‘) { if(s[i]==t[j]) dp[i][j]=dp[i-1][j-1]; } else { dp[i][j]=max(dp[i][j-1],dp[i][j-2]);// dp[i][j-1]為a*表示為a的情況 dp[i][j-2]為a*表示為空的情況· if(dp[i-1][j] && s[i-1]==s[i]) dp[i][j]=1;// 這裏表示a*為2個a以上的情況 } } } if(dp[slen][tlen]) cout<<"yes"<<endl; else cout<<"no"<<endl; } return 0; }
hdu 6170 dp