题目地址: http://ac.jobdu.com/problem.php?pid=1547
题目描述:
给定一个初始为空的栈,和n个操作组成的操作序列,每个操作只可能是出栈或者入栈。
要求在操作序列的执行过程中不会出现非法的操作,即不会在空栈时执行出栈操作,同时保证当操作序列完成后,栈恰好为一个空栈。
求符合条件的操作序列种类。
例如,4个操作组成的操作序列符合条件的如下:
入栈,出栈,入栈,出栈
入栈,入栈,出栈,出栈
共2种。
输入:
输入包含多组测试用例,每组测试用例仅包含一个整数n(1<=n<=1000)。
输出:
输出仅一个整数,表示符合条件的序列总数,为了防止总数过多超出int的范围,结果对1000000007取模(mod 1000000007)。
样例输入:
2
4
10
样例输出:
1
2
42
来源:
2014年王道论坛研究生机试练习赛(一)
这个题和Leetcode上的Generate Parentheses,思路参考(LeetCode/Valid Parentheses && Generate Parentheses && Longest Valid Parentheses)有点类似,我觉得某些地方可以参考,所以试了试BFS,超时,不意外。
后来又想想,这个题目好像应该用动态规划,有点像跳台阶。
dp[i][j]表示出栈为i,入栈为j的方法数有多少。
很快就可以得出,dp[i][j] = (dp[i-1][j] + dp[i][j-1]),前提是入栈数要大于出栈,也就是i <= j。
在出栈数为0时,入栈不管为多少,都只有一种方式。
题目描述:
给定一个初始为空的栈,和n个操作组成的操作序列,每个操作只可能是出栈或者入栈。
要求在操作序列的执行过程中不会出现非法的操作,即不会在空栈时执行出栈操作,同时保证当操作序列完成后,栈恰好为一个空栈。
求符合条件的操作序列种类。
例如,4个操作组成的操作序列符合条件的如下:
入栈,出栈,入栈,出栈
入栈,入栈,出栈,出栈
共2种。
输入:
输入包含多组测试用例,每组测试用例仅包含一个整数n(1<=n<=1000)。
输出:
输出仅一个整数,表示符合条件的序列总数,为了防止总数过多超出int的范围,结果对1000000007取模(mod 1000000007)。
样例输入:
2
4
10
样例输出:
1
2
42
来源:
2014年王道论坛研究生机试练习赛(一)
这个题和Leetcode上的Generate Parentheses,思路参考(LeetCode/Valid Parentheses && Generate Parentheses && Longest Valid Parentheses)有点类似,我觉得某些地方可以参考,所以试了试BFS,超时,不意外。
后来又想想,这个题目好像应该用动态规划,有点像跳台阶。
dp[i][j]表示出栈为i,入栈为j的方法数有多少。
很快就可以得出,dp[i][j] = (dp[i-1][j] + dp[i][j-1]),前提是入栈数要大于出栈,也就是i <= j。
在出栈数为0时,入栈不管为多少,都只有一种方式。
Java AC
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
/*
* 1547
*/
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(
new InputStreamReader(System.in)));
while (st.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int)st.nval;
if((n & 1) == 1 || n == 0){
System.out.println(0);
continue;
}
int dp[][] = new int[n][n];
for (int j = 0; j < n; j++) {
dp[0][j] = 1;
}
for (int i = 1; i < n/2+1; i++) {
for (int j = i; j < n/2+1; j++) {
dp[i][j] = (dp[i-1][j] + dp[i][j-1]) % 1000000007;
}
}
System.out.println(dp[n/2][n/2]);
}
}
}
/**************************************************************
Problem: 1547
User: wzqwsrf
Language: Java
Result: Accepted
Time:440 ms
Memory:26932 kb
****************************************************************/
C++ AC
#include <stdio.h>
const int maxn = 502;
const int mod = 1000000007;
int n,i,j;
int main(){
while(scanf("%d",&n) != EOF){
if(n & 1 == 1 || n==0){
printf("0\n");
continue;
}
int dp[maxn][maxn] = {0};
for(j = 0; j <= n/2; j++){
dp[0][j] = 1;
}
for(i = 1; i <= n/2; i++){
for(j = i; j <= n/2; j++){
dp[i][j] = (dp[i-1][j]+dp[i][j-1]) % mod;
}
}
printf("%d\n",dp[n/2][n/2]);
}
return 0;
}
/**************************************************************
Problem: 1547
User: wangzhenqing
Language: C++
Result: Accepted
Time:50 ms
Memory:1936 kb
****************************************************************/
Java BFS 超时
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
public class Main {
/*
* 1547
*/
public static int maxNum;
public static void main(String[] args) throws IOException {
StreamTokenizer st = new StreamTokenizer(new BufferedReader(
new InputStreamReader(System.in)));
while (st.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int)st.nval;
maxNum = 0;
dfs(n/2, 0, 0);
System.out.println(maxNum % 1000000007);
}
}
public static void dfs(int n,int leftNum, int rightNum) {
if (leftNum == n) {
maxNum++;
return;
}
dfs(n, leftNum+1, rightNum);
if (leftNum > rightNum) {
dfs(n, leftNum, rightNum+1);
}
}
}
/**************************************************************
Problem: 1547
User: wzqwsrf
Language: Java
Result: Time Limit Exceed
****************************************************************/