简述:
这道题是标准的动态规划题
定义于字母表∑{a,b,c)上的乘法表如表1所示
表1∑乘法表
a b c
a b b a
b c b a
c a c c
依此乘法表,对任一定义于∑上的字符串,适当加括号表达式后得到一个表达式。例如,对于字符串x=bbbba,它的一个加括号表达式为i(b(bb))(ba)。依乘法表,该表达式的值为a。试设计一个动态规划算法,对任一定义于∑上的字符串x=x1x2…xn,计算有多少种不同的加括号方式,使由x导出的加括号表达式的值为a
要求:
输入:输入一个以a,b,c组成的任意一个字符串。
输出:计算出的加括号方式数。
算法描述:
从最小的两个字符的括号开始加起,逐步增加括号内字符的数量,从下至上的动态规划
其实就是从小到大给字符串加括号,大括号的结果依赖于小括号的结果
例如(abc)中(abc)依赖于(ab) * (c) 以及 (a)*(bc)
所以由此看来,大括号的结果就是小括号结果的继续, 其实归到地就是单个字符间的结果,
这也就是循环刚开始的时候,是从连续的两个字符的括号开始的,并逐步向上规约
package dynamic_programming;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class MultiplicationTable {
private static String str = null;
public static void main(String[] args) {
InputStream inputStream = System.in;
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
try{
out: while(true){
System.out.print("Please input a string: ");
if((str = bufferedReader.readLine()).length() == 0){
System.out.println("Empty Input! ");
continue;
}
for(char ch : str.toCharArray()){
if(ch > 'c' || ch < 'a'){
System.out.println("Illegal Input! input among 'a', 'b' or 'c'");
continue out;
}
}
break;
}
}catch(IOException e){
e.printStackTrace();
}
int n = str.length();
int a[][][] = new int[n][n][3];
//intialize the array
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
for(int k = 0; k < 3; k++)
a[i][j][k] = 0;
//get info from the given string
for(int i = 0; i < n; i++)
a[i][i][str.charAt(i) - 'a'] = 1;//here 0:a, 1:b, 2:c
for(int k = 1; k < n; k++) { //the length of a pair of brackets from 1 to n - 1
for(int i = 0; i < n - k; i++) { //the position of the first bracket
int j = i + k;
for(int t = i;t < j;t++) { //t is the position of the second bracket from i to j - 1
a[i][j][0] += a[i][t][2] * a[t+1][j][0] //c * a = a
+ a[i][t][0] * a[t+1][j][2] //a * c = a
+ a[i][t][1] * a[t+1][j][2]; //b * c = a
a[i][j][1] += a[i][t][0] * a[t+1][j][0] //a * a = b
+ a[i][t][0] * a[t+1][j][1] //a * b = b
+ a[i][t][1] * a[t+1][j][1]; //b * b = b
a[i][j][2] += a[i][t][1] * a[t+1][j][0] //b * a = c
+ a[i][t][2] * a[t+1][j][1] //c * b = c
+ a[i][t][2] * a[t+1][j][2]; //c * c = c
}
}
}
// a[0][n-1][0] means the number of methods str[0 to n-1] which equals a
System.out.println("Methods Of Adding Brackets: " + a[0][n-1][0]);
}
}
输出: