剑指 Offer 13. 机器人的运动范围
分析:
dfs不断搜索,直至访问完所有能够访问的格子。
代码:
class Solution {
private:
int dirs[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
vector<vector<int>> visited;
int count = 0;
public:
int getSum(int x) {
int res = 0;
while(x) {
res += x % 10;
x /= 10;
}
return res;
}
void dfs(int x, int y, int m, int n, int k) {
if(x < 0 || x >= m || y < 0 || y >= n || visited[x][y] || getSum(x) + getSum(y) > k) {
return;
}
count++;
visited[x][y] = 1;
for(int i = 0; i < 4; i++) {
int xx = x + dirs[i][0];
int yy = y + dirs[i][1];
dfs(xx, yy, m, n, k);
}
return;
}
int movingCount(int m, int n, int k) {
visited = vector<vector<int>>(m, vector<int>(n, 0));
dfs(0, 0, m, n, k);
return count;
}
};
剑指 Offer 14- I. 剪绳子
分析:
动态规划:设绳子长度为i时的最大乘积为dp[i]。边界条件:当绳子长度为2时,由于必须剪成2段以上,所以dp[2] = 1 * 1 = 1。当绳子长度为i > 2时,剪掉的长度j范围为[1, i - 2],剪下一段后,剩余部分可以剪也可以不剪,如果不剪则得到的长度乘积为 j * (i - j) 。如果剪得到的长度为j * dp[i - j],两者取最大值。
代码:
class Solution {
public:
int cuttingRope(int n) {
vector<int> dp(n + 1, 0);
dp[2] = 1;
for(int i = 3; i <= n; i++) {
for(int j = 1; j <= i - 2; j++) {
dp[i] = max(dp[i], max(j * (i - j), dp[i - j] * j));
}
}
return dp[n];
}
};