简体   繁体   中英

Find a Number of ways to Generate a Number

I have given Fibonacci digits only , i have to find out the numbers of ways to generate a number using K Fibonacci numbers only.

Constraints:

1<=K<=10
1<=N<=10^9

For Example:

N=14 and K=3

There are two ways:

(8,5,1) and (8,3,3) 

Here is my recursive solution:

public static void num_gen(int i ,long val ,int used){

      if(used==0){

          if(val==n) ans++;
          return ;
      }

      if(i==Fib.length) return ;

      for(int j=0;j<=used;j++){

          long x = j*Fib[i];
          if(x+val<=n){
              num_gen(i+1,x+val, used-j);
          }
      }

}

This solution will timeout for large value of N and K=10. Can you provide me algorithm with better complexity.

This can be expressed as multiplying polynomials where exponents are Fibonacci numbers.

Number of factors is K.

The result is a coefficient of the member of the result polynomial whose exponent equals N.

Example: What is the number of ways to compose number 7 from 3 numbers where each of these 3 numbers can be 1,2 or 3.

(x + x² + x³)³ = x⁹ + 3x⁸ +6x⁷ + 7x⁶ + 6x⁵ + 3x⁴ + x³

Result is 6 since it is the coefficient of the x⁷ member of the result polynomial.

I'd like to give you a solution that works in another language, and I hope that helps you learn in the process of translating it to Java. Because I'm unclear on how to otherwise help you fix the recursive solution you're working on, as I believe that no recursion is required. Also no preset array of Fibonacci numbers is needed.

This is in Perl, it worked for:

$ perl fibber.pl 3 14
8,5,1
8,3,3
2 matches

But I can't guarantee it's perfectly right.

#!/usr/bin/perl
use bigint;
use List::Util qw(sum);

my ($digits, $goal) = @ARGV;
if (!($digits > 0) || !($goal > 0)) {
    die "Missing 2 arguments: the number count to sum, the value they sum to.";
}

sub fib {
    my ($a, $b) = @_;
    return sub {
        if (0 == scalar @_) {
            (my $r, $a, $b) = ($a, $b, $a+$b);
            return $r;
        } else {
            ($a, $b) = @_;
            (my $r, $a, $b) = ($b, $a+$b, $a+$b+$b);
            return $r;
        }
    }
}

my @f = (0) x $digits;
   @f = map {fib(1,2)} @f;
my @d = map {$_->()}   @f;
my $count = 0;
while ($d[0] < $goal) {
    if ($goal == sum @d) {
        $count++;
        print(join(",", @d)."\n");
    }
    my ($i, $a, $b) = (0, $d[$i], $f[$i]->());
    $d[$i] = $b;
    while ($goal <= $d[$i]) {
        $i++;
        if ($i == $digits) {
            print "$count matches\n";
            exit 0;
        }
        ($a, $b) = ($d[$i], $f[$i]->());
        $d[$i] = $b;
    }
    while ($i > 0) {
        $i--;
        $d[$i] = $f[$i]->($a, $b);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM