题意:给出一串数字字符(长度在[2, 15]),现要在其中加一个 "=",不加或加一些 "+",问成立的等式有多少条?
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4403
——>>数据量较小,暴力吧。。
1、dp预处理出任意两个字符间的数值大小
2、枚举 = 的位置,分别对 = 的左边、右边各dfs一次,并记录各个数出现的次数
3、根据乘法原理求组合数
#include <cstdio>
#include <cstring>
#include <map>
using std::map;
const int MAXN = 15 + 10;
char s[MAXN];
int len;
int num[MAXN][MAXN];
map<int, int> mpLeft;
map<int, int> mpRight;
void Init()
{
len = strlen(s);
for (int i = 0; i < len; ++i)
{
for (int j = 0; j < len; ++j)
{
num[i][j] = j == i ? s[i] - '0' : num[i][j - 1] * 10 + s[j] - '0';
}
}
}
void Dfs(int cur, int goal, int sum, map<int, int>& mp)
{
if (cur == goal)
{
++mp[sum];
return;
}
for (int i = cur; i < goal; ++i)
{
Dfs(i + 1, goal, sum + num[cur][i], mp);
}
}
void Solve()
{
int ret = 0;
for (int i = 1; i < len; ++i)
{
mpLeft.clear();
mpRight.clear();
Dfs(0, i, 0, mpLeft);
Dfs(i, len, 0, mpRight);
for (map<int, int>::const_iterator iter = mpLeft.begin(); iter != mpLeft.end(); ++iter)
{
if (mpRight.find(iter->first) != mpRight.end())
{
ret += iter->second * mpRight[iter->first];
}
}
}
printf("%d\n", ret);
}
int main()
{
while (scanf("%s", s) == 1)
{
if (strcmp(s, "END") == 0) break;
Init();
Solve();
}
return 0;
}