One, the problem description
Given an integer n, the number of FIB numbers can be added to solve the integer at least.
The fib sequence is like: 1,1,2,3,5,8,13 ....
The fib sequence satisfies the condition: fib (n) =fib (n-1) +fib (n-2) fib (0) =1 fib (1) =1;fib number, which is a number in the fib sequence.
For example 70 = 55+13+2, which is a total of 3 fib numbers to get
Second, problem solving
① Find all fib numbers less than or equal to n
//get all fib numbers less than or equal to n Private StaticArraylist<integer> Getfibs (intN) {ArrayList<Integer> fibs =NewArraylist<integer>(); intFIB1 = 1; intFIB2 = 1; Fibs.add (FIB1); Fibs.add (FIB2); intfibn; while((fibn = fib1 + fib2) <=N) {fibs.add (fibn); FIB1=Fib2; Fib2=fibn; } returnfibs; }
② In fact, this problem can be translated into a "complete 0-1 knapsack problem".
The so-called complete 0-1 knapsack problem refers to: Each item can be selected repeatedly . And here, each FIB number can be selected repeatedly.
such as: 70=34+34+2,34 chose two times, fib (i) the maximum number of times that can be selected is: N/fib (i), that is, a fib number is split into (copied) multiple same as the original value of the same fib number. In this way, the equivalent of each number can be selected only once, that is, either select it or do not select it.
In this way, the complete 0-1 knapsack problem is converted into a normal 0-1 knapsack problem.
In this way, the FIB number in the ArrayList found above can be "augmented" into a ArrayList with a repeating fib number.
For example, for 70: The expanded FIB array is: There will be 70 1,70/2 2 ...
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, 13, 13, 13, 13, 13, 21, 21, 21, 34, 34, 55]
According to the general 0-1 knapsack problem, for this problem, always prefer to choose the most close to the fib number of N, and then consider the number of the fib smaller than n times ...
That is, always try to choose the fib number close to n whenever possible.
In fact, this is equivalent to a greedy problem??? Should not need to use DP bar??
Entire complete code:
1 Importjava.util.ArrayList;2 3 Public classSolution {4 5 //get all fib numbers less than or equal to n6 Private StaticArraylist<integer> Getfibs (intN) {7Arraylist<integer> fibs =NewArraylist<integer>();8 intFIB1 = 1;9 intFIB2 = 1;Ten One Fibs.add (FIB1); A Fibs.add (FIB2); - - intfibn; the while((fibn = fib1 + fib2) <=N) - { - Fibs.add (fibn); -FIB1 =fib2; +FIB2 =fibn; - } + returnfibs; A } at - //turn it into a 0-1-pack problem that can be repeatedly selected - Private StaticArraylist<integer> augument (arraylist<integer> fibs,intN) { -Arraylist<integer> dupfibs =NewArraylist<integer>(); - for(Integer integer:fibs) { - inttimes = N/integer;//up to how many times each fib number can be selected in for(inti = 1; I <= times; i++) -Dupfibs.add (integer);//"Split" fib number to } + returndupfibs; - } the * //similar to DP Solver $ Private Static intDP (arraylist<integer> dupfibs,intN) {Panax Notoginseng intCurrentsum = 0; - intCount = 0;//Number of fib numbers to use the while(Currentsum! =N) { + for(inti = Dupfibs.size ()-1; I >= 0; i--){ ACurrentsum + =Dupfibs.get (i); thecount++; + if(Currentsum >N) - { $Currentsum-=Dupfibs.get (i); $count--; - } - } the } - returncount;Wuyi } the - //function Entrance Wu Public Static intfunctionintN) { -Arraylist<integer> fibs =getfibs (n); AboutFibs =augument (fibs, n); $ intresult =DP (fibs, n); - returnresult; - } - A //Test + Public Static voidMain (string[] args) { the intresult = function (70); - System.out.println (result); $ } the}
Given an integer, the number of FIB numbers can be added to solve the integer at least