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 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\n", ans); 46 } 47 48 return 0; 49 }