九度oj 1547

题目描述:

给定一个初始为空的栈,和n个操作组成的操作序列,每个操作只可能是出栈或者入栈。
要求在操作序列的执行过程中不会出现非法的操作,即不会在空栈时执行出栈操作,同时保证当操作序列完成后,栈恰好为一个空栈。
求符合条件的操作序列种类。
例如,4个操作组成的操作序列符合条件的如下:
入栈,出栈,入栈,出栈
入栈,入栈,出栈,出栈
共2种。

输入:

输入包含多组测试用例,每组测试用例仅包含一个整数n(1<=n<=1000)。

输出:

输出仅一个整数,表示符合条件的序列总数,为了防止总数过多超出int的范围,结果对1000000007取模(mod 1000000007)。

样例输入:
2
4
10
样例输出:
1
2
42
 1 /*i = 3; j = 1
 2 111 0
 3 110 1
 4 101 1
 5 
 6 i = 2; j = 1
 7 110
 8 101
 9 
10 i = 3 j = 0
11 111
12 3 3 = 2 3 + 3 2
13 i = 3; j = 2
14 1110 0
15 1101 0
16 1011 0
17 1100 1
18 1010 1
19 
20 i = 2; j = 2
21 1100
22 1010
23  
24 i = 3; j = 1
25 1110
26 1101
27 1011
28 */
29 /*
30 状态dp[i][j](i >= j)表示入栈i次出栈j次的种类数
31 
32 状态转移方程:dp[i][j] = dp[i-1][j] + dp[i][j-1]
             最后一个是入栈 最后一个是出栈
33 */ 34 #include <cstdio> 35 #include <cstdlib> 36 #define MAX 1002 37 38 int dp[MAX][MAX]; 39 int top(int n) { 40 int temp = n/2; 41 if(temp *2 == n) { 42 return temp; 43 } 44 return temp + 1; 45 } 46 int main(int argc, char const *argv[]) 47 { 48 int n; 49 for(int i = 0; i < 502; i++) { 50 dp[i][0] = 1; 51 dp[0][i] = 0; 52 } 53 for(int i = 1; i <= 502; i++) { 54 for(int j = 1; j <= 502; j++) { 55 if(i >= j) { 56 dp[i][j] = (dp[i-1][j] + dp[i][j-1])%1000000007; 57 } 58 else { 59 dp[i][j] = 0; 60 } 61 } 62 } 63 while(scanf("%d",&n) != EOF) { 64 if(n & 1) { 65 printf("%d\n",0); 66 } 67 else { 68 printf("%d\n",dp[n/2][n/2]); 69 } 70 71 72 } 73 return 0; 74 } 75

 

  这道题一开始完全没有思路,最重要的是得出状态转移方程,利用动态规划求解。

  另外,while(scanf("%d",&n))会导致结果output limit exceed

  要写成 while(scanf("%d",&n) != EOF)

  还有,题目说“同时保证当操作序列完成后,栈恰好为一个空栈”不是说它的输入保证这一点,而是如果有这样的输入,答案是0,也就是如果输入时奇数,答案是0

posted @ 2016-07-16 12:06  Jason杰  阅读(215)  评论(0编辑  收藏  举报