现在的位置: 首页 > 综合 > 正文

hdu – 4403 – A very hard Aoshu problem(dp + dfs + map + 乘法原理)

2019年08月28日 ⁄ 综合 ⁄ 共 992字 ⁄ 字号 评论关闭

题意:给出一串数字字符(长度在[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;
}

抱歉!评论已关闭.