【算法题】寻找最少完全平方数

来源:互联网 发布:adobe杀人软件 编辑:程序博客网 时间:2024/04/30 02:20

问题:

给出一个正整数n,寻找最少的完全平方数,使他们的和为n
完全平方数:1,4,9,16 …
12 = 4+4+4
13 = 4+9

解法一:动态规划

状态转移方程:F(n) = min{ F(n-ai) + 1 } 其中ai为小于等于n的完全平方数

int a[100005];int func(int n){    if (n <= 0)        return -1;    for (auto i = 1; i <= n;++i)    {        a[i] = 99999;    }    int min_tmp;    int tmp;    for (auto i = 1; i <= n;++i)    {        min_tmp = 99999;        for (auto j = 1; j*j <= i;++j)        {            tmp = a[i - j*j] + 1;            if (tmp<min_tmp)            {                min_tmp = tmp;            }        }        a[i] = min_tmp;    }    return a[n];}

解法二:最短路径算法

问题转化为搜索节点n到节点0的最短路径,当两个节点差值为完全平方数时,节点间存在一条路径,路径长度均为1。

int BFSfunc(int n){    if (n<=0)        return -1;    queue<pair<int, int>> q;    q.push(make_pair(n, 0));    while (!q.empty())    {        int num = q.front().first;        int step = q.front().second;        q.pop();        if (num == 0)        {            return step;        }        for (auto i = 1; i*i <= num;++i)        {            q.push(make_pair(num - i*i, step + 1));        }    }    return -1;}

改进:使用记录表,避免重复的入队

int BFSfunc(int n){    if (n<=0)        return -1;    queue<pair<int, int>> q;    q.push(make_pair(n, 0));    vector<char> visited(n+1, 0);    visited[n] = 1;    int tmp;    while (!q.empty())    {        int num = q.front().first;        int step = q.front().second;        q.pop();        if (num == 0)        {            return step;        }        for (auto i = 1; i*i <= num;++i)        {            tmp = num - i*i;            if (visited[tmp])            {                continue;            }            q.push(make_pair( tmp, step + 1));            visited[tmp] = 1;        }    }    return -1;}
原创粉丝点击