Leetcode 279 完全平方数 (动态规划)

这道题尝试了dfs,bfs,dp

dfs超时了

 

这道题类似于背包问题

物品:完全平方数,每种都有无数个

包的容积:n

目标:恰好把包放满时,物品的个数最少

 

这道题如果暴力的话,应该使用bfs,而不是dfs,类似于求最短路径,最快走到出口的就是最优解

 

使用dp的重点在于递推式,看了大佬(leetcode用户Liture)的题解

f(i)=1+min{f(i-1*1),f(i-2*2),...,f(i-k*k)} k为小于i的最大完全平方数

 

class Solution {
public:
    int numSquares(int n) {
        vector<int> f(n + 1, 0);
        for (int i = 1;i <= n;i++) {
            int m = n + 1;
            for (int j = 1;j*j <= i;j++) {
                if (f[i - j*j] < m)m = f[i - j*j];
            }
            f[i] = m + 1;
        }
        return f[n];
    }
};

 

bfs代码

class Solution {
public:
    vector<int> squ;
    int getSqu(int rest , int e) {
        for (int i = e;i >= 0;i--) {
            if (squ[i] <= rest)return i;
        }
        return 0;
    }
    int ans = (1 << 30) - 1;
    struct sta {
        int rest;
        int msqu;
        int co = 0;
        sta(int r, int m, int c) :rest(r), msqu(m), co(c) {}
    };
    queue<sta> Q;
    void bfs(int n) {
        vector<bool>vis(n + 1, false);
        sta ini(n, squ.size() - 1, 0);
        Q.push(ini);
        while (!Q.empty()) {
            sta cur = Q.front();
            Q.pop();
            if (cur.rest == 0) {
                ans = cur.co;
                break;
            }
            int msqu = getSqu(cur.rest, cur.msqu);
            for (int i = msqu;i >= 0;i--) {
                if (!vis[cur.rest - squ[i]]) {
                    sta next(cur.rest - squ[i], msqu, cur.co + 1);
                    Q.push(next);
                    vis[cur.rest - squ[i]] = true;
                }
            }
        }
    }
    int numSquares(int n) {
        for (int i = 1;i*i <= n;i++) {
            squ.push_back(i*i);
        }
        bfs(n);
        return ans;
    }
};

 

posted @ 2019-06-21 11:07  suuusu  阅读(587)  评论(0)    收藏  举报