【练习题】 青蛙回家问题

package datastruct;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class DPTest {

 //动态规划练习题
 public static void main(String[] args) {
  
  //青蛙回家问题
  frogBackHome();

 }
 
 //青蛙可以一次跳一步二步三步,它不喜欢碰石子,石子在某几点上(会列出N点有石子)问要怎么以碰到最少的石子为代价家对岸
 private static void frogBackHome(){
  
  /*解:
   如果i的位置上有石子
   DP[i] = Min(DP[i-1],DP[i-2],DP[i-3]) + 1
   如果i的位置上没有石子
   DP[i] = Min(DP[i-1],DP[i-2],DP[i-3])
   应该就搞定了,O(n)的
  */

  int[] stone = {0,0,1,1,0,0,1,0,1,0,0};
  int bu = 10;
  int ge = 10;
  int maxBu = 3;
  int[][] matrix = new int[bu+1][ge+1];
  String[][] path = new String[bu+1][ge+1];
  for(int i = 0 ; i < bu + 1 ; i++){
   matrix[i][0] = i==0?0:10000;
   path[i][0]="0,0";
  }
  for(int j = 0 ; j < ge + 1 ; j++){
   matrix[0][j] = 0;
   path[0][j]="0,0";
  }
  for(int i = 1 ; i < bu + 1 ; i++){
   for(int j = 1 ; j < ge + 1 ; j++){
    int limit = 0;
    if(ge+1 > maxBu * i){
     limit = maxBu * i + 1;
    }else{
     limit = ge + 1;
    }
    if(i <= j && j < limit){
     int val1 = 0;
     int val2 = 0;
     int val3 = 0;
     Label label1 = new Label();
     if(j-3 < 1){
      val1 = 10000; 
      label1.setV(val1);
     }else{
      val1 = matrix[i-1][j-3];
      label1.setV(val1);
     }
     label1.setI(i-1);
     label1.setJ(j-3<1?0:j-3);
     Label label2 = new Label();
     if(j-2 < 1){
      val2 = 10000;
      label2.setV(val2);
     }else{
      val2 = matrix[i-1][j-2];
      label2.setV(val2);
     }
     label2.setI(i-1);
     label2.setJ(j-2<1?0:j-2);
     Label label3 = new Label();
     if(j-1 < 1){
      val3 = 10000;
      label3.setV(val3);
     }else{
      val3 = matrix[i-1][j-1];
      label3.setV(val3);
     }
     label3.setI(i-1);
     label3.setJ(j-1<1?0:j-1);
     if(stone[j] == 1){
      Label l =  min(label1,
        label2,
        label3);
      if(l != null ){
       if(l.i > 0 && l.j > 0)
        path[i][j]=l.i+","+l.j;
       matrix[i][j] = l.getV()+1;
      }else{
       path[i][j]=null;
       matrix[i][j] = 0;
      }
     }else{
      Label l =  min(label1,
        label2,
        label3);
      if(l != null){
       if(l.i > 0 && l.j > 0)
        path[i][j]=l.i+","+l.j;
       matrix[i][j] = l.getV();
      }else{
       path[i][j]=null;
       matrix[i][j] = 0;
      }
     }
    }else
     matrix[i][j]=10000;
   }
  }
  System.out.println("----------------青蛙跳步矩阵------------------------");
  for(int i = 0 ; i < bu + 1 ; i++){
   for(int j = 0 ; j < ge + 1 ; j++){
    System.out.print(matrix[i][j] +"\t");
   }
   System.out.println();
  }
  System.out.println("----------------青蛙位置矩阵------------------------");
  for(int i = 0 ; i < bu + 1 ; i++){
   for(int j = 0 ; j < ge + 1 ; j++){
    System.out.print(path[i][j] +"\t");
   }
   System.out.println();
  }
  System.out.println("----------------可能的最优结果------------------------");
  
 }
 
 private static Label min(Label i,Label j, Label k){
  
  List<Label> list = new ArrayList<Label>();
  if(i.v != 10000){
   list.add(i);
  }
  if(j.v != 10000){
   list.add(j);
  }
  if(k.v != 10000){
   list.add(k);
  }
  Collections.sort(list,new Comparator<Label>(){
   @Override
   public int compare(Label o1, Label o2) {
    
    if((o1.v) > o2.v){
     return 1;
    }
    return -1;
   }
  });
  return list.size() > 0 ? list.get(0) : null;
 }
 
 static class Label{
  
  private int i;
  private int j;
  private int v;
  public int getI() {
   return i;
  }
  public void setI(int i) {
   this.i = i;
  }
  public int getJ() {
   return j;
  }
  public void setJ(int j) {
   this.j = j;
  }
  public int getV() {
   return v;
  }
  public void setV(int v) {
   this.v = v;
  }
 }

}

 

转载于:https://www.cnblogs.com/lixusign/p/3160384.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
青蛙回家吃虫子问题是一个经典的贪心算法问题问题描述如下: 青蛙在一条数轴上,它要从起点跳到终点,途中有一些虫子,青蛙可以选择吃或不吃。每个虫子有一个位置和一个价值,青蛙在这个位置吃掉虫子可以获得这个虫子的价值。青蛙每次跳的距离不能超过它当前位置到终点的距离,即青蛙不能跳过终点。现在给定虫子的位置和价值,青蛙在起点,请问青蛙最多能获得多少价值? 这个问题可以用贪心算法来解决。贪心算法的思想是每次选择最优的局部解,最终得到全局最优解。 具体的贪心策略是:首先将所有虫子按照位置从小到大排序,然后依次考虑每个虫子。如果青蛙当前位置能够到达这个虫子,那么就吃掉这个虫子,否则就跳过这个虫子。因为青蛙每次跳的距离不能超过它当前位置到终点的距离,所以这个贪心策略是正确的。 下面是 Python 代码实现: ```python def max_value(pos, val, n, end): # pos: 虫子的位置 # val: 虫子的价值 # n: 虫子的数量 # end: 终点的位置 bugs = list(zip(pos, val)) bugs.sort() # 按照位置从小到大排序 cur_pos, ans = 0, 0 for i in range(n): if bugs[i][0] > cur_pos + end: # 跳过这个虫子 continue if bugs[i][0] > cur_pos: # 能够到达这个虫子 ans += bugs[i][1] cur_pos = bugs[i][0] if cur_pos >= end: # 到达终点 break return ans ``` 该算法的时间复杂度为 $O(n\log n)$,其中 $n$ 是虫子的数量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值