650. 2 Keys Keyboard &651. 4 Keys Keyboard

在这里插入图片描述

这一题的要求是“恰好最后有n个”,所以这一题关键就是恰好。
思路这样:
对于一个目标,我们找它最大的因子,然后它就应该由它的因子得来。然后同样的步骤处理这个因子,直到1.

class Solution {
public:
    int minSteps(int n) {
        if (n <= 0)
            return 0;
        if (n == 1)
            return 0;
        int retCnt = 0;
        while (n > 1) {
            int maxFac = getMaxFac(n);
            retCnt += (n / maxFac);
            n = maxFac;
        }
        return retCnt;
    }
private:
    int getMaxFac(int n) {
        int num = n / 2;
        while (num > 1) {
            if (n % num == 0)
                return num;
            --num;
        }
        return 1;
    }
};

在这里插入图片描述

class Solution {
public:
    int maxA(int N) {
        vector<int> dp(N+1, 0);
        for (int i = 1; i <= N; ++i) {
            //第i步执行了key1
            dp[i] = dp[i-1] + 1;
            //第i步执行了key4
            for (int j = 2; j + 1 < i; ++j)//假设在j步执行了选中(key2),后面一直到i都是粘贴
                dp[i] = max(dp[i], dp[j-1]*(i-j));//注意是i-j
        }
        return dp[N];
    }
};
//好暴力啊
//把所有可能的情况都表示出来了
//可能是打印一个
//也可能是执行了复制,那么从哪儿开始复制好呢?假设把所有可能开始执行选中复制的位置都实验一遍。

其中i-j的原因而不是i-j-i的原因是除去复制的那一部分,还是开始本来就有的那一部分呢?
这里是暴力解法,下面是更加精细的解法

还有答案是:

class Solution {
public:
    int maxA(int N) {
        if (N <= 5)
            return N;
        return max(3 * maxA(N-4), 4 * maxA(N-5));
    }
};

需要仔细的思考一下为什么这样是对的。(为什么没有2maxA(N-3) 和 5maxA(N-6))
如果不确定,可以把2*maxA(N-3)加上。
时间复杂度是O(2^n),考虑提高:

class Solution {
public:
    int maxA(int N) {
        if (N <= 5)
            return N;
        vector<int> dp(N+1, 0);
        for (int i = 0; i <= 5; ++i)
            dp[i] = i;
        for (int i = 6; i <= N; ++i)
            dp[i] = max(2 * dp[i-3], max(3 * dp[i-4], 4 * dp[i-5]));
        return dp[N];
    }
};
posted @ 2019-09-26 16:35  于老师的父亲王老爷子  阅读(11)  评论(0)    收藏  举报