八皇后问题
int[] result = new int[8];//全局或成员变量,下标表示行,值表示queen存储在哪一列
public void cal8queens(int row) { // 调用方式:cal8queens(0);
if (row == 8) { // 8个棋子都放置好了,打印结果
printQueens(result);
return; // 8行棋子都放好了,已经没法再往下递归了,所以就return
}
for (int column = 0; column < 8; ++column) { // 每一行都有8中放法
if (isOk(row, column)) { // 有些放法不满足要求
result[row] = column; // 第row行的棋子放到了column列
cal8queens(row+1); // 考察下一行
}
}
}
private boolean isOk(int row, int column) {//判断row行column列放置是否合适
int leftup = column - 1, rightup = column + 1;
for (int i = row-1; i >= 0; --i) { // 逐行往上考察每一行
if (result[i] == column) return false; // 第i行的column列有棋子吗?
if (leftup >= 0) { // 考察左上对角线:第i行leftup列有棋子吗?
if (result[i] == leftup) return false;
}
if (rightup < 8) { // 考察右上对角线:第i行rightup列有棋子吗?
if (result[i] == rightup) return false;
}
--leftup; ++rightup;
}
return true;
}
private void printQueens(int[] result) { // 打印出一个二维矩阵
for (int row = 0; row < 8; ++row) {
for (int column = 0; column < 8; ++column) {
if (result[row] == column) System.out.print("Q ");
else System.out.print("* ");
}
System.out.println();
}
System.out.println();
}
0-1 背包问题
/**
* 0-1背包问题--回溯法
* @author ybz
*
*/
class Knapsack {
public static class Element implements Comparable{
int id;//物品编号
double d;
public Element(int id,double d){
this.id=id;
this.d=d;
}
@Override
public int compareTo(Object x) {
double xd=((Element)x).d;//递减顺序排列
if(d<xd) return -1;
if(d==xd) return 0;
return 1;
}
}
double c;//背包容量
int n;//物品数
double[] w;//物品重量数组
double[] p;//物品价值数组
double cw;//当前重量
double cp;//当前价值
double bestp;//最优价值
int[] x;//当前装入背包顺序
int[] bestx;//最优装入背包顺序
Element[] q;//q为单位重量价值数组
public double knapsack(double[] pp,double[] ww,double cc){
//初始化
c=cc;
n=pp.length-1;
cw=0;
cp=0;
bestp=0;
x=new int[n+1];
bestx=new int[n+1];
//q为单位重量价值数组
q=new Element[n+1];
for(int i=0;i<=n;i++){
q[i]=new Element(i,pp[i]/ww[i]);
}
//将个物品依单位重量价值从大到小排列
java.util.Arrays.sort(q);
p=new double[n+1];
w=new double[n+1];
for(int i=1;i<=n;i++){
p[i]=pp[q[i].id];
w[i]=ww[q[i].id];
}
backtrack(1);
return bestp;
}
public void backtrack(int i){
if(i>n){//到达叶子节点
bestp=cp;
for(int j=1;j<=n;j++){//保存最优值对应的包的编号
bestx[j]=x[j];
}
return;
}
if(cw+w[i]<=c){//左子树
x[i]=1;
cw+=w[i];
cp+=p[i];
backtrack(i+1);
cw-=w[i];//恢复现场
cp-=p[i];
}
if(bound(i+1)>bestp){
x[i]=0;
backtrack(i+1);
}
}
public double bound(int i){//上界函数
double cleft=c-cw;
double bound=cp;
while(i<=n&&w[i]<=cleft){
cleft-=w[i];
bound+=p[i];
i++;
}
if(i<=n){
bound+=p[i]*cleft/w[i];
}
return bound;
}
}
public class Pattern {
private boolean matched = false;
private char[] pattern; // 正则表达式
private int plen; // 正则表达式长度
public Pattern(char[] pattern, int plen) {
this.pattern = pattern;
this.plen = plen;
}
public boolean match(char[] text, int tlen) { // 文本串及长度
matched = false;
rmatch(0, 0, text, tlen);
return matched;
}
private void rmatch(int ti, int pj, char[] text, int tlen) {
if (matched) return; // 如果已经匹配了,就不要继续递归了
if (pj == plen) { // 正则表达式到结尾了
if (ti == tlen) matched = true; // 文本串也到结尾了
return;
}
if (pattern[pj] == '*') { // *匹配任意个字符
for (int k = 0; k <= tlen-ti; ++k) {
rmatch(ti+k, pj+1, text, tlen);
}
} else if (pattern[pj] == '?') { // ?匹配0个或者1个字符
rmatch(ti, pj+1, text, tlen);
rmatch(ti+1, pj+1, text, tlen);
} else if (ti < tlen && pattern[pj] == text[ti]) { // 纯字符匹配才行
rmatch(ti+1, pj+1, text, tlen);
}
}
}
杨辉三角
“杨辉三角”不知道你听说过吗?我们现在对它进行一些改造。每个位置的数字可以随意填写,经过某个数字只能到达下面一层相邻的两个数字。假设你站在第一层,往下移动,我们把移动到最底层所经过的所有数字之和,定义为路径的长度。请你编程求出从最高层移动到最底层的最短路径长度。
int[][] matrix = {{5},{7,8},{2,3,4},{4,9,6,1},{2,7,9,4,5}};
public static int yanghuiTriangle(int[][] matrix) {
int minDis = Integer.MAX_VALUE;
int[][] states = new int[matrix.length][matrix.length];
states[0][0] = matrix[0][0];
for (int i = 1; i < matrix.length; i++) {
for (int j = 0; j < matrix[i].length; j++) {
if (j == 0) {
states[i][j] = states[i - 1][j] + matrix[i][j];
} else if (j == matrix[i].length - 1) {
states[i][j] = states[i - 1][j - 1] + matrix[i][j];
} else {
int x1 = states[i - 1][j];
int x2 = states[i - 1][j - 1];
states[i][j] = Math.min(x1, x2) + matrix[i][j];
}
}
}
for (int j = matrix[matrix.length - 1].length-1; j >= 0; j--) {
if (states[matrix.length - 1][j] > 0 && minDis > states[matrix.length - 1][j]) {
minDis = states[matrix.length - 1][j];
}
}
return minDis;
}