Fibonacci Series using Dynamic Programming - algorithm

Let us consider the implementation of Fibonacci series using dynamic programming.
// Fibonacci Series using Dynamic Programming
class fibonacci
{
static int fib(int n)
{
/* Declare an array to store Fibonacci numbers. */
int f[] = new int[n+1];
int i;
/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
System.out.println(fib(n));
}
}
We use the dynamic programming so that the repetition of the recursive work does not occur. But here when every time the function has been called,a new array will be generated. So how could this algorithm is said to be more optimized ?

one optimization would be only save the last 2 values instead of all results. You don't need to store all your results.
you also can write the fibonacci series recursively in O(n):
int fib(int n1, int n2, int counter)
{
if(counter == 0)
{
return n2;
}
else
{
return fib(n2,n2 + n1,counter-1);
}
}
//to start:
int result = fib(0,1,100); //gives you the 100 fibonacci value
This code runs recursively and is easy to read. You don't have to initialize an array or other stuff.
alternatively you can use the nonrecursive option:
int fib(int number)
{
int n1 = 0;
int n2 = 1;
int temp;
for(int i = 0; i< number;i++)
{
temp = n1 + n2;
n1 = n2;
n2 = temp;
}
return n2;
}
If you want to store your results, you have to initialize the array outside of your fib function:
// Fibonacci Series using Dynamic Programming
class fibonacci
{
/* Declare an array to store Fibonacci numbers. */
int f[];
static void init(int n)
{ /* 0th and 1st number of the series are 0 and 1*/
f = new int[n+1];
f[0] = 0;
f[1] = 1;
}
static int fib(int n)
{
int i;
for (i = 2; i <= n; i++)
{
/* Add the previous 2 numbers in the series
and store it */
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
public static void main (String args[])
{
int n = 9;
init(n);
System.out.println(fib(n));
}
}

We use Memoization to prevent further recursion with Dynamic Programming. Memoization is the way to store already calculated values ex - let say fib(m) for index m is calculated and stored in memoization table. Further in upcoming recursions if fib(m) reoccur for calculation, then we take it from memoization table instead of doing again fib(m-1)+fib(m-2) i.e. avoid unnecessary recursions...Note - this will keep the complexity linear i.e. O(n).
We can implement this memoization in many ways for faster search. However here for Fibonacci we can implement memoization as array. And yes memoization table will be initialized just once. Below code is illustration for above explanation -
Note - we have taken a variable "complexity" which will incremented whenever we cant find value in memoization table i.e. whenever we go for recursion..
package com.company.dynamicProgramming;
import java.math.BigInteger;
public class FibonacciByBigDecimal {
static int complexity = 0;
public static void main(String ...args) {
int n = 200;
BigInteger[] memoization = new BigInteger[n + 1];
System.out.println("fibonacci of "+ n + " is : " + fibByDivCon(n, memoization));
System.out.println("Complexity is "+complexity);
}
static BigInteger fibByDivCon(int n, BigInteger[] memoization){
if(memoization[n]!=null){
return memoization[n];
}
complexity++;
if (n == 1 || n== 2){
memoization[n] = BigInteger.ONE;
return BigInteger.ONE;
}
// creates 2 further entries in stack
BigInteger fibOfn = fibByDivCon(n-1, memoization).add( fibByDivCon(n-2, memoization)) ;
memoization[n] = fibOfn;
return fibOfn;
}
}
Above i am calculating Fibonacci number at index 200. When I ran above code the result is : -
fibonacci of 200 is : 280571172992510140037611932413038677189525
Complexity is 200
Process finished with exit code 0

Related

What is the total running time of the following code:

What is the total running time of the following code:
I concluded that this code takes O(N log N) times to perform, when the class is being created the loop takes O(N) time to perform, where this for-loop below takes log n time. But I am not completely sure about it, thats why I am asking here.
Z z = new Z(N);
for (int i = 0; i < N-1; i = i+2)
z.update(i,i+1);
Class Z:
public class Z
{
int[] next, prev;
Z(int N)
{
prev = new int[N];
next = new int[N];
for (int i = 0; i<N; ++i)
// put element i in a list of its own
{
next[i] = i;
prev[i] = i;
}
}
int first(int i)
// return first element of list containing i
{
while (i != prev[i]) i = prev[i];
return i;
}
int last(int i)
// return last element of list containing i
{
while (i != next[i]) i = next[i];
return i;
}
void update(int i, int j)
{
int f = first(j);
int l = last(i);
next[l] = f;
prev[f] = l;
}
boolean query(int i, int j)
{
return last(i) == last(j);
}
}
The total running time is only O(N).
The constructor's loop has O(N) steps.
It creates the next/prev arrays as [0, 1, ..., N].
z.update(i,i+1) takes only O(1) time. Since you only call update() once for each i=i and j=i+1, first(j) and last(i) will return j and i, respectively.
It is not possible to analyze the expected complexity of first() and last() under general conditions, as they could easily contain infinite loops (for instance, if called with 0 when next=[1,0]). However, in the example given, they will always skip the while loop entirely, as each call to these functions is on an index that has not yet been modified.
Your for loop takes O(N) time. You run it a total of N/2 times and because you ignore the constant this is N. Total runtime O(N^2). There is no logarithm.
Here is my analysis:
Z z = new Z(N); // O(n)
for (int i = 0; i < N-1; i = i+2) // O(n)
z.update(i,i+1); // O(1)
Hence, the total running time will be O(n).
int first(int i)
{
while (i != prev[i]) i = prev[i]; // O(1), i will always equal prev[i]
// for any input n > 0
return i;
}
int last(int i)
{
while (i != next[i]) i = next[i]; // O(1), i will always equal next[i]
// for any input n > 0
return i;
}
void update(int i, int j)
{
int f = first(j); // O(1)
int l = last(i); // O(1)
next[l] = f; // O(1)
prev[f] = l; // O(1)
}

What is the total running time of the following code (N is an int variable)

I am preparing for the exam, where I came to this question:
What is the total running time of the following code (N is an int variable)
Z z = new Z(N);
for (int i = 0; i < N; i++) z.insert("Bob", i);
Class Z:
public class Z
{
String[] names;
Integer[] numbers;
int N = 0;
public Z(int cap)
{
names = new String[cap];
numbers = new Integer[cap];
}
public Integer find(String S)
{
for (int i = 0; i < N; i++)
{
if (names[i].equals(S)) return numbers[i];
}
return null;
}
public void insert(String S, Integer M)
{
for (int i = 0; i < N; i++)
{
if (names[i].equals(S)) numbers[i] = M;
}
names[N] = S;
numbers[N] = M;
N++;
}
}
I think the answer for this question is O(n^2). The first for loop takes O(n) times, and the method insert takes O(n) times (notice: n++ on every insert call), which total gives O(n^2)
First note that the N variable in the main part is not the same as the N referenced within the object instance.
After the z object is created, its private N member is equal to 0 and only increases with every call to insert.
So the number of times the loop in the insert method iterates is equal to the number of previous calls made to the insert method.
So the total number iterations made in the insert method (taking all the N calls together) is:
Σi=0..N-1 (i)
This is equal to:
½N(N-1)
which is ½N² - ½N and thus O(n²)

Reduce Time complexity of the following program

import java.util.Scanner;
class Special_Pairs{
private static Scanner scan;
public static void main(String [] args) {
byte t;
int n;
scan = new Scanner(System.in);
t=scan.nextByte();
int[] a=new int[100000];
while(t>0)
{
int i,j,count=0;
n=scan.nextInt();
for(i=0;i<n;i++)
{
a[i]=scan.nextInt();
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(((a[i]&a[j])==0)||((a[j]&a[i])==0))
{
count++;
}
}
}
t--;
System.out.println(count);
}
}
}
Help me reduce time complexity of this program
Question :
You have been given an integer array A on size N. You must report the number of ordered pairs (i,j) such that A[i] & A[j]=0.
Here & denotes the BITWISE AND (i,j) and (j,i) are considered different.
Input: First line contains T-Number of Test cases. First line of each test contains N. Next line contains N integers - the i'th integer A[i].
Output: Output the number of such pairs for each test case.
Constraints: T ≤ 10; N ≤ 100000; A[i] ≤ 1000000
Sample Input(Plaintext Link)
1
5
41 47 34 40 29
Sample Output(Plaintext Link)
2
Explanation: These are the required pairs (3 5) (5 3)
I would suggest three optimization for this. I have modified the code as well.
You need not to always start from 0 for each iteration of outer loop. The second loop can start from current+1 of the first loop. So will not be comparing elements which you have already compared.
You don't need to check for both pairs (i,j) and (j,i). If one is zero then other will always be zero.
You need not to initialize the array with fix size. You can always initialize it reading the value of n.
import java.util.Scanner;
public class Pairs {
public static void main(String [] args) {
Scanner scan = new Scanner(System.in);
int t = scan.nextInt();
while(t > 0) {
t--;
int count = 0;
int n = scan.nextInt();
int a[] = new int[n];
for(int i = 0; i<n; i++) {
a[i]=scan.nextInt();
}
for(int i = 0; i<n-1; i++) {
for(int j = i+1; j<n; j++) {
if((a[i] & a[j])==0)
{
count += 2;
}
}
}
System.out.println(count);
}
}
}
If you are competing on a programming contest (like ICPC or something like this), maybe you shouldn't use Scanner. It's too slow for reading from the keyboard. I've already competed at ICPC, but I used to use C++. Maybe you should try BufferedReader instead of Scanner.

Maximal Nested Intervals Set

This is a problem based on finding size of maximal nested intervals set..
There are many intervals each defined by pair containing a starting point and a ending point (si, ei). Two intervals i1 and i2 are called nested if i2 lies completely inside of i1. Example:- (2,6) and (3,4) are nested, since (3,4) is a part of (2,6). Similarly k intervals i1, i2, i3....ik are called nested if, i2 lies inside i1, i3 lies inside i2, ...and so on. Determine size of largest set of intervals from the given intervals, such that all the intervals in that set could produce a nesting.
I thought it in following way:- Let us take an e.g.- (0,7) (0,5) (1,21) (1,9) (2,8) (2,4) (3,20) (4,16) (5,15) (6,21) Sort it in the way such that a[i-1]<=a[i] && b[i-1]>=b[i] Than starting from first interval we start a linked list.. if the next interval comes inside a interval we move down the node and traverse the graph created down the node(other than main list)..we store the pointer of the maximum level node in this graph at which the new interval can fit.. and traverse further in linked list to see under whom the current interval comes.. at last we have a pointer to a node with whom we have to attach the current interval.. and compare the level of this node with the maximum level we already have..... The final value of maximum level is size of maximal nested intervals set..
complexity of above solution is likely to be:- O(n(k+l) + nlogn)
I guess it is difficult to get it this way, but I have no other option... if anyone got any other algorithm to solve it.. please post because my algorithm will take much longer to implement(lot of data structures involved)... thanks!!!
Edit: A few solutions to the problem are posted here, including two that claim to be O(n lg n). However, I don't think the O(n lg n) solutions work. I made comments on that page indicating why. If anyone has an O(n lg n) solution, I'd love to hear it.
Quadratic Solution
This problem can be solved in O(n^2) time using dynamic programming:
Compute how many intervals each interval contains (can be done with two nested loops)
Sort the intervals in ascending order of number of contained intervals
Use the recurrence MaxNestedIntervals to solve the problem
*Note:
Step 1 can be done in O(n lg n) time using the solution here: Sub O(n^2) algorithm for counting nested intervals?
Step 2 can be done in O(n lg n) time with any optimal comparison-based sorting algorithm.
There may be a way to optimize step 3, but I haven't found it yet.
Recurrence
MaxNestedIntervals(i) =
max {j = 0 to i-1} :
1 + MaxNestedIntervals(j) if interval i contains interval j
0 if interval i doesn't contain interval j
Base case
MaxNestedIntervals(i) =
0 if interval i contains 0 intervals
1 if interval i contains 1 interval
Sample code
import java.util.*;
public class MaxNestedIntervals {
public static void main(String[] args) {
Interval[] intervals = new Interval[10];
intervals[0] = new Interval(0, 7);
intervals[1] = new Interval(0, 5);
intervals[2] = new Interval(1, 21);
intervals[3] = new Interval(1, 9);
intervals[4] = new Interval(2, 8);
intervals[5] = new Interval(2, 4);
intervals[6] = new Interval(3, 20);
intervals[7] = new Interval(4,16);
intervals[8] = new Interval(5,15);
intervals[9] = new Interval(6,21);
int n = intervals.length;
AugmentedInterval[] augmentedIntervals = new AugmentedInterval[n];
for (int i = 0; i < n; i++) {
augmentedIntervals[i] = new AugmentedInterval(intervals[i]);
}
for (int i = 0; i < n; i++) {
AugmentedInterval outerInterval = augmentedIntervals[i];
for (int j = 0; j < n; j++) {
if (i == j) {
continue;
}
AugmentedInterval innerInterval = augmentedIntervals[j];
if (outerInterval.contains(innerInterval)) {
outerInterval.numContainedIntervals++;
if (outerInterval.childInterval == null) {
outerInterval.childInterval = innerInterval;
}
}
}
}
Arrays.sort(augmentedIntervals, new Comparator<AugmentedInterval>() {
public int compare(AugmentedInterval i, AugmentedInterval j) {
return i.numContainedIntervals - j.numContainedIntervals;
}
});
int maxNestedIntervals = 0;
AugmentedInterval parentInterval = null;
for (int i = 0; i < n; i++) {
AugmentedInterval currentInterval = augmentedIntervals[i];
if (currentInterval.numContainedIntervals == 0) {
currentInterval.maxNestedIntervals = 0;
} else if (currentInterval.numContainedIntervals == 1) {
currentInterval.maxNestedIntervals = 1;
} else {
int maxNestedIntervalsForCurrentInterval = 0;
for (int j = 0; j < i; j++) {
AugmentedInterval candidateNestedInterval = augmentedIntervals[j];
int maxNestedIntervalsForCurrentCandidate = candidateNestedInterval.maxNestedIntervals + 1;
if (currentInterval.contains(candidateNestedInterval) && maxNestedIntervalsForCurrentCandidate >= maxNestedIntervalsForCurrentInterval) {
maxNestedIntervalsForCurrentInterval = maxNestedIntervalsForCurrentCandidate;
currentInterval.childInterval = candidateNestedInterval;
}
}
currentInterval.maxNestedIntervals = maxNestedIntervalsForCurrentInterval;
if (maxNestedIntervalsForCurrentInterval >= maxNestedIntervals) {
maxNestedIntervals = maxNestedIntervalsForCurrentInterval;
parentInterval = currentInterval;
}
}
}
if (n == 0) {
System.out.println("The largest set of nested intervals is the empty set.");
} else if (maxNestedIntervals == 0) {
System.out.println("The largest set of nested intervals has 1 interval.\n");
System.out.println("That interval is:");
} else {
System.out.println("The largest set of nested intervals has " + (maxNestedIntervals + 1) + " intervals.\n");
System.out.println("Those intervals are:");
}
for (AugmentedInterval currentInterval = parentInterval; currentInterval != null; currentInterval = currentInterval.childInterval) {
System.out.println(currentInterval);
}
System.out.println();
}
private static class Interval implements Comparable<Interval> {
public int start = 0;
public int end = 0;
public Interval(int start, int end) {
this.start = start;
this.end = end;
}
public int size() {
return this.end - this.start;
}
public boolean contains(Interval other) {
return (this.start <= other.start && this.end >= other.end);
}
public int compareTo(Interval other) {
return this.size() - other.size();
}
public String toString() {
return "[" + this.start + ", " + this.end + "]";
}
}
private static class AugmentedInterval extends Interval {
public int numContainedIntervals = 0;
public int maxNestedIntervals = 0;
public AugmentedInterval childInterval = null;
public AugmentedInterval(Interval interval) {
super(interval.start, interval.end);
}
}
}

Sum of factorials for large numbers

I want to calculate the sum of digits of N!.
I want to do this for really large values of N, say N(1500). I am not using .NET 4.0. I cannot use the BigInteger class to solve this.
Can this be solved by some other algorithm or procedure? Please help.
I want to do some thing like this Calculate the factorial of an arbitrarily large number, showing all the digits but in C#. However I am unable to solve.
There is no special magic that allows you to calculate the sum of the digits, as far as I am concerned.
It shouldn't be that hard to create your own BigInteger class anyway - you only need to implement the long multiplication algorithm from 3rd grade.
If your goal is to calculate the sum of the digits of N!, and if N is reasonably bounded, you can do the following without a BigInteger type:
Find a list of factorial values online (table lookup will be much more efficient than calculating from scratch, and does not require BigInteger)
Store as a string data type
Parse each character in the string as an integer
Add the resulting integers
There are two performance shortcuts that you can use for whatever implementation you choose.
Chop off any zeros from the numbers.
If the number is evenly divisible by 5^n, divide it by 10^n.
in this way,
16*15*14*13*12*11*10*9*8*7*6*5*4*3*2 = 20,922,789,888,000
//-->
16*1.5*14*13*12*11*1*9*8*7*6*0.5*4*3*2 = 20,922,789,888 //Sum of 63
Also, it feels like there should be some algorithm without reverting to calculating it all out. Going to 18!, the sums of the digits are:
2,6,6,3,9,9,9,27,27,36,27,27,45,45,63,63,63
//the sums of the resulting digits are:
2,6,6,3,9,9,9,9,9,9,9,9,9,9,9,9,9
and notably, the sum of the digits of 1500! is 16749 (the sum of whose digits are 27)
Here's some working code. Some components can be improved upon to increase efficiency. The idea is to use whatever multiplication algorithm I was told in school, and to store long integers as strings.
As an afterthought, I think it would be smarter to represent large numbers with List<int>() instead of string. But I'll leave that as an exercise to the reader.
Code Sample
static string Mult(string a, string b)
{
int shift = 0;
List<int> result = new List<int>();
foreach (int aDigit in a.Reverse().Select(c => int.Parse(c.ToString())))
{
List<int> subresult = new List<int>();
int store = 0;
foreach (int bDigit in b.Reverse().Select(c => int.Parse(c.ToString())))
{
int next = aDigit*bDigit + store;
subresult.Add(next%10);
store = next/10;
}
if (store != 0) subresult.Add(store);
subresult.Reverse();
for (int i = 0; i < shift; ++i) subresult.Add(0);
subresult.Reverse();
int newResult = new List<int>();
store = 0;
for (int i = 0; i < subresult.Count; ++i)
{
if (result.Count >= i + 1)
{
int next = subresult[i] + result[i] + store;
if (next >= 10)
newResult.Add(next % 10);
else newResult.Add(next);
store = next / 10;
}
else
{
int next = subresult[i] + store;
newResult.Add(next % 10);
store = next / 10;
}
}
if (store != 0) newResult.Add(store);
result = newResult;
++shift;
}
result.Reverse();
return string.Join("", result);
}
static int FactorialSum(int n)
{
string result = "1";
for (int i = 2; i <= n; i++)
result = Mult(i.ToString(), result);
return result.Sum(r => int.Parse(r.ToString()));
}
Code Testing
Assuming the code snippet above is in the same class as your Main method, call it thusly.
Input
static void Main(string[] args)
{
Console.WriteLine(FactorialSum(1500));
}
Output
16749
Here's a port of the C++ code you reference in one of your comments. One thing to realize when porting from C++ to C# is that integers that are zero evaluate to false and integers that are non-zero evaluate to true when used in a Boolean comparison.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ArbitraryFactorial
{
class Program
{
const int max = 5000;
static void display(int[] arr)
{
int ctr = 0;
for (int i = 0; i < max; i++)
{
if (ctr == 0 && arr[i] != 0) ctr = 1;
if (ctr != 0)
Console.Write(arr[i]);
}
}
static void factorial(int[] arr, int n)
{
if (n == 0) return;
int carry = 0;
for (int i = max - 1; i >= 0; --i)
{
arr[i] = (arr[i] * n) + carry;
carry = arr[i] / 10;
arr[i] %= 10;
}
factorial(arr, n - 1);
}
static void Main(string[] args)
{
int[] arr = new int[max];
arr[max - 1] = 1;
int num;
Console.Write("Enter the number: ");
num = int.Parse(Console.ReadLine());
Console.Write("Factorial of " + num + " is: ");
factorial(arr, num);
display(arr);
}
}
}
you can find the source code at : http://codingloverlavi.blogspot.in/2013/03/here-is-one-more-interesting-program.html
#include<stdio.h>
#include<conio.h>
#include<iostream.h>
#include<time.h>
#define max 5000
void multiply(long int *,long int);
void factorial(long int *,long int);
int main()
{
clrscr();
cout<<"PROGRAM TO CALCULATE FACTORIAL OF A NUMBER";
cout<<"\nENTER THE NUMBER\n";
long int num;
cin>>num;
long int a[max];
for(long int i=0;i<max;i++)
a[i]=0;
factorial(a,num);
clrscr();
//PRINTING THE FINAL ARRAY...:):):)
cout<<"THE FACTORIAL OF "<<num<<" is "<<endl<<endl;
long int flag=0;
int ans=0;
for(i=0;i<max;i++)
{
if(flag||a[i]!=0)
{
flag=1;
cout<<a[i];
ans=ans+a[i];
}
}
cout<<endl<<endl<<"the sum of all digits is: "<<ans;
getch();
return 1;
}
void factorial(long int *a,long int n)
{
long int lavish;
long int num=n;
lavish=n;
for(long int i=max-1;i>=0&&n;i--)
{
a[i]=n%10;
n=n/10;
}
for(i=2;i<(lavish);i++)
{
multiply(a,num-1);
num=num-1;
}
}
void multiply(long int *a,long int n)
{
for(long int i=0;i<max;i++)
a[i]=a[i]*n;
for(i=max-1;i>0;i--)
{
a[i-1]=a[i-1]+(a[i]/10);
a[i]=a[i]%10;
}
}
You can't use these numbers at all without a BigInteger type.
No algorithm or procedure can squeeze numbers larger than 264 into a long.
You need to find a BigInteger implementation for .Net 3.5.

Resources