hdu5707

类型:字符串处理
思路:水题

#include
#include
using namespace std;
char a1[2005],a2[1005],b1[2005];
int main()  {
  while(gets(a1))  {
    gets(a2);
    gets(b1);
    strcat(a1,a2);
    if(strlen(a1)!=strlen(b1)  cout<<"NO\n";
    else { 
      for(int i=0;i

**

真正的

**
类型:dp
思路:设 dp[i][j] 表示字符串 S3 的前 i + j 位是否可以由字符串 S1 的前 i 位以及字符串 S2 的前 j 位组成. dp[i][j] = 1 表示可以, dp[i][j] = 0 则表示不可以.

则 dp[i][j] 可以由 dp[i - 1][j] 和 dp[i][j - 1] 转移过来.如果 dp[i][j] 由 dp[i - 1][j] 转移而来,那么应该满足:

dp[i - 1][j] 是合法状态( 即 dp[i - 1][j] = 1 ) 且 S1的第 i 个字符必须等于 S3 的第 i + j 个字符.

如果 dp[i][j] 由 dp[i][j - 1] 转移而来, 那么应该满足:

dp[i][j - 1] 是合法状态( 即 dp[i][j - 1] = 1 ) 且 S2 的第 j 个字符必须等于 S3 的第 i + j 个字符.

综上就可以得到状态转移方程:

i == 0 && j == 0 : dp[i][j] = 1; //显然空串可以由两个空串组成,是合法状态. 除此之外其他状态的初始化应该为 0

i != 0 && j == 0 : dp[i][j] = dp[i - 1][j] && S1[i - 1] == S3[i + j - 1] //字符串下标从零开始

i == 0 && j != 0 : dp[i][j] = dp[i][j - 1] && S2[j - 1] == S3[i + j - 1]

i != 0 && j != 0 : dp[i][j] = ( dp[i - 1][j] && S1[i - 1] == S3[i + j - 1] ) || ( dp[i][j] = dp[i][j - 1] && S2[j - 1] == S3[i + j - 1] ) //两者满足其一即可

除此之外, 题目中还要求 S3 必须恰好由 S1 和 S2 组成, 则除满足 dp[ len(S1) ][ len(S2) ] == 1 之外, len(S1) + len(S2) == len(S3) 也应必须成立.

#include 
#include
#include
#include
using namespace std;
 
const int maxn=4000+5;
int dp[maxn][maxn];
 
int main()
{
   string a,b,c;
   while(cin>>a>>b>>c)
   {
       memset(dp,0,sizeof(dp));
       if(c.size()!=b.size()+a.size())
        cout<<"No"<

你可能感兴趣的:(不懂,dp)