1. 程式人生 > >hdu 6170 dp

hdu 6170 dp

() 動態 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