捕鱼问题的java实现

来源:互联网 发布:手机怎么发布淘宝宝贝 编辑:程序博客网 时间:2024/05/10 05:43

今天看到了一个捕鱼问题,觉得很不错,自己也跟着琢磨了半天,写了java的实现程序,现把问题叙述如下:

题目:20个桶,每个桶中有10条鱼,用网从每个桶中抓鱼,每次可以抓住的条数随机,每个桶只能抓一次,问一共抓到180条的排列有多少种 (也可求概率)

分析:1.我们要在20个桶中一共抓取180条鱼,每个桶能抓到鱼的条数为0-10,仔细想下,这个问题是可以分解成子问题的:假设我们在前i个桶中抓取了k(0<=k<=10*i)条鱼,那么抓取180条鱼的排列种数就等于在剩下的(20-i)个桶中抓取(180-k)条鱼的方法加上前i个桶中抓取k条鱼的方法。

2.换个思维,在实现上这个题目可以有更为简洁的方法,我们看看这个问题的对偶问题,抓取了180条鱼之后,20个桶中剩下了20条鱼,不同的抓取的方法就对应着这些鱼在20个桶中不同的分布,于是问题转化为将20条鱼分到20个桶中有多少中不同的排列方法(这个问题当然也等价于180条鱼分到20个桶中有多少种不同的方法)?其中,每个桶最多放10条,最少放0条。这样一转化,无论是用搜索还是DP,问题规模都缩小了很大一块。

java代码实现:

import java.util.Scanner;public class fishing {        static Scanner obj; static int [][]dp=new int[21][200];int i,j,k;   public static void main(String []args){ int bucketN, fishN; obj = new Scanner(System.in); bucketN = obj.nextInt(); fishN = obj.nextInt();      for(int i = 0; i <= 10; ++i)  /* 初始化合法状态 */        {            dp[1][i] = 1;        }        for(int i = 2; i <= bucketN; ++i)  /* 从第二个桶开始 */        {            for(int j = 0; j <= fishN; ++j)            {                for(int k = 0; k <= 10 && j-k >= 0; ++k)                {                    dp[i][j] += dp[i-1][j-k];                }            }        }  System.out.println(dp[bucketN][fishN]);   }}
输入 两个值即可

总结:要把问题不断化为小问题去解决,即分治法,亦或从对立的角度去思考问题

出现的问题总结:1.二维数组初始化尽量用int [][] array = new int [10][10];

                                2.利用scanner类实现输入(以前没这方面的研究...好水,)利用nextInt()方法获取输入数值,或者可以利用字符流输入,利用split方法截取输入的参数

文章参考:http://www.ahathinking.com/archives/112.html

0 0
原创粉丝点击