GeeksforGeeks Dynamic Programming | Set 37 (Boolean Parenthesization Problem)

题目描述和算法见: http://www.geeksforgeeks.org/dynamic-programming-set-37-boolean-parenthesization-problem/

这里的做法完全一样。动态规划尝试所有的分割点。

#include <iostream>
#include <vector>
using namespace std;

int numways(const vector<char> &symbols, const vector<char> &operators)
{
	vector<std::vector<int> > nwayst(symbols.size(), std::vector<int>(symbols.size(), 0));
	vector<std::vector<int> > nwaysf(symbols.size(), std::vector<int>(symbols.size(), 0));

	for (int i = 0; i < symbols.size(); ++i)
	{
		if (symbols[i] == 'T')
		{
			nwayst[i][i] = 1;
		}
		else
		{
			nwaysf[i][i] = 1;	
		}
	}

	for (int len = 1; len < symbols.size(); ++len)
	{
		for (int i = 0; i + len < symbols.size(); ++i)
		{
			int j = i + len;
			for (int k = i; k < j; ++k)
			{
				// (i, k), (k + 1, j)
				if (operators[k] == '&')
				{
					nwayst[i][j] += nwayst[i][k] * nwayst[k + 1][j];
					nwaysf[i][j] += nwaysf[i][k] * nwayst[k + 1][j] + nwayst[i][k] * nwaysf[k + 1][j] + nwaysf[i][k] * nwaysf[k + 1][j];
				}
				else if (operators[k] == '|')
				{
					nwayst[i][j] += nwayst[i][k] * nwaysf[k + 1][j] + nwaysf[i][k] * nwayst[k + 1][j] + nwayst[i][k] * nwayst[k + 1][j];
					nwaysf[i][j] += nwaysf[i][k] * nwaysf[k + 1][j];
				}
				else if (operators[k] == '^')
				{
					nwayst[i][j] += nwayst[i][k] * nwaysf[k + 1][j] + nwaysf[i][k] * nwayst[k + 1][j];
					nwaysf[i][j] += nwayst[i][k] * nwayst[k + 1][j] + nwaysf[i][k] * nwaysf[k + 1][j];
				}
			}
		}
	}

	return nwayst[0][symbols.size() - 1];
}

int main()
{
	std::vector<char> symbols, operators;
	//2
	// symbols.push_back('T');
	// symbols.push_back('F');
	// symbols.push_back('T');
	// operators.push_back('^');
	// operators.push_back('&');

	// 2
	// symbols.push_back('T');
	// symbols.push_back('F');
	// symbols.push_back('F');
	// operators.push_back('^');
	// operators.push_back('|');

	// 4
	symbols.push_back('T');
	symbols.push_back('T');
	symbols.push_back('F');
	symbols.push_back('T');
	operators.push_back('|');
	operators.push_back('&');
	operators.push_back('^');
	cout<<numways(symbols, operators)<<endl;
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值