这是一道比CCCC简单题难的简单题
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/262140KB (Java/Others)
Submit Status
集训队的CFT大爷精通Python
有一天,CFT大爷跑在vps上的python爬虫程序挂了
CFT大爷经过缜密的推断,发现程序挂了的原因是Python的垃圾回收机制不够优越,导致内存炸了,那些卖vps的奸商强行杀掉了他的爬虫程序
CFT大爷决定再也不用python这门垃圾语言,他要发明一个新的语言CFTthon
CFT大爷的CFTthon是跑在CFT大爷以前写的CFT_OS上的,在CFT_OS中,内存布局是一个n*m的长方形矩阵,而CFTthon所有的变量,都只占用1*2大小的小长方形内存空间。
CFT大爷在手写CFTthon的GC系统时,想到了一个问题:给定n,m,要求用CFTthon的变量把整个内存空间完全覆盖,不重合不遗漏,有多少种方法呢?
**** 扯淡题意分割线 ****
给定一个n*m的矩阵,使用1*2的小长方形覆盖矩阵,要求完全覆盖的同时不出现重合,也不允许超出边界,问有多少种可能的覆盖方法,方案数对1e9+7取模
2<=n<=1000
3<=m<=5
Input
整数n,m
Output
方案数
Sample input and output
Sample Input Sample Output
2 4 5
Hint
注意取模
Source
Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/262140KB (Java/Others)
Submit Status
集训队的CFT大爷精通Python
有一天,CFT大爷跑在vps上的python爬虫程序挂了
CFT大爷经过缜密的推断,发现程序挂了的原因是Python的垃圾回收机制不够优越,导致内存炸了,那些卖vps的奸商强行杀掉了他的爬虫程序
CFT大爷决定再也不用python这门垃圾语言,他要发明一个新的语言CFTthon
CFT大爷的CFTthon是跑在CFT大爷以前写的CFT_OS上的,在CFT_OS中,内存布局是一个n*m的长方形矩阵,而CFTthon所有的变量,都只占用1*2大小的小长方形内存空间。
CFT大爷在手写CFTthon的GC系统时,想到了一个问题:给定n,m,要求用CFTthon的变量把整个内存空间完全覆盖,不重合不遗漏,有多少种方法呢?
**** 扯淡题意分割线 ****
给定一个n*m的矩阵,使用1*2的小长方形覆盖矩阵,要求完全覆盖的同时不出现重合,也不允许超出边界,问有多少种可能的覆盖方法,方案数对1e9+7取模
2<=n<=1000
3<=m<=5
Input
整数n,m
Output
方案数
Sample input and output
Sample Input Sample Output
2 4 5
Hint
注意取模
Source
2017 UESTC Training for Dynamic Programming
My Solution
状态压缩dp经典例题
hihoCoder 1048 : 状态压缩·二
这里有更好的讲解。
时间复杂度 O(n*m*(1<<m))
空间复杂度 O(2*(1<<m))
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const int MAXN = 5;
const int MOD = 1e9 + 7;
int dp[2][1 << MAXN];
inline int mod(int x)
{
return x - x / MOD * MOD;
}
int main()
{
#ifdef LOCAL
freopen("6.in", "r", stdin);
//freopen("l.out", "w", stdout);
#endif // LOCAL
//ios::sync_with_stdio(false); cin.tie(0);
int n, m, x, i, j, k;
scanf("%d%d", &n, &m);
if(n < m) swap(n, m);
x = 1;
dp[0][(1 << m) - 1] = 1;
for(i = 0; i < n; i++){
for(j = 0; j < m; j++, x ^= 1){
memset(dp[x], 0, sizeof(dp[x]));
for(k = 0; k < (1 << m); k++){
if(k & (1 << (m-1))){
dp[x][(k << 1) ^ (1 << m)] = mod(dp[x][(k << 1) ^ (1 << m)] + dp[x^1][k]);
}
if(i && !(k & (1 << (m-1)))){
dp[x][(k << 1) ^ 1] = mod(dp[x][(k << 1) ^ 1] + dp[x^1][k]);
}
if(j && (k & (1 << (m-1))) && !(k & 1)){
dp[x][(k << 1) ^ (1 << m) ^ 3] = mod(dp[x][(k << 1) ^ (1 << m) ^ 3] + dp[x^1][k]);
}
}
}
}
printf("%d\n", dp[x^1][(1 << m) - 1]);
return 0;
}
Thank you!
------from ProLights