题目描述
思路分析
状态机dp
f
[
i
]
[
0
]
:
摆
完
前
i
列
,
且
第
i
列
俩
个
“
横
”
的
方
案
数
;
f[i][0]:摆完前i列,且第i列俩个“横”的方案数;
f[i][0]:摆完前i列,且第i列俩个“横”的方案数;
f
[
i
]
[
1
]
:
摆
完
前
i
列
,
且
第
i
列
摆
一
个
“
竖
“
的
方
案
数
;
f[i][1]:摆完前i列,且第i列摆一个“竖“的方案数;
f[i][1]:摆完前i列,且第i列摆一个“竖“的方案数;
转
移
方
程
为
:
f
[
i
]
[
1
]
=
f
[
i
−
1
]
[
1
]
+
f
[
i
−
1
]
[
0
]
,
f
[
i
]
[
0
]
=
f
[
i
−
2
]
[
0
]
+
f
[
i
−
2
]
[
1
]
;
转移方程为:f[i][1]=f[i-1][1]+f[i-1][0],f[i][0]=f[i-2][0]+f[i-2][1];
转移方程为:f[i][1]=f[i−1][1]+f[i−1][0],f[i][0]=f[i−2][0]+f[i−2][1];
该题扩展到N*M,则要用状态压缩dp。详情搜索”蒙德里安的梦想“。
代码实现
class Solution {
public:
//f[i][1]=f[i-1][1]+f[i-1][0],f[i][0]=f[i-2][0]+f[i-2][1];
int rectCover(int n) {
if(!n) return 0;
if(n==1) return 1;
vector<vector<int>> f(n+1,vector<int>(2));
f[1][0]=0,f[1][1]=1;
f[2][0]=1,f[2][1]=1;
for(int i=3;i<=n;i++){
f[i][1]=f[i-1][1]+f[i-1][0];
f[i][0]=f[i-2][0]+f[i-2][1];
}
return f[n][1]+f[n][0];
}
};