题目传送门
1 /*
2 题意:给n块砖头,问能组成多少个楼梯,楼梯至少两层,且每层至少一块砖头,层与层之间数目不能相等!
3 递推DP:dp[i][j] 表示总共i块砖头,最后一列的砖头数是j块的方案数
4 状态转移方程:dp[i][j] += dp[i-j][k] 表示最后一列是j,那么上一个状态是少了最后一列
5 总共i-j块砖头,倒数第二列是k块砖头。k<j, j<=i
6 最后累加dp[n][i], i<n因为最少要两层
7 dp[0][0] = 1;
8 还有更简单的做法,没看懂:http://m.blog.csdn.net/blog/jyysc2010/9917439
9 */
10 #include <cstdio>
11 #include <algorithm>
12 #include <cmath>
13 #include <cstring>
14 #include <string>
15 using namespace std;
16
17 const int MAXN = 5e2 + 10;
18 const int INF = 0x3f3f3f3f;
19 long long dp[MAXN][MAXN];
20 long long ans;
21
22 int main(void) //URAL 1017 Staircases
23 {
24 //freopen ("J.in", "r", stdin);
25
26 int n;
27 while (scanf ("%d", &n) == 1)
28 {
29 memset (dp, 0, sizeof (dp));
30
31 dp[0][0] = 1;
32 for (int i=1; i<=n; ++i)
33 {
34 for (int j=0; j<=i; ++j)
35 {
36 for (int k=0; k<j; ++k)
37 {
38 dp[i][j] += dp[i-j][k];
39 }
40 }
41 }
42
43 ans = 0;
44 for (int i=0; i<n; ++i) ans += dp[n][i];
45 printf ("%I64d
", ans);
46 }
47
48 return 0;
49 }