算法(41)-动态规划(0)-字符串交错组成-C++

动态规划一般分四种模型:

1.从左到右,例如背包问题。
2.范围上尝试的,L-R。
3.str1行,str2列,玩二维表,或者对应表。
4.随意试,用分支限界的方法来规定限制条件。

题目:给定三个字符 str1,str2,aim包含且仅包含来自str1,str2的所有字符。
str1="ab",str2="12".那么"AB12","A1B2","A12B","1A2B","1AB2"都是str1 str2的交错组成。
此为经典的动态规划模式。
三个信息点:1.dp意义:dp[i][j] 代表aim[0,i+j-1] 能否被str1[0..i-1] str2[0..j-1]组成。
                      2. aim 长度 m+n
                      3.返回最右下角的值
四个步骤1.dp[0][0] 赋值  aim空时true
                   2.第一赋值 dp[0...col][0]    aim[0..i-1]?=str1[0..i-1]
                   3.第一赋值 dp[0][0...row]   aim[0..j-1]?=str2[0...j-1]
                   4.dp[i][j]
                       4.1上位置+以前str1[i-1]==aim[i+j-1])+(str1[0..i-2],str2[0...j-1],aim[0...i+j-2])
                       4.2左位置+以前  (str2[j-1]==aim[i+j-1])+(str1[0...i-1],str2[0...j-2],aim[0...i+j-2])

上代码:

bool isCross(string str1, string str2, string aim)
{

	int i_max = str1.size();
	int j_max = str2.size();
	if (aim.size() != (i_max + j_max))
	{
		cout << "aim.size() != (i_max + j_max)" << endl;
		return false;
		
	}
	vector<vector<bool> > dp(j_max + 1);// 行 row str2
	for (int i = 0; i < i_max + 1; i++)
	{
		dp[i].resize(i_max + 1);//列  col  str1
	}
	
	   //1.dp[0][0]=true;
	      dp[0][0] = true;
		//2.col列 str1  i j 都是从1开始的
		  for (int i = 1; i <= i_max; i++)
		  {
			 if (str1[i-1]==aim[i-1])
			  {
				  dp[i][0] = true;
			  }
			  else
			  {
				  dp[i][0] = false;
			  }
		  }
		//3.row 行 str2
		  for (int j = 1; j <= j_max; j++)
		  {
			  if (str2[j-1]==aim[j-1])
			  {
				  dp[0][j] = true;
			  }
			  else
			  {
				  dp[0][j] = false;
			  }
		  }
		//4 dp[i][j]  
		//4.1 左dp[i][j-1]
		//4.2 上dp[i-1][j]
		  for (int i = 1; i <=i_max; i++)
		  {
			  for (int j = 1; j <= j_max; j++)
			  {
				  bool topbefore = dp[i - 1][j];
				  bool leftbefore = dp[i][j - 1];
				  bool top = (str1[i - 1] == aim[i + j - 1] ? true : false);
				  bool left = (str2[j - 1] == aim[i + j - 1]?true : false);
				  if ((topbefore==true && top==true)||(leftbefore == true && left == true))
				  {
					  dp[i][j] = true;
				  }
			  }
		  }

		return dp[i_max][j_max];
}


void strArrCross_main()
{
	cout<<"***strArrCross_main**********"<<endl;
	string str1 = "AB";
	string str2 = "12";
	string aim1 = "AB12";
	string aim2 = "A1B2";
	string aim3 = "A12B";
	string aim4 = "1AB2";

	cout << isCross(str1, str2, aim1) << endl;
	cout << isCross(str1, str2, aim2) << endl;
	cout << isCross(str1, str2, aim3) << endl;
	cout << isCross(str1, str2, aim4) << endl;



}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值