题目描述:一条街道上共有 n * 2 个地块 ,街道的两侧各有 n 个地块。每一边的地块都按从 1 到 n 编号。每个地块上都可以放置一所房子。现要求街道同一侧不能存在两所房子相邻的情况,请你计算并返回放置房屋的方式数目。由于答案可能很大,需要对 109 + 7 取余后再返回。
方法1:动态规划dp[i]表示n个地块时可放置的房屋数,有两种情况:
第i个地块不放,dp[i-1]种,第i个地块放,dp[i-2]种,dp[i] = dp[i-1]+dp[i-2]
class Solution {
public:
int countHousePlacements(int n) {
vector<int>dp(n+1);
dp[0] = 1;
dp[1] = 2;
int a = 1e9 + 7;
for(int i=2;i<=n;i++){
dp[i] = (dp[i-1] + dp[i-2])%a;
}
return (dp[n] * dp[n])%a;
}
};
出现错误,内存溢出
错误原因,dp[n] * dp[n]这个值可能会溢出,将dp数组设为long int
class Solution {
public:
int countHousePlacements(int n) {
vector<long int>dp(n+1);
dp[0] = 1;
dp[1] = 2;
int a = 1e9 + 7;
for(int i=2;i<=n;i++){
dp[i] = (dp[i-1] + dp[i-2])%a;
}
return (dp[n] * dp[n])%a;
}
};
不用dp数组,记得把s设为long int
class Solution {
public:
int countHousePlacements(int n) {
int p = 1;
int q = 2;
long int s = 2;
int a = 1e9 + 7;
for(int i=1;i<n;i++){
s = (p + q)%a;
p = q;
q = s;
}
return (s * s)%a;
}
};