算法题

八皇后问题


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;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值