兔子繁衍问题
问题概述
在一个荒岛,一个猎人带去了一对刚出生的兔子(一公一母),兔子年龄为n,当兔子年龄大于2岁时每年会生下一对兔子,直到死去的前一年,每年末,当岛上兔子大于10对时,猎人会带走年龄最大的两对兔子,求y年后岛上兔子年龄总和,这里为简便记,只求最终的兔子总对数。
问题思路
采用动态规划的思想,但是又不是个动态规划的问题,即 状态变量+状态转移方程 这里,状态变量可表示为一个数组rabbit[n+1],数组下标表示年龄,对应的值表示该年龄对应的兔子总数。rabbit[0]表示刚出生的兔子总数;
解决问题过程
(1)建立基本框架
public
static void main(String args[])
{ //每过一年,兔子的年龄增长一岁,导致年龄为x的兔子对数挪到年龄为x+1的位置;
//兔子年龄达到最大值后会死去,即tuziSet[n]清零;
//兔子年龄在【3,n-1)之间的兔子,每一对兔子每年繁殖一对兔子;
//兔子对数大于10时,猎人会带走年龄最大的两对兔子;
}
(2)年龄增长
每过一年,从年龄大的往小的遍历,依次把值进行交换,模拟出兔子年龄增长
期间要判断观察年份和兔子最大年份,分别进行处理。
(3)最大年龄死去
每过一年,把年龄最大的数量变为0,rabbit[maxage]=0
(4)兔子繁衍
兔子年龄在【3,n-1)之间的兔子,每一对兔子每年繁殖一对兔子;就是每一年都要统计年龄3-maxage的数量,即计算rabbit[3]-rabbit[maxge] 的值。
然后每一对兔子每年繁殖一对兔子,
则rabbit[0]=rabbit[3]+···+rabbit[maxage]
(5)兔子的捕走
兔子对数大于10时,猎人会带走年龄最大的两对兔子;
先统计所有的兔子数量,如果兔子数量大于10,在下一年去除年龄最大的两只
去除两只兔子
设一个变量为hunt=0;
从年龄大到下进行遍历,没当捕走一只后,hunt-1;当hunt=0时跳出循环。
兔子最大年龄的数量不确定,当是0,1,2或大于2时分类处理。
(6)输出兔子年龄情况
每过一年,把数组遍历输出一次,就能看到每年兔子动态变化的情况
代码
在这里插入代码片
public class Rabbit {
public static void main(String[] args) {
int maxage=20; //定义最大年龄为20 ,可以自己改变,也可改为手动输入。
int obs=30; //定义观察年份为30年 可以自己改变,也可改为手动输入
int[] rabbit= new int[maxage+1]; //建立一个数组,数组的下表为年龄,数值为数量
int yunnum=0; //定义能怀孕的兔子的数量
int num=0; //定义兔子的总数量
int hunt=2; //定义被捕走兔子的数量
for(int i=0;i<=obs;i++) { //年份的循环,执行一次为一年 i=year
{
if(i==0&i<=maxage) { //判断观察年份与兔子最大年龄大小,分别进行处理 每过一年,将数组前一位变为后一位,数组第一位为0
rabbit[0]=1;
}
else if(i!=0&i<=maxage){
b:for(int h=i;h<=i;h--) {
if(h==0) {
break b;
}
else if(h>0&h<=maxage){
rabbit[h]=rabbit[h-1];
}
}
rabbit[0]=0;
}
else if(i>maxage) {
for(int e=maxage;e>0;e--) {
rabbit[e]=rabbit[e-1];
}
rabbit[0]=0;
}
}
{
if(i>maxage) {
rabbit[maxage]=0; // 最大年纪的老死
}
}
{ //当兔子年龄大于3时为怀孕的兔子
if(i>=3 & i<=maxage) {
for(int j=4;j<=maxage;j++) {
yunnum+=rabbit[j]; //计算数组从下标为3到最后一个的值的和
}
rabbit[0]=yunnum; //一对怀孕兔子生一对 把怀孕兔子值赋给数组下标为0
yunnum=0;
}
else if(i>maxage&i<=obs){
for(int u=4;u<=maxage;u++) {
yunnum+=rabbit[u];
}
rabbit[0]=yunnum;
yunnum=0;
}
}
if(num>10) { //当兔子数量大于10时,将最大年龄的两只兔子捕走。
int flag1=0;
int m = maxage;
hunt=2;
a:for( flag1=1;m>0&flag1==1;m--) { //从年龄最大的到最小的进行遍历,去掉年龄最大的
{
if(hunt==0) {
//flag1=0;
break a;
}
}
{if(rabbit[m]==1) { //对年龄最大的数量的情况进行判断,进行处理
rabbit[m]=rabbit[m]-1;
hunt=hunt-1;
if(rabbit[m-1]>=2) {
rabbit[m-1]=rabbit[m-1]-1;
hunt=hunt-1;
}
continue a;
}
else if(rabbit[m]>=2) {
rabbit[m]=rabbit[m]-2;
//flag1=0 ;
hunt=hunt-2;
break a;
}
else if(rabbit[m]==0) {
continue a;
}
}
}
System.out.println(" "+hunt);
}
num=0;
for(int k=0;k<=maxage;k++) { //计算兔子的总数量
num+=rabbit[k];
}
System.out.println("第"+i+"年兔子数量为"+num);
{
System.out.print("兔子第"+i+"年的组合为:");
for(int t=0;t<=20;t++) {
System.out.print(rabbit[t]+" "); //输出数组值,也就是兔子各个年龄的分布情况
}
System.out.println("");
}
}
}
}
运行结果