I. Rabbits
Originally, I wanted to find the constant algorithm of the rabbit, because I thought that constant algorithms can be obtained as long as the recursive formula is expanded.
However, the basis for self-analysis is too poor to be necessary, but an algorithm is emerging in the middle to obtain a linear algorithm.
The bunny seems to be a complex recursive structure, but in fact, the bunny has only 13 States (12 months), because its life is very short.
0.0 bunny
0.5 bunny
1.0 rabbits
1.5 rabbits
2.0 rabbits (2 rabbits in 2.0)
2.5 rabbits
3.0 rabbits
3.5 rabbits
4.0 rabbits
4.5 rabbits
5.0 rabbits
5.5 rabbits
6.0 rabbits (> = 6.0 rabbits died)
The thirteen states are a first-in-first-out queue. As the age increases, the status only migrates backward.
The newly added status (new rabbit) is the total number of States in eight breeding periods.
The final State is the State of death.
We need to know how many rabbits are still alive. We only need to count the total number of rabbits in addition to the last grid. No matter how much n is, you only need to update the status 2 * n times.
Code:
// Use an array of cyclic States to solve the litter size problem of rabbits. //, 12 static int bunny (uint n) {// initialize uint [] states = new uint [13]; // status loop int start = 0; // 0 ~ 11 states [start] = 1; // The initial bunny is 0 years old. // After n times of growth, for (int I = 0; I <n; I ++) {// Add age AddAge (ref start); // Update Status states [start] = states [getIndex (start, 10)] + states [getIndex (start, 3)] + states [getIndex (start, 4)] + states [getIndex (start, 5)] + states [getIndex (start, 6)] + states [getIndex (start, 7)] + states [getIndex (start, 8)] + states [getIndex (start, 9)]; // debug the Console. write ("bunny" + (float) (I + 1)/2 ). toString ("{0.0}") + "year:"); for (int j = 0; j <13; j ++) {Console. write (states [getIndex (start, j)] + ",");} Console. writeLine () ;}// statistical result uint count = 0; for (int I = 0; I <12; I ++) {count + = states [getIndex (start, i)];} return (int) count;} static void AddAge (ref int index) {index --; if (index <0) index + = 13 ;} static int getIndex (int start, int index) {return (start + index) % 13 ;}
Ii. Soda bottle change
Soda bottle changing is also a recursive structure, but a non-recursive formula can be obtained through a simple algebraic transformation.
3 empty bottles = 1 water + 1 empty bottles -- "2 empty bottles = 1 Water
The problem is that there is a precondition for such replacement, that is, when replacing, you must ensure that there are more than three empty bottles first. Otherwise, the prerequisite is not met, and the subsequent formula is meaningless.
How can we ensure that there are at least three empty bottles? You can take three empty bottles first and put them aside. The four bottles are left in 997/2... 1 + 3 = 4. It is easy to calculate the remaining two empty bottles according to the regular formula.
In fact, we can proceed further. We only need to take one empty bottle out, because there are at least two empty bottles before the conversion, and the one you leave will be better.
So: 999/2 = 499... 1 + 1 = more than 2.
Soda drink: 499 + 1000 = 1499.
The benefit of this algorithm is that you don't need to worry about the sum of the remainder to calculate it again.
Code:
Static Tuple <int, int> soda bottle change (int n, int p, int k)
{
Tuple <int, int> t = empty bottle for soda (n, p, k );
Tuple <int, int> result = new Tuple <int, int> (t. Item1 + n, t. Item2 );
Return result;
}
// N = number of empty bottles
// Change k bottles of soda for p empty bottles
Private static Tuple <int, int> Empty Bottle for soda (int n, int p, int k)
{
Int soda = (n-k)/(p-k );
Int residual bottle = k + (n-k) % (p-k );
Return new Tuple <int, int> (soda, residual bottle );
}