DP BestCoder Round #50 (div.2) 1003 The mook jong
1 /*
2 DP:这题赤裸裸的dp,dp[i][1/0]表示第i块板放木桩和不放木桩的方案数。状态转移方程:
3 dp[i][1] = dp[i-3][1] + dp[i-3][0] + 1; dp[i][0] = dp[i-1][1] + dp[i-1][0];
4 比赛时二维dp写搓了,主要是边界情况的判断出错,比如dp[3][1] = 1,因为第3块放了木桩,其他地方不能再放,dp[3][0]同理
5 解释一下dp[i][1]的三种情况,可能是前面相隔2个放的方案或者是不放的方案,还有唯独在第i块放的方案(1)
6 比赛时瞄了一下样例,感觉有规律,就写出了dp[i] = dp[i-3] + dp[i-1] + 1;(dp[1] = 1; dp[2] = 2; dp[3] = 3;)其实都一样
7 */
8 /************************************************
9 * Author :Running_Time
10 * Created Time :2015-8-9 8:48:32
11 * File Name :C_2.cpp
12 ************************************************/
13
14 #include <cstdio>
15 #include <iostream>
16 #include <algorithm>
17 #include <cstring>
18 #include <string>
19 #include <vector>
20 #include <map>
21 #include <set>
22 #include <queue>
23 #include <cmath>
24 #include <ctime>
25 #include <cstdlib>
26 #include <list>
27
28 #define lson l, mid, rt << 1
29 #define rson mid + 1, r, rt << 1 | 1
30 typedef long long ll;
31 const int MAXN = 66;
32 const int INF = 0x3f3f3f3f;
33 const int MOD = 1e9 + 7;
34 ll dp[MAXN][2];
35
36 void solve(void) {
37 dp[1][1] = 1; dp[1][0] = 0;
38 dp[2][1] = 1; dp[2][0] = 1;
39 dp[3][1] = 1; dp[3][0] = 2;
40 for (int i=4; i<=60; ++i) {
41 dp[i][1] = dp[i-3][1] + dp[i-3][0] + 1;
42 dp[i][0] = dp[i-1][1] + dp[i-1][0];
43 }
44 }
45
46 int main(void) { //BestCoder Round #50 (div.2) 1003 The mook jong
47 solve ();
48 int n;
49 while (scanf ("%d", &n) == 1) {
50 printf ("%I64d\n", dp[n][0] + dp[n][1]);
51 }
52
53 return 0;
54 }
编译人生,运行世界!