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];
}
};
浙公网安备 33010602011771号