0% found this document useful (1 vote)
1K views

Dynamic Programming

The document is a table of contents that lists 38 topics related to dynamic programming. Each topic is numbered and includes the name of the dynamic programming problem addressed and the page number of its source material. The topics cover a range of classic dynamic programming problems from longest common subsequence to knapsack problems to matrix chain multiplication.

Uploaded by

Tarun Dhamor
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (1 vote)
1K views

Dynamic Programming

The document is a table of contents that lists 38 topics related to dynamic programming. Each topic is numbered and includes the name of the dynamic programming problem addressed and the page number of its source material. The topics cover a range of classic dynamic programming problems from longest common subsequence to knapsack problems to matrix chain multiplication.

Uploaded by

Tarun Dhamor
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3020

Contents

1 DP-01 | Overlapping Subproblems Property in Dynamic Programming 27


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

2 DP-02 | Optimal Substructure Property in Dynamic Programming 36


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

3 DP-03 | Longest Increasing Subsequence 38


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

4 DP-04 | Longest Common Subsequence 47


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58

5 DP-05 | Edit Distance 59


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

6 DP-06 | Min Cost Path 74


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

7 DP-07 | Coin Change 87


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

8 DP-08 | Matrix Chain Multiplication 101


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

9 DP-09 | Binomial Coefficient 113


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

10 DP-10 | 0-1 Knapsack Problem 127


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138

11 DP-11 | Egg Dropping Puzzle 139


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149

12 DP-12 | Longest Palindromic Subsequence 150


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159

13 DP-13 | Cutting a Rod 160


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

1
Contents

14 DP-14 | Maximum Sum Increasing Subsequence 170


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176

15 DP-15 | Longest Bitonic Subsequence 177


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

16 DP-16 | Floyd Warshall Algorithm 184


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194

17 DP-17 | Palindrome Partitioning 195


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207

18 DP-18 | Partition problem 208


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219

19 DP-19 | Word Wrap Problem 220


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

20 DP-20 | Maximum Length Chain of Pairs 230


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235

21 DP-21 | Variations of LIS 236


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237

22 DP-22 | Box Stacking Problem 238


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245

23 DP-23 | Bellman–Ford Algorithm 246


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257

24 DP-24 | Optimal Binary Search Tree 258


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269

25 DP-25 | Subset Sum Problem 270


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281

26 DP-26 | Largest Independent Set Problem 282


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288

27 DP-27 | Maximum sum rectangle in a 2D matrix 289


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

28 DP-28 | Minimum insertions to form a palindrome 296


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

29 DP-29 | Longest Common Substring 306


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312

30 DP-30 | Dice Throw 313


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319

2
Contents

31 DP-31 | Optimal Strategy for a Game 320


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 324

32 DP-32 | Word Break Problem 325


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332

33 DP-33 | Find if a string is interleaved of two other strings 333


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336

34 DP-34 | Assembly Line Scheduling 337


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345

35 DP-35 | Longest Arithmetic Progression 346


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352

36 DP-36 | Maximum Product Cutting 353


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362

37 DP-37 | Boolean Parenthesization Problem 363


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366

38 A Space Optimized DP solution for 0-1 Knapsack Problem 367


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370

39 A Space Optimized Solution of LCS 371


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377

40 All ways to add parenthesis for evaluation 378


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380

41 Alternate Fibonacci Numbers 381


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381

42 Balanced expressions such that given positions have opening brackets 384
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387

43 Balanced expressions such that given positions have opening brackets |


Set 2 388
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392

44 Bell Numbers (Number of ways to Partition a Set) 393


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399

45 Bitmasking and Dynamic Programming | Set 1 (Count ways to assign


unique cap to every person) 400
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409

46 Bitmasking and Dynamic Programming | Set-2 (TSP) 410


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417

47 Check for possible path in 2D matrix 418

3
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424

48 Check if all people can vote on two machines 425


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427

49 Check if any valid sequence is divisible by M 428


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433

50 Check if array sum can be made K by three operations on it 434


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436

51 Check if it is possible to transform one string to another 437


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441

52 Check if possible to cross the matrix with given power 442


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449

53 Check whether row or column swaps produce maximum size binary


sub-matrix with all 1s 450
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 454

54 Choice of Area 455


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459

55 Choose maximum weight with given weight and value ratio 460
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 464

56 Clustering/Partitioning an array such that sum of square differences is


minimum 465
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474

57 Coin game winner where every player has three choices 475
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481

58 Collect maximum coins before hitting a dead end 482


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487

59 Collect maximum points in a grid using two traversals 488


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491

60 Compute nCr % p | Set 1 (Introduction and Dynamic Programming


Solution) 492
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498

61 Compute sum of digits in all numbers from 1 to n 499


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512

62 Construction of Longest Increasing Subsequence using Dynamic Pro-


gramming 513
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515

4
Contents

63 Convert to Strictly increasing array with minimum changes 516


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521

64 Count numbers from 1 to n that have 4 as a digit 522


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522

65 Count All Palindrome Sub-Strings in a String | Set 1 531


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535

66 Count All Palindromic Subsequence in a given String 536


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541

67 Count Balanced Binary Trees of Height h 542


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545

68 Count Derangements (Permutation such that no element appears in its


original position) 546
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555

69 Count Distinct Subsequences 556


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560

70 Count Possible Decodings of a given Digit Sequence 561


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567

71 Count all increasing subsequences 568


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575

72 Count all possible paths from top left to bottom right of a mXn matrix 576
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582

73 Count all possible walks from a source to a destination with exactly k


edges 583
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593

74 Count all subsequences having product less than K 594


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 597

75 Count all triplets whose sum is equal to a perfect cube 598


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 602

76 Count binary strings with k times appearing adjacent two set bits 603
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 605

77 Count digit groupings of a number with given constraints 606


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 613

78 Count distinct occurrences as a subsequence 614


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 619

5
Contents

79 Count even length binary sequences with same sum of first and second
half bits 620
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 633

80 Count number of binary strings without consecutive 1’s 634


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638

81 Count number of increasing subsequences of size k 639


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 643

82 Count number of paths with at-most k turns 644


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 647

83 Count number of subsets having a particular XOR value 648


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 651

84 Count number of ways to cover a distance 652


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 660

85 Count number of ways to fill a “n x 4” grid using “1 x 4” tiles 661


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 668

86 Count number of ways to jump to reach end 669


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 674

87 Count number of ways to partition a set into k subsets 675


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680

88 Count number of ways to reach a given score in a game 681


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688

89 Count number of ways to reach destination in a Maze 689


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698

90 Count of AP (Arithmetic Progression) Subsequences in an array 699


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706

91 Count of Palindromic substrings in an Index range 707


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713

92 Count of arrays having consecutive element with different values 714


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719

93 Count of arrays in which all adjacent elements are such that one of them
divide the another 720
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723

94 Count of different ways to express N as the sum of 1, 3 and 4 724


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729

95 Count of n digit numbers whose sum of digits equals to given sum 730

6
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742

96 Count of possible hexagonal walks 743


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749

97 Count of strings that can be formed using a, b and c under given


constraints 750
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758

98 Count of strings where adjacent characters are of difference one 759


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762

99 Count of subarrays whose maximum element is greater than k 763


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 769

100 Count possible ways to construct buildings 770


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 777

101 Count the number of ways to tile the floor of size n x m using 1 x m
size tiles 778
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 784

102 Count total number of N digit numbers such that the difference be-
tween sum of even and odd digits is 1 785
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787

103 Count ways to build street under given constraints 788


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 792

104 Count ways to divide circle using N non-intersecting chords 793


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797

105 Count ways to increase LCS length of two strings by one 798
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801

106 Count ways to reach the nth stair using step 1, 2 or 3 802
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 810

107 Count ways to reach the n’th stair 811


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823

108 Counting numbers of n digits that are monotone 824


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830

109 Counting pairs when a person can form pair with at most one 831
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838

110 Counts paths from a point to reach Origin 839


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847

111 Delannoy Number 848

7
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856

112 Different ways to sum n using numbers greater than or equal to m 857
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 861

113 Digit DP | Introduction 862


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 867

114 Dynamic Programming on Trees | Set 2 868


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 875

115 Dynamic Programming on Trees | Set-1 876


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 880

116 Dynamic Programming vs Divide-and-Conquer 881


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 891

117 Dynamic Programming | Building Bridges 892


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 895

118 Dynamic Programming | High-effort vs. Low-effort Tasks Problem 896


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899

119 Dynamic Programming | Wildcard Pattern Matching | Linear Time


and Constant Space 900
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 906

120 Edit Distance | DP using Memoization 907


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 915

121 Edit distance and LCS (Longest Common Subsequence) 916


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 917

122 Efficient program to print all prime factors of a given number 918
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 924

123 Entringer Number 925


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 933

124 Eulerian Number 934


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942

125 Find Jobs involved in Weighted Job Scheduling 943


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 946

126 Find Maximum dot product of two arrays with insertion of 0’s 947
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950

127 Find all combinations of k-bit numbers with n bits set where 1 <= n
<= k in sorted order 951
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 953

8
Contents

128 Find all distinct palindromic sub-strings of a given string 954


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 960

129 Find all distinct subset (or subsequence) sums of an array 961
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968

130 Find all distinct subset (or subsequence) sums of an array | Set-2 969
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 971

131 Find if string is K-Palindrome or not | Set 1 972


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978

132 Find if string is K-Palindrome or not | Set 2 979


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983

133 Find length of longest subsequence of one string which is substring of


another string 984
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 990

134 Find length of the longest consecutive path from a given starting char-
acter 991
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 999

135 Find longest bitonic sequence such that increasing and decreasing parts
are from two different arrays 1000
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1002

136 Find maximum length Snake sequence 1003


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1009

137 Find maximum possible stolen value from houses 1010


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1021

138 Find maximum sum array of length less than or equal to m 1022
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1023

139 Find minimum adjustment cost of an array 1024


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1031

140 Find minimum number of coins that make a given value 1032
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1043

141 Find minimum possible size of array with given rules for removing
elements 1044
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1047

142 Find minimum sum such that one of every three consecutive elements
is taken 1048
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1054

9
Contents

143 Find n-th element from Stern’s Diatomic Series 1055


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1061

144 Find number of endless points 1062


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1070

145 Find number of solutions of a linear equation of n variables 1071


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1081

146 Find number of times a string occurs as a subsequence in given string1082


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1090

147 Find the Longest Increasing Subsequence in Circular manner 1091


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1098

148 Find the largest area rectangular sub-matrix whose sum is equal to k 1099
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1103

149 Find the longest path in a matrix with given constraints 1104
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1108

150 Find the minimum cost to reach destination using a train 1109
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1119

151 Find the probability of reaching all points after N moves from point N1120
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1122

152 Finding the maximum square sub-matrix with all equal elements 1123
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1132

153 Friends Pairing Problem 1133


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1138

154 G-Fact 21 | Collatz Sequence 1139


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1139

155 Generate all unique partitions of an integer 1140


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1149

156 Given a large number, check if a subsequence of digits is divisible by 81150


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1161

157 Gold Mine Problem 1162


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1168

158 Golomb sequence 1169


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1177

159 Highway Billboard Problem 1178


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1182

10
Contents

160 Hosoya’s Triangle 1183


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1193

161 How to print maximum number of A’s using given four keys 1194
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1203

162 How to solve a Dynamic Programming Problem ? 1204


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1207

163 Jacobsthal and Jacobsthal-Lucas numbers 1208


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1219

164 K maximum sums of non-overlapping contiguous sub-arrays 1220


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1229

165 K maximum sums of overlapping contiguous sub-arrays 1230


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1236

166 LCS (Longest Common Subsequence) of three strings 1237


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1244

167 LCS formed by consecutive segments of at least length K 1245


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1250

168 Largest Sum Contiguous Subarray 1251


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1264

169 Largest area rectangular sub-matrix with equal number of 1’s and 0’s 1265
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1269

170 Largest divisible pairs subset 1270


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1275

171 Largest rectangular sub-matrix having sum divisible by k 1276


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1280

172 Largest rectangular sub-matrix whose sum is 0 1281


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1285

173 Largest sum Zigzag sequence in a matrix 1286


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1294

174 Largest sum subarray with at-least k numbers 1295


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1301

175 Length of Longest Balanced Subsequence 1302


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1306

176 Length of longest common subsequence containing vowels 1307


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1307

11
Contents

177 Length of the longest valid substring 1311


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1316

178 Level Ancestor Problem 1317


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1324

179 Lobb Number 1325


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1331

180 Longest Common Substring (Space optimized DP solution) 1332


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1339

181 Longest Common Increasing Subsequence (LCS + LIS) 1340


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1355

182 Longest Common Subsequence with at most k changes allowed 1356


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1358

183 Longest Common Subsequence | DP using Memoization 1359


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1363

184 Longest Decreasing Subsequence 1364


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1369

185 Longest Even Length Substring such that Sum of First and Second
Half is same 1370
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1382

186 Longest Geometric Progression 1383


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1386

187 Longest Increasing Odd Even Subsequence 1387


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1392

188 Longest Increasing Path in Matrix 1393


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1396

189 Longest Increasing Subsequence Size (N log N) 1397


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1408

190 Longest Increasing consecutive subsequence 1409


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1411

191 Longest Palindromic Substring | Set 1 1412


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1418

192 Longest Repeated Subsequence 1419


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1425

193 Longest Repeating Subsequence 1426


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1431

12
Contents

194 Longest Zig-Zag Subsequence 1432


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1439

195 Longest alternating (positive and negative) subarray starting at every


index 1440
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1445

196 Longest alternating sub-array starting from every index in a Binary


Array 1446
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1453

197 Longest alternating subsequence 1454


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1461

198 Longest palindrome subsequence with O(n) space 1462


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1470

199 Longest repeating and non-overlapping substring 1471


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1474

200 Longest subarray having maximum sum 1475


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1477

201 Longest subsequence such that difference between adjacents is one 1478
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1485

202 Lucas Numbers 1486


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1494

203 Matrix Exponentiation 1495


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1503

204 Maximize arr[j] – arr[i] + arr[l] – arr[k], such that i < j < k < l 1504
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1506

205 Maximize array elements upto given number 1507


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1524

206 Maximize the binary matrix by filpping submatrix once 1525


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1527

207 Maximize the sum of selected numbers from an array to make it empty 1528
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1530

208 Maximum Product Subarray | Added negative product case 1531


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1534

209 Maximum Subarray Sum Excluding Certain Elements 1535


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1545

210 Maximum Subarray Sum using Divide and Conquer algorithm 1546

13
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1553

211 Maximum Sum Decreasing Subsequence 1554


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1559

212 Maximum absolute difference between sum of two contiguous sub-arrays 1560
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1571

213 Maximum and Minimum Values of an Algebraic Expression 1572


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1582

214 Maximum average sum partition of an array 1583


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1586

215 Maximum decimal value path in a binary matrix 1587


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1593

216 Maximum difference of zeros and ones in binary string 1594


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1599

217 Maximum difference of zeros and ones in binary string | Set 2 (O(n)
time) 1600
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1605

218 Maximum games played by winner 1606


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1610

219 Maximum length of segments of 0’s and 1’s 1611


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1613

220 Maximum length subsequence with difference between adjacent ele-


ments as either 0 or 1 1614
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1620

221 Maximum number of segments of lengths a, b and c 1621


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1627

222 Maximum number of trailing zeros in the product of the subsets of


size k 1628
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1632

223 Maximum path sum for each position with jumps under divisibility
condition 1633
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1639

224 Maximum path sum in a triangle. 1640


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1646

225 Maximum path sum that starting with any cell of 0-th row and ending
with any cell of (N-1)-th row 1647

14
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1652

226 Maximum points collected by two persons allowed to meet once 1653
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1656

227 Maximum points from top left of matrix to bottom right and return
back 1657
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1662

228 Maximum product of an increasing subsequence 1663


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1667

229 Maximum profit by buying and selling a share at most k times 1668
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1681

230 Maximum profit by buying and selling a share at most twice 1682
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1691

231 Maximum profit from sale of wines 1692


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1699

232 Maximum size square sub-matrix with all 1s 1700


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1706

233 Maximum size subset with given sum 1707


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1710

234 Maximum sub-matrix area having count of 1’s one more than count of
0’s 1711
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1715

235 Maximum subarray sum in O(n) using prefix sum 1716


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1723

236 Maximum subarray sum in an array created after repeated concatenation 1724
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1730

237 Maximum subsequence sum such that no three are consecutive 1731
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1738

238 Maximum sum Bi-tonic Sub-sequence 1739


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1746

239 Maximum sum alternating subsequence 1747


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1756

240 Maximum sum bitonic subarray 1757


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1768

241 Maximum sum in a 2 x n grid such that no two elements are adjacent1769
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1772

15
Contents

242 Maximum sum in circular array such that no two elements are adjacent 1773
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1776

243 Maximum sum increasing subsequence from a prefix and a given ele-
ment after prefix is must 1777
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1782

244 Maximum sum of a path in a Right Number Triangle 1783


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1791

245 Maximum sum of pairs with specific difference 1792


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1802

246 Maximum sum path in a matrix from top to bottom 1803


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1810

247 Maximum sum subarray removing at most one element 1811


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1819

248 Maximum sum subsequence with at-least k distant elements 1820


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1825

249 Maximum sum such that no two elements are adjacent 1826
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1831

250 Maximum value with the choice of either dividing or considering as it is 1832
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1836

251 Maximum weight path ending at any element of last row in a matrix 1837
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1843

252 Maximum weight transformation of a given string 1844


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1848

253 Memoization (1D, 2D and 3D) 1849


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1861

254 Minimal moves to form a string by adding characters or appending


string itself 1862
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1863

255 Minimum Cost Path with Left, Right, Bottom and Up moves allowed 1864
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1867

256 Minimum Cost Polygon Triangulation 1868


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1873

257 Minimum Cost To Make Two Strings Identical 1874


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1879

258 Minimum Initial Points to Reach Destination 1880

16
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1885

259 Minimum Sum Path In 3-D Array 1886


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1894

260 Minimum Sum Path in a Triangle 1895


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1901

261 Minimum and Maximum values of an expression with * and + 1902


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1905

262 Minimum cells required to reach destination with jumps equal to cell
values 1906
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1914

263 Minimum cost to fill given weight in a bag 1915


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1921

264 Minimum cost to make Longest Common Subsequence of length k 1922


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1924

265 Minimum cost to make two strings identical by deleting the digits 1925
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1930

266 Minimum cost to reach the top of the floor by climbing stairs 1931
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1941

267 Minimum cost to sort strings using reversal operations of different costs 1942
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1946

268 Minimum insertions to sort an array 1947


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1952

269 Minimum jumps to reach last building in a matrix 1953


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1961

270 Minimum number of deletions and insertions to transform one string


into another 1962
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1967

271 Minimum number of deletions to make a sorted sequence 1968


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1976

272 Minimum number of deletions to make a string palindrome 1977


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1984

273 Minimum number of deletions to make a string palindrome | Set 2 1985


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1988

274 Minimum number of elements which are not part of Increasing or


decreasing subsequence in array 1989

17
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1992

275 Minimum number of jumps to reach end 1993


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2009

276 Minimum number of jumps to reach end | Set 2 (O(n) solution) 2010
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2017

277 Minimum number of single digit primes required whose sum is equal
to N 2018
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2026

278 Minimum number of squares whose sum equals to given number n 2027
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2038

279 Minimum removals from array to make max – min <= K 2039
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2048

280 Minimum splits in a binary string such that every substring is a power
of 4 or 6. 2049
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2054

281 Minimum steps to delete a string after repeated deletion of palindrome


substrings 2055
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2061

282 Minimum steps to minimize n as per given condition 2062


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2072

283 Minimum steps to reach a destination 2073


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2079

284 Minimum steps to reach target by a Knight | Set 2 2080


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2084

285 Minimum sum of multiplications of n numbers 2085


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2092

286 Minimum sum submatrix in a given 2D array 2093


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2096

287 Minimum sum subsequence such that at least one of every four con-
secutive elements is picked 2097
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2104

288 Minimum time to finish tasks without skipping two consecutive 2105
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2114

289 Minimum time to write characters using insert, delete and copy operation 2115
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2117

18
Contents

290 Mobile Numeric Keypad Problem 2118


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2126

291 Modify array to maximize sum of adjacent differences 2127


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2132

292 Moser-de Bruijn Sequence 2133


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2144

293 Multistage Graph (Shortest Path) 2145


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2148

294 Newman-Conway Sequence 2149


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2156

295 Newman–Shanks–Williams prime 2157


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2164

296 Non-crossing lines to connect points in a circle 2165


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2172

297 Non-decreasing subsequence of size k with minimum sum 2173


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2179

298 Number of Co-prime pairs obtained from the sum of digits of elements
in the given range 2180
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2186

299 Number of NGEs to the right 2187


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2190

300 Number of Unique BST with a given key | Dynamic Programming 2191
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2196

301 Number of arrays of size N whose elements are positive integers and
sum is K 2197
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2202

302 Number of circular tours that visit all petrol pumps 2203
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2206

303 Number of decimal numbers of length k, that are strict monotone 2207
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2212

304 Number of different cyclic paths of length N in a tetrahedron 2213


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2216

305 Number of n digit stepping numbers 2217


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2224

306 Number of n-digits non-decreasing integers 2225

19
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2231

307 Number of non-negative integral solutions of a + b + c = n 2232


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2239

308 Number of ordered pairs such that (Ai & Aj) = 0 2240
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2247

309 Number of palindromic paths in a matrix 2248


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2251

310 Number of palindromic subsequences of length k where k <= 3 2252


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2260

311 Number of paths from source to destination in a directed acyclic graph 2261
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2264

312 Number of paths with exactly k coins 2265


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2270

313 Number of permutation with K inversions 2271


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2276

314 Number of subsequences in a string divisible by n 2277


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2280

315 Number of subsequences of the form a^i b^j c^k 2281


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2289

316 Number of subsets with sum divisible by m 2290


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2292

317 Number of substrings divisible by 8 but not by 3 2293


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2300

318 Number of ways a convex polygon of n+2 sides can split into triangles
by connecting vertices 2301
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2306

319 Number of ways to arrange N items under given constraints 2307


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2309

320 Number of ways to form a heap with n distinct integers 2310


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2314

321 Number of ways to form an array with distinct adjacent elements 2315
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2324

322 Number of ways to insert a character to increase the LCS by one 2325
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2328

20
Contents

323 Number of ways to reach Nth floor by taking at-most K leaps 2329
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2336

324 Number of ways to represent a number as sum of k fibonacci numbers2337


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2339

325 Padovan Sequence 2340


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2345

326 Painting Fence Algorithm 2346


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2350

327 Paper Cut into Minimum Number of Squares | Set 2 2351


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2358

328 Partition a set into two subsets such that the difference of subset sums
is minimum 2359
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2367

329 Partitioning into two contiguous element subarrays with equal sums 2368
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2371

330 Path with maximum average value 2372


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2377

331 Perfect Sum Problem (Print all subsets with given sum) 2378
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2383

332 Permutation Coefficient 2384


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2398

333 Prefix Sum of Matrix (Or 2D Array) 2399


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2406

334 Print Fibonacci Series in reverse order 2407


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2412

335 Print Fibonacci sequence using 2 variables 2413


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2420

336 Print Longest Palindromic Subsequence 2421


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2423

337 Print Maximum Length Chain of Pairs 2424


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2427

338 Print all distinct characters of a string in order (3 Methods) 2428


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2436

339 Print all longest common sub-sequences in lexicographical order 2437


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2440

21
Contents

340 Print all possible ways to convert one string into another string | Edit-
Distance 2441
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2449

341 Print equal sum sets of array (Partition Problem) | Set 2 2450
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2459

342 Print equal sum sets of array (Partition problem) | Set 1 2460
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2473

343 Print n terms of Newman-Conway Sequence 2474


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2478

344 Printing Items in 0/1 Knapsack 2479


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2484

345 Printing Longest Bitonic Subsequence 2485


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2489

346 Printing Longest Common Subsequence | Set 2 (Printing All) 2490


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2493

347 Printing Maximum Sum Increasing Subsequence 2494


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2497

348 Printing Shortest Common Supersequence 2498


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2502

349 Printing brackets in Matrix Chain Multiplication Problem 2503


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2507

350 Printing longest Increasing consecutive subsequence 2508


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2510

351 Probability of Knight to remain in the chessboard 2511


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2519

352 Probability of getting at least K heads in N tosses of Coins 2520


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2527

353 Probability of reaching a point with 2 or 3 steps at a time 2528


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2532

354 Program for Bridge and Torch problem 2533


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2537

355 Program for Fibonacci numbers 2538


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2560

356 Program for nth Catalan Number 2561


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2569

22
Contents

357 Program to find amount of water in a given glass 2570


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2579

358 Pyramid form (increasing then decreasing) consecutive array using


reduce operations 2580
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2583

359 Queries on number of Binary sub-matrices of Given size 2584


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2592

360 Queries to find distance between two nodes of a Binary tree 2593
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2595

361 Recursively break a number in 3 parts to get maximum sum 2596


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2602

362 Remove array end element to maximize the sum of product 2603
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2604

363 Remove minimum elements from either side such that 2*min becomes
more than max 2605
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2610

364 Rencontres Number (Counting partial derangements) 2611


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2624

365 Semiperfect Number 2625


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2627

366 Sequence Alignment problem 2628


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2639

367 Sequences of given length where every element is more than or equal
to twice of previous 2640
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2650

368 Shortest Common Supersequence 2651


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2664

369 Shortest Uncommon Subsequence 2665


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2669

370 Shortest path with exactly k edges in a directed and weighted graph 2670
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2676

371 Shortest possible combination of two strings 2677


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2687

372 Sieve of Eratosthenes 2688


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2695

23
Contents

373 Size of The Subarray With Maximum Sum 2696


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2701

374 Size of array after repeated deletion of LIS 2702


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2705

375 Smallest length string with repeated replacement of two distinct adjacent 2706
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2711

376 Smallest number with given sum of digits and sum of square of digits 2712
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2715

377 Smallest sum contiguous subarray 2716


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2722

378 Space and time efficient Binomial Coefficient 2723


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2727

379 Sub-tree with minimum color difference in a 2-coloured tree 2728


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2731

380 Subset Sum Problem in O(sum) space 2732


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2736

381 Subset with sum divisible by m 2737


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2745

382 Sudo Placement[1.5] | Wolfish 2746


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2750

383 Sum of all substrings of a string representing a number | Set 1 2751


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2757

384 Sum of all substrings of a string representing a number | Set 2 (Con-


stant Extra Space) 2758
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2763

385 Sum of average of all subsets 2764


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2772

386 Sum of elements of all partitions of number such that no element is


less than K 2773
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2778

387 Sum of product of consecutive Binomial Coefficients 2779


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2786

388 Sum of product of r and rth Binomial Coefficient (r * nCr) 2787


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2794

389 Sum of products of all combination taken (1 to n) at a time 2795

24
Contents

Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2804

390 Super Ugly Number (Number whose prime factors are in given set) 2805
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2808

391 Tabulation vs Memoizatation 2809


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2811

392 Temple Offerings 2812


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2820

393 Tetranacci Numbers 2821


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2826

394 The Two Water Jug Puzzle 2827


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2831

395 The painter’s partition problem 2832


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2845

396 The painter’s partition problem | Set 2 2846


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2855

397 Tile Stacking Problem 2856


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2858

398 Tiling Problem 2859


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2860

399 Tiling with Dominoes 2861


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2867

400 Total number of decreasing paths in a matrix 2868


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2875

401 Total number of non-decreasing numbers with n digits 2876


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2884

402 Total number of possible Binary Search Trees and Binary Trees with
n keys 2885
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2895

403 Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming) 2896
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2897

404 Traversal of tree with k jumps allowed between nodes of same height 2898
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2903

405 Ugly Numbers 2904


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2918

25
Contents

406 Unbounded Knapsack (Repetition of items allowed) 2919


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2925

407 Unique paths in a Grid with Obstacles 2926


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2928

408 Value of continuous floor function : F(x) = F(floor(x/2)) + x 2929


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2933

409 Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree) 2934
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2939

410 Water Jug Problem using Memoization 2940


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2942

411 Ways of transforming one string to other by removing 0 or more char-


acters 2943
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2944

412 Ways to arrange Balls such that adjacent balls are of different types 2945
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2958

413 Ways to sum to N using array elements with repetition allowed 2959
Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2963

414 Ways to write n as sum of two or more positive integers 2964


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2968

415 Weighted Job Scheduling 2969


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2974

416 Weighted Job Scheduling in O(n Log n) time 2975


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2982

417 Weighted Job Scheduling | Set 2 (Using LIS) 2983


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2986

418 Weird Number 2987


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2994

419 WildCard pattern matching having three symbols ( * , + , ? ) 2995


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2999

420 Wildcard Pattern Matching 3000


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3007

421 Word Wrap problem ( Space optimized solution ) 3008


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3014

422 n-th number with digits in {0, 1, 2, 3, 4, 5} 3015


Source . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3020

26
Chapter 1

DP-01 | Overlapping
Subproblems Property in
Dynamic Programming

Overlapping Subproblems Property in Dynamic Programming | DP-1 - GeeksforGeeks


Dynamic Programming is an algorithmic paradigm that solves a given complex problem by
breaking it into subproblems and stores the results of subproblems to avoid computing the
same results again. Following are the two main properties of a problem that suggests that
the given problem can be solved using Dynamic programming.
In this post, we will discuss first property (Overlapping Subproblems) in detail. The second
property of Dynamic programming is discussed in next post i.e. Set 2.
1) Overlapping Subproblems
2) Optimal Substructure
1) Overlapping Subproblems:
Like Divide and Conquer, Dynamic Programming combines solutions to sub-problems. Dy-
namic Programming is mainly used when solutions of same subproblems are needed again
and again. In dynamic programming, computed solutions to subproblems are stored in a
table so that these don’t have to be recomputed. So Dynamic Programming is not useful
when there are no common (overlapping) subproblems because there is no point storing the
solutions if they are not needed again. For example, Binary Search doesn’t have common
subproblems. If we take an example of following recursive program for Fibonacci Numbers,
there are many subproblems which are solved again and again.

/* simple recursive program for Fibonacci numbers */


int fib(int n)
{
   if ( n <= 1 )
      return n;
   return fib(n-1) + fib(n-2);

27
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

Recursion tree for execution of fib(5)

fib(5)
/ \
fib(4) fib(3)
/ \ / \
fib(3) fib(2) fib(2) fib(1)
/ \ / \ / \
fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
/ \
fib(1) fib(0)

We can see that the function fib(3) is being called 2 times. If we would have stored the
value of fib(3), then instead of computing it again, we could have reused the old stored value.
There are following two different ways to store the values so that these values can be reused:
a) Memoization (Top Down)
b) Tabulation (Bottom Up)
a) Memoization (Top Down): The memoized program for a problem is similar to the
recursive version with a small modification that it looks into a lookup table before computing
solutions. We initialize a lookup array with all initial values as NIL. Whenever we need the
solution to a subproblem, we first look into the lookup table. If the precomputed value is
there then we return that value, otherwise, we calculate the value and put the result in the
lookup table so that it can be reused later.
Following is the memoized version for nth Fibonacci Number.
C/C++

/* C/C++ program for Memoized version for nth Fibonacci number */


#include<stdio.h>
#define NIL -1
#define MAX 100
  
int lookup[MAX];
  
/* Function to initialize NIL values in lookup table */
void _initialize()
{
  int i;
  for (i = 0; i < MAX; i++)
    lookup[i] = NIL;
}
  
/* function for nth Fibonacci number */
int fib(int n)

28
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

{
   if (lookup[n] == NIL)
   {
      if (n <= 1)
         lookup[n] = n;
      else
         lookup[n] = fib(n-1) + fib(n-2);
   }
  
   return lookup[n];
}
  
int main ()
{
  int n = 40;
  _initialize();
  printf("Fibonacci number is %d ", fib(n));
  return 0;
}

Java

/* Java program for Memoized version */


public class Fibonacci
{
  final int MAX = 100;
  final int NIL = -1;
  
  int lookup[] = new int[MAX];
  
  /* Function to initialize NIL values in lookup table */
  void _initialize()
  {
    for (int i = 0; i < MAX; i++)
        lookup[i] = NIL;
  }
  
  /* function for nth Fibonacci number */
  int fib(int n)
  {
    if (lookup[n] == NIL)
    {
      if (n <= 1)
          lookup[n] = n;
      else
          lookup[n] = fib(n-1) + fib(n-2);
    }
    return lookup[n];

29
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

  }
  
  public static void main(String[] args)
  {
    Fibonacci f = new Fibonacci();
    int n = 40;
    f._initialize();
    System.out.println("Fibonacci number is" + " " + f.fib(n));
  }
  
}
// This Code is Contributed by Saket Kumar

Python

# Python program for Memoized version of nth Fibonacci number


  
# Function to calculate nth Fibonacci number
def fib(n, lookup):
  
    # Base case
    if n == 0 or n == 1 :
        lookup[n] = n
  
    # If the value is not calculated previously then calculate it
    if lookup[n] is None:
        lookup[n] = fib(n-1 , lookup)  + fib(n-2 , lookup) 
  
    # return the value corresponding to that value of n
    return lookup[n]
# end of function
  
# Driver program to test the above function
def main():
    n = 34 
    # Declaration of lookup table
    # Handles till n = 100 
    lookup = [None]*(101)
    print "Fibonacci Number is ", fib(n, lookup)
  
if __name__=="__main__":
    main()
  
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

C#

// C# program for Memoized versionof nth Fibonacci number 

30
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

using System;
  
class GFG
{
      
    static int MAX = 100;
    static int NIL = -1;
    static int []lookup = new int[MAX];
      
    /* Function to initialize NIL 
    values in lookup table */
    static void initialize()
    {
        for (int i = 0; i < MAX; i++)
            lookup[i] = NIL;
    }
      
    /* function for nth Fibonacci number */
    static int fib(int n)
    {
        if (lookup[n] == NIL)
        {
        if (n <= 1)
            lookup[n] = n;
        else
            lookup[n] = fib(n - 1) + fib(n - 2);
        }
        return lookup[n];
    }
      
    // Driver code
    public static void Main()
    {
      
        int n = 40;
        initialize();
        Console.Write("Fibonacci number is" + " " + fib(n));
    }
}
  
// This Code is Contributed by Sam007

b) Tabulation (Bottom Up): The tabulated program for a given problem builds a table
in bottom up fashion and returns the last entry from table. For example, for the same
Fibonacci number, we first calculate fib(0) then fib(1) then fib(2) then fib(3) and so on. So
literally, we are building the solutions of subproblems bottom-up.
Following is the tabulated version for nth Fibonacci Number.

31
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

C/C++

/* C program for Tabulated version */


#include<stdio.h>
int fib(int n)
{
  int f[n+1];
  int i;
  f[0] = 0;   f[1] = 1; 
  for (i = 2; i <= n; i++)
      f[i] = f[i-1] + f[i-2];
  
  return f[n];
}
   
int main ()
{
  int n = 9;
  printf("Fibonacci number is %d ", fib(n));
  return 0;
}

Java

/* Java program for Tabulated version */


public class Fibonacci
{
  int fib(int n)
  {
    int f[] = new int[n+1];
    f[0] = 0;
    f[1] = 1;
    for (int i = 2; i <= n; i++)
          f[i] = f[i-1] + f[i-2];
    return f[n];
  }
  
  public static void main(String[] args)
  {
    Fibonacci f = new Fibonacci();
    int n = 9;
    System.out.println("Fibonacci number is" + " " + f.fib(n));
  }
  
}
// This Code is Contributed by Saket Kumar

Python

32
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

# Python program Tabulated (bottom up) version


def fib(n):
  
    # array declaration
    f = [0]*(n+1)
  
    # base case assignment
    f[1] = 1
  
    # calculating the fibonacci and storing the values
    for i in xrange(2 , n+1):
        f[i] = f[i-1] + f[i-2]
    return f[n]
  
# Driver program to test the above function
def main():
    n = 9
    print "Fibonacci number is " , fib(n)
  
if __name__=="__main__":
    main()
  
# This code is contributed by Nikhil Kumar Singh (nickzuck_007)

C#

// C# program for Tabulated version


using System;
  
class GFG
{
    static int fib(int n)
    {
        int []f = new int[n + 1];
        f[0] = 0;
        f[1] = 1;
        for (int i = 2; i <= n; i++)
            f[i] = f[i - 1] + f[i - 2];
        return f[n];
    }
      
    public static void Main()
    {
          
        int n = 9;
        Console.Write("Fibonacci number is" + " " + fib(n));
    }
}

33
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

  
// This Code is Contributed by Sam007

PHP

<?php
// PHP program for Tabulated version
  
function fib($n)
{
    $f[$n + 1]=0;
    $i;
    $f[0] = 0;
    $f[1] = 1; 
    for ($i = 2; $i <= $n; $i++)
        $f[$i] = $f[$i - 1] + 
                 $f[$i - 2];
      
    return $f[$n];
}
  
// Driver Code
$n = 9;
echo("Fibonacci number is "); 
echo(fib($n));
  
// This code is contributed by nitin mittal.
?>

Output:

Fibonacci number is 34

Both Tabulated and Memoized store the solutions of subproblems. In Memoized version,
table is filled on demand while in Tabulated version, starting from the first entry, all entries
are filled one by one. Unlike the Tabulated version, all entries of the lookup table are not
necessarily filled in Memoized version. For example, Memoized solution of the LCS problem
doesn’t necessarily fill all entries.
To see the optimization achieved by Memoized and Tabulated solutions over the basic Re-
cursive solution, see the time taken by following runs for calculating 40th Fibonacci number:
Recursive solution
Memoized solution
Tabulated solution
Time taken by Recursion method is much more than the two Dynamic Programming tech-
niques mentioned above – Memoization and Tabulation!

34
Chapter 1. DP-01 | Overlapping Subproblems Property in Dynamic Programming

Also, see method 2 of Ugly Number post for one more simple example where we have
overlapping subproblems and we store the results of subproblems.
We will be covering Optimal Substructure Property and some more example problems in
future posts on Dynamic Programming.
Try following questions as an exercise of this post.
1) Write a Memoized solution for LCS problem. Note that the Tabular solution is given in
the CLRS book.
2) How would you choose between Memoization and Tabulation?
References:
http://www.youtube.com/watch?v=V5hZoJ6uK-s
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/overlapping-subproblems-property-in-dynamic-programming-dp-1/

35
Chapter 2

DP-02 | Optimal Substructure


Property in Dynamic
Programming

Optimal Substructure Property in Dynamic Programming | DP-2 - GeeksforGeeks


As we discussed in Set 1, following are the two main properties of a problem that suggest
that the given problem can be solved using Dynamic programming:
1) Overlapping Subproblems
2) Optimal Substructure
We have already discussed Overlapping Subproblem property in the Set 1. Let us discuss
Optimal Substructure property here.
2) Optimal Substructure: A given problems has Optimal Substructure Property if op-
timal solution of the given problem can be obtained by using optimal solutions of its sub-
problems.
For example, the Shortest Path problem has following optimal substructure property:
If a node x lies in the shortest path from a source node u to destination node v then the
shortest path from u to v is combination of shortest path from u to x and shortest path
from x to v. The standard All Pair Shortest Path algorithms like Floyd–Warshall and
Bellman–Fordare typical examples of Dynamic Programming.
On the other hand, the Longest Path problem doesn’t have the Optimal Substructure prop-
erty. Here by Longest Path we mean longest simple path (path without cycle) between two
nodes. Consider the following unweighted graph given in the CLRS book. There are two
longest paths from q to t: q→r→t and q→s→t. Unlike shortest paths, these longest paths
do not have the optimal substructure property. For example, the longest path q→r→t is
not a combination of longest path from q to r and longest path from r to t, because the
longest path from q to r is q→s→t→r and the longest path from r to t is r→q→s→t.

36
Chapter 2. DP-02 | Optimal Substructure Property in Dynamic Programming

We will be covering some example problems in future posts on Dynamic Programming.


References:
http://en.wikipedia.org/wiki/Optimal_substructure
CLRS book
Improved By : ASAJ RAWAT

Source

https://www.geeksforgeeks.org/optimal-substructure-property-in-dynamic-programming-dp-2/

37
Chapter 3

DP-03 | Longest Increasing


Subsequence

Longest Increasing Subsequence | DP-3 - GeeksforGeeks


We have discussed Overlapping Subproblems and Optimal Substructure properties.
Let us discuss Longest Increasing Subsequence (LIS) problem as an example problem that
can be solved using Dynamic Programming.
The Longest Increasing Subsequence (LIS) problem is to find the length of the longest
subsequence of a given sequence such that all elements of the subsequence are sorted in
increasing order. For example, the length of LIS for {10, 22, 9, 33, 21, 50, 41, 60, 80} is 6
and LIS is {10, 22, 33, 50, 60, 80}.

More Examples:

Input : arr[] = {3, 10, 2, 1, 20}


Output : Length of LIS = 3
The longest increasing subsequence is 3, 10, 20

Input : arr[] = {3, 2}


Output : Length of LIS = 1
The longest increasing subsequences are {3} and {2}

Input : arr[] = {50, 3, 10, 7, 40, 80}


Output : Length of LIS = 4
The longest increasing subsequence is {3, 7, 40, 80}

38
Chapter 3. DP-03 | Longest Increasing Subsequence

Optimal Substructure:
Let arr[0..n-1] be the input array and L(i) be the length of the LIS ending at index i such
that arr[i] is the last element of the LIS.
Then, L(i) can be recursively written as:
L(i) = 1 + max( L(j) ) where 0 < j < i and arr[j] < arr[i]; or
L(i) = 1, if no such j exists.
To find the LIS for a given array, we need to return max(L(i)) where 0 < i < n.
Thus, we see the LIS problem satisfies the optimal substructure property as the main prob-
lem can be solved using solutions to subproblems.
Following is a simple recursive implementation of the LIS problem. It follows the recursive
structure discussed above.
C/C++

/* A Naive C/C++ recursive implementation of LIS problem */


#include<stdio.h>
#include<stdlib.h>
  
/* To make use of recursive calls, this function must return
   two things:
   1) Length of LIS ending with element arr[n-1]. We use
      max_ending_here for this purpose
   2) Overall maximum as the LIS may end with an element
      before arr[n-1] max_ref is used this purpose.
   The value of LIS of full array of size n is stored in
   *max_ref which is our final result */
int _lis( int arr[], int n, int *max_ref)
{
    /* Base case */
    if (n == 1)
        return 1;
  
    // 'max_ending_here' is length of LIS ending with arr[n-1]
    int res, max_ending_here = 1; 
  
    /* Recursively get all LIS ending with arr[0], arr[1] ...
       arr[n-2]. If   arr[i-1] is smaller than arr[n-1], and
       max ending with arr[n-1] needs to be updated, then
       update it */
    for (int i = 1; i < n; i++)
    {
        res = _lis(arr, i, max_ref);
        if (arr[i-1] < arr[n-1] && res + 1 > max_ending_here)
            max_ending_here = res + 1;
    }
  
    // Compare max_ending_here with the overall max. And
    // update the overall max if needed

39
Chapter 3. DP-03 | Longest Increasing Subsequence

    if (*max_ref < max_ending_here)


       *max_ref = max_ending_here;
  
    // Return length of LIS ending with arr[n-1]
    return max_ending_here;
}
  
// The wrapper function for _lis()
int lis(int arr[], int n)
{
    // The max variable holds the result
    int max = 1;
  
    // The function _lis() stores its result in max
    _lis( arr, n, &max );
  
    // returns max
    return max;
}
  
/* Driver program to test above function */
int main()
{
    int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Length of lis is %dn",
           lis( arr, n ));
    return 0;
}

Java

/* A Naive Java Program for LIS Implementation */


class LIS
{
   static int max_ref; // stores the LIS
  
   /* To make use of recursive calls, this function must return
   two things:
   1) Length of LIS ending with element arr[n-1]. We use
      max_ending_here for this purpose
   2) Overall maximum as the LIS may end with an element
      before arr[n-1] max_ref is used this purpose.
   The value of LIS of full array of size n is stored in
   *max_ref which is our final result */
   static int _lis(int arr[], int n)
   {
       // base case

40
Chapter 3. DP-03 | Longest Increasing Subsequence

       if (n == 1)
           return 1;
  
       // 'max_ending_here' is length of LIS ending with arr[n-1]
       int res, max_ending_here = 1;
  
        /* Recursively get all LIS ending with arr[0], arr[1] ...
           arr[n-2]. If   arr[i-1] is smaller than arr[n-1], and
           max ending with arr[n-1] needs to be updated, then
           update it */
        for (int i = 1; i < n; i++)
        {
            res = _lis(arr, i);
            if (arr[i-1] < arr[n-1] && res + 1 > max_ending_here)
                max_ending_here = res + 1;
        }
  
        // Compare max_ending_here with the overall max. And
        // update the overall max if needed
        if (max_ref < max_ending_here)
           max_ref = max_ending_here;
  
        // Return length of LIS ending with arr[n-1]
        return max_ending_here;
   }
  
    // The wrapper function for _lis()
    static int lis(int arr[], int n)
    {
        // The max variable holds the result
         max_ref = 1;
  
        // The function _lis() stores its result in max
        _lis( arr, n);
  
        // returns max
        return max_ref;
    }
  
    // driver program to test above functions
    public static void main(String args[])
    {
        int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
        int n = arr.length;
        System.out.println("Length of lis is "
                           + lis(arr, n) + "n");
    }
 }

41
Chapter 3. DP-03 | Longest Increasing Subsequence

/*This code is contributed by Rajat Mishra*/

Python

# A naive Python implementation of LIS problem


  
""" To make use of recursive calls, this function must return
 two things:
 1) Length of LIS ending with element arr[n-1]. We use
 max_ending_here for this purpose
 2) Overall maximum as the LIS may end with an element
 before arr[n-1] max_ref is used this purpose.
 The value of LIS of full array of size n is stored in
 *max_ref which is our final result """
  
# global variable to store the maximum
global maximum
  
def _lis(arr , n ):
  
    # to allow the access of global variable
    global maximum
  
    # Base Case
    if n == 1 :
        return 1
  
    # maxEndingHere is the length of LIS ending with arr[n-1]
    maxEndingHere = 1
  
    """Recursively get all LIS ending with arr[0], arr[1]..arr[n-2]
       IF arr[n-1] is maller than arr[n-1], and max ending with
       arr[n-1] needs to be updated, then update it"""
    for i in xrange(1, n):
        res = _lis(arr , i)
        if arr[i-1] < arr[n-1] and res+1 > maxEndingHere:
            maxEndingHere = res +1
  
    # Compare maxEndingHere with overall maximum. And
    # update the overall maximum if needed
    maximum = max(maximum , maxEndingHere)
  
    return maxEndingHere
  
def lis(arr):
  
    # to allow the access of global variable
    global maximum

42
Chapter 3. DP-03 | Longest Increasing Subsequence

  
    # lenght of arr
    n = len(arr)
  
    # maximum variable holds the result
    maximum = 1
  
    # The function _lis() stores its result in maximum
    _lis(arr , n)
  
    return maximum
  
# Driver program to test the above function
arr = [10 , 22 , 9 , 33 , 21 , 50 , 41 , 60]
n = len(arr)
print "Length of lis is ", lis(arr)
  
# This code is contributed by NIKHIL KUMAR SINGH

Length of lis is 5

Overlapping Subproblems:
Considering the above implementation, following is recursion tree for an array of size 4.
lis(n) gives us the length of LIS for arr[].

lis(4)
/ |
lis(3) lis(2) lis(1)
/ /
lis(2) lis(1) lis(1)
/
lis(1)

We can see that there are many subproblems which are solved again and again. So this
problem has Overlapping Substructure property and recomputation of same subproblems
can be avoided by either using Memoization or Tabulation. Following is a tabluated imple-
mentation for the LIS problem.
C/C++

/* Dynamic Programming C/C++ implementation of LIS problem */


#include<stdio.h>
#include<stdlib.h>
  
/* lis() returns the length of the longest increasing
  subsequence in arr[] of size n */
int lis( int arr[], int n )

43
Chapter 3. DP-03 | Longest Increasing Subsequence

{
    int *lis, i, j, max = 0;
    lis = (int*) malloc ( sizeof( int ) * n );
  
    /* Initialize LIS values for all indexes */
    for (i = 0; i < n; i++ )
        lis[i] = 1;
  
    /* Compute optimized LIS values in bottom up manner */
    for (i = 1; i < n; i++ )
        for (j = 0; j < i; j++ ) 
            if ( arr[i] > arr[j] && lis[i] < lis[j] + 1)
                lis[i] = lis[j] + 1;
  
    /* Pick maximum of all LIS values */
    for (i = 0; i < n; i++ )
        if (max < lis[i])
            max = lis[i];
  
    /* Free memory to avoid memory leak */
    free(lis);
  
    return max;
}
  
/* Driver program to test above function */
int main()
{
    int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Length of lis is %dn", lis( arr, n ) );
    return 0;
}

Java

/* Dynamic Programming Java implementation of LIS problem */


  
class LIS
{
    /* lis() returns the length of the longest increasing
       subsequence in arr[] of size n */
    static int lis(int arr[],int n)
    {
          int lis[] = new int[n];
          int i,j,max = 0;
  
          /* Initialize LIS values for all indexes */

44
Chapter 3. DP-03 | Longest Increasing Subsequence

           for ( i = 0; i < n; i++ )


              lis[i] = 1;
  
           /* Compute optimized LIS values in bottom up manner */
           for ( i = 1; i < n; i++ )
              for ( j = 0; j < i; j++ ) 
                         if ( arr[i] > arr[j] && lis[i] < lis[j] + 1)
                    lis[i] = lis[j] + 1;
  
           /* Pick maximum of all LIS values */
           for ( i = 0; i < n; i++ )
              if ( max < lis[i] )
                 max = lis[i];
  
            return max;
    }
  
    public static void main(String args[])
    {
        int arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 };
            int n = arr.length;
            System.out.println("Length of lis is " + lis( arr, n ) + "n" );
    }
}
/*This code is contributed by Rajat Mishra*/

Python

# Dynamic programming Python implementation of LIS problem


  
# lis returns length of the longest increasing subsequence
# in arr of size n
def lis(arr):
    n = len(arr)
  
    # Declare the list (array) for LIS and initialize LIS
    # values for all indexes
    lis = [1]*n
  
    # Compute optimized LIS values in bottom up manner
    for i in range (1 , n):
        for j in range(0 , i):
            if arr[i] > arr[j] and lis[i]< lis[j] + 1 :
                lis[i] = lis[j]+1
  
    # Initialize maximum to 0 to get the maximum of all
    # LIS
    maximum = 0

45
Chapter 3. DP-03 | Longest Increasing Subsequence

  
    # Pick maximum of all LIS values
    for i in range(n):
        maximum = max(maximum , lis[i])
  
    return maximum
# end of lis function
  
# Driver program to test above function
arr = [10, 22, 9, 33, 21, 50, 41, 60]
print "Length of lis is", lis(arr)
# This code is contributed by Nikhil Kumar Singh

Output:

Length of lis is 5

Note that the time complexity of the above Dynamic Programming (DP) solution is O(n^2)
and there is a O(nLogn) solution for the LIS problem. We have not discussed the O(n Log
n) solution here as the purpose of this post is to explain Dynamic Programming with a
simple example. See below post for O(n Log n) solution.
Longest Increasing Subsequence Size (N log N)

• Printing LIS of array


• Recent articles based on LIS!

Source

https://www.geeksforgeeks.org/longest-increasing-subsequence-dp-3/

46
Chapter 4

DP-04 | Longest Common


Subsequence

Longest Common Subsequence | DP-4 - GeeksforGeeks


We have discussed Overlapping Subproblems and Optimal Substructure properties in Set
1 and Set 2 respectively. We also discussed one example problem in Set 3. Let us discuss
Longest Common Subsequence (LCS) problem as one more example problem that can be
solved using Dynamic Programming.
LCS Problem Statement: Given two sequences, find the length of longest subsequence present
in both of them. A subsequence is a sequence that appears in the same relative order, but
not necessarily contiguous. For example, “abc”, “abg”, “bdf”, “aeg”, ‘”acefg”, .. etc are
subsequences of “abcdefg”. So a string of length n has 2^n different possible subsequences.
It is a classic computer science problem, the basis of diff(a file comparison program that
outputs the differences between two files), and has applications in bioinformatics.
Examples:
LCS for input Sequences “ABCDGH” and “AEDFHR” is “ADH” of length 3.
LCS for input Sequences “AGGTAB” and “GXTXAYB” is “GTAB” of length 4.
The naive solution for this problem is to generate all subsequences of both given sequences
and find the longest matching subsequence. This solution is exponential in term of time
complexity. Let us see how this problem possesses both important properties of a Dynamic
Programming (DP) Problem.
1) Optimal Substructure:
Let the input sequences be X[0..m-1] and Y[0..n-1] of lengths m and n respectively. And let
L(X[0..m-1], Y[0..n-1]) be the length of LCS of the two sequences X and Y. Following is the
recursive definition of L(X[0..m-1], Y[0..n-1]).
If last characters of both sequences match (or X[m-1] == Y[n-1]) then
L(X[0..m-1], Y[0..n-1]) = 1 + L(X[0..m-2], Y[0..n-2])
If last characters of both sequences do not match (or X[m-1] != Y[n-1]) then
L(X[0..m-1], Y[0..n-1]) = MAX ( L(X[0..m-2], Y[0..n-1]), L(X[0..m-1], Y[0..n-2]) )

47
Chapter 4. DP-04 | Longest Common Subsequence

Examples:
1) Consider the input strings “AGGTAB” and “GXTXAYB”. Last characters match for the
strings. So length of LCS can be written as:
L(“AGGTAB”, “GXTXAYB”) = 1 + L(“AGGTA”, “GXTXAY”)

2) Consider the input strings “ABCDGH” and “AEDFHR. Last characters do not match
for the strings. So length of LCS can be written as:
L(“ABCDGH”, “AEDFHR”) = MAX ( L(“ABCDG”, “AEDFHR”), L(“ABCDGH”,
“AEDFH”) )
So the LCS problem has optimal substructure property as the main problem can be solved
using solutions to subproblems.
2) Overlapping Subproblems:
Following is simple recursive implementation of the LCS problem. The implementation
simply follows the recursive structure mentioned above.
C/C++

/* A Naive recursive implementation of LCS problem */


#include<bits/stdc++.h>
  
int max(int a, int b);
  
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int lcs( char *X, char *Y, int m, int n )
{
   if (m == 0 || n == 0)
     return 0;
   if (X[m-1] == Y[n-1])
     return 1 + lcs(X, Y, m-1, n-1);
   else
     return max(lcs(X, Y, m, n-1), lcs(X, Y, m-1, n));
}
  
/* Utility function to get max of 2 integers */

48
Chapter 4. DP-04 | Longest Common Subsequence

int max(int a, int b)


{
    return (a > b)? a : b;
}
  
/* Driver program to test above function */
int main()
{
  char X[] = "AGGTAB";
  char Y[] = "GXTXAYB";
  
  int m = strlen(X);
  int n = strlen(Y);
  
  printf("Length of LCS is %d", lcs( X, Y, m, n ) );
  
  return 0;
}

Java

/* A Naive recursive implementation of LCS problem in java*/


public class LongestCommonSubsequence
{
  
  /* Returns length of LCS for X[0..m-1], Y[0..n-1] */
  int lcs( char[] X, char[] Y, int m, int n )
  {
    if (m == 0 || n == 0)
      return 0;
    if (X[m-1] == Y[n-1])
      return 1 + lcs(X, Y, m-1, n-1);
    else
      return max(lcs(X, Y, m, n-1), lcs(X, Y, m-1, n));
  }
  
  /* Utility function to get max of 2 integers */
  int max(int a, int b)
  {
    return (a > b)? a : b;
  }
  
  public static void main(String[] args)
  {
    LongestCommonSubsequence lcs = new LongestCommonSubsequence();
    String s1 = "AGGTAB";
    String s2 = "GXTXAYB";
  

49
Chapter 4. DP-04 | Longest Common Subsequence

    char[] X=s1.toCharArray();
    char[] Y=s2.toCharArray();
    int m = X.length;
    int n = Y.length;
  
    System.out.println("Length of LCS is" + " " +
                                  lcs.lcs( X, Y, m, n ) );
  }
  
}
  
// This Code is Contributed by Saket Kumar

Python

# A Naive recursive Python implementation of LCS problem


  
def lcs(X, Y, m, n):
  
    if m == 0 or n == 0:
       return 0;
    elif X[m-1] == Y[n-1]:
       return 1 + lcs(X, Y, m-1, n-1);
    else:
       return max(lcs(X, Y, m, n-1), lcs(X, Y, m-1, n));
  
  
# Driver program to test the above function
X = "AGGTAB"
Y = "GXTXAYB"
print "Length of LCS is ", lcs(X , Y, len(X), len(Y))

C#

/* C#  Naive recursive implementation of LCS problem */


using System;
  
class GFG
{
      
  
    /* Returns length of LCS for X[0..m-1], Y[0..n-1] */
    static int lcs( char[] X, char[] Y, int m, int n )
    {
        if (m == 0 || n == 0)
        return 0;
        if (X[m - 1] == Y[n - 1])

50
Chapter 4. DP-04 | Longest Common Subsequence

        return 1 + lcs(X, Y, m - 1, n - 1);


        else
        return max(lcs(X, Y, m, n - 1), lcs(X, Y, m - 1, n));
    }
      
    /* Utility function to get max of 2 integers */
    static int max(int a, int b)
    {
        return (a > b)? a : b;
    }
      
    public static void Main()
    {
        String s1 = "AGGTAB";
        String s2 = "GXTXAYB";
      
        char[] X=s1.ToCharArray();
        char[] Y=s2.ToCharArray();
        int m = X.Length;
        int n = Y.Length;
      
        Console.Write("Length of LCS is" + " " 
                      +lcs( X, Y, m, n ) );
    }
}
// This code is Contributed by Sam007

PHP

<?php 
// A Naive recursive PHP
// implementation of LCS problem 
function lcs($X, $Y, $m, $n)

    if($m == 0 || $n == 0) 
    return 0; 
    else if ($X[$m - 1] == $Y[$n - 1]) 
        return 1 + lcs($X, $Y, 
                       $m - 1, $n - 1); 
    else
        return max(lcs($X, $Y, $m, $n - 1), 
                   lcs($X, $Y, $m - 1, $n)); 
}
  
// Driver Code
$X = "AGGTAB";
$Y = "GXTXAYB";
echo "Length of LCS is ";

51
Chapter 4. DP-04 | Longest Common Subsequence

echo lcs($X , $Y, strlen($X),


                  strlen($Y)); 
  
// This code is contributed
// by Shivi_Aggarwal
?>

Output:

Length of LCS is 4

Time complexity of the above naive recursive approach is O(2^n) in worst case and worst
case happens when all characters of X and Y mismatch i.e., length of LCS is 0.
Considering the above implementation, following is a partial recursion tree for input strings
“AXYT” and “AYZX”

lcs("AXYT", "AYZX")
/
lcs("AXY", "AYZX") lcs("AXYT", "AYZ")
/ /
lcs("AX", "AYZX") lcs("AXY", "AYZ") lcs("AXY", "AYZ") lcs("AXYT", "AY")

In the above partial recursion tree, lcs(“AXY”, “AYZ”) is being solved twice. If we draw the
complete recursion tree, then we can see that there are many subproblems which are solved
again and again. So this problem has Overlapping Substructure property and recomputation
of same subproblems can be avoided by either using Memoization or Tabulation. Following
is a tabulated implementation for the LCS problem.
C/C++

/* Dynamic Programming C/C++ implementation of LCS problem */


#include<bits/stdc++.h>
   
int max(int a, int b);
   
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int lcs( char *X, char *Y, int m, int n )
{
   int L[m+1][n+1];
   int i, j;
   
   /* Following steps build L[m+1][n+1] in bottom up fashion. Note 
      that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */
   for (i=0; i<=m; i++)
   {
     for (j=0; j<=n; j++)
     {

52
Chapter 4. DP-04 | Longest Common Subsequence

       if (i == 0 || j == 0)
         L[i][j] = 0;
   
       else if (X[i-1] == Y[j-1])
         L[i][j] = L[i-1][j-1] + 1;
   
       else
         L[i][j] = max(L[i-1][j], L[i][j-1]);
     }
   }
     
   /* L[m][n] contains length of LCS for X[0..n-1] and Y[0..m-1] */
   return L[m][n];
}
   
/* Utility function to get max of 2 integers */
int max(int a, int b)
{
    return (a > b)? a : b;
}
   
/* Driver program to test above function */
int main()
{
  char X[] = "AGGTAB";
  char Y[] = "GXTXAYB";
   
  int m = strlen(X);
  int n = strlen(Y);
   
  printf("Length of LCS is %d", lcs( X, Y, m, n ) );
  
  return 0;
}

Java

/* Dynamic Programming Java implementation of LCS problem */


public class LongestCommonSubsequence
{
  
  /* Returns length of LCS for X[0..m-1], Y[0..n-1] */
  int lcs( char[] X, char[] Y, int m, int n )
  {
    int L[][] = new int[m+1][n+1];
  
    /* Following steps build L[m+1][n+1] in bottom up fashion. Note
         that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1] */

53
Chapter 4. DP-04 | Longest Common Subsequence

    for (int i=0; i<=m; i++)


    {
      for (int j=0; j<=n; j++)
      {
        if (i == 0 || j == 0)
            L[i][j] = 0;
        else if (X[i-1] == Y[j-1])
            L[i][j] = L[i-1][j-1] + 1;
        else
            L[i][j] = max(L[i-1][j], L[i][j-1]);
      }
    }
  return L[m][n];
  }
  
  /* Utility function to get max of 2 integers */
  int max(int a, int b)
  {
    return (a > b)? a : b;
  }
  
  public static void main(String[] args)
  {
    LongestCommonSubsequence lcs = new LongestCommonSubsequence();
    String s1 = "AGGTAB";
    String s2 = "GXTXAYB";
  
    char[] X=s1.toCharArray();
    char[] Y=s2.toCharArray();
    int m = X.length;
    int n = Y.length;
  
    System.out.println("Length of LCS is" + " " +
                                  lcs.lcs( X, Y, m, n ) );
  }
  
}
  
// This Code is Contributed by Saket Kumar

Python

# Dynamic Programming implementation of LCS problem


  
def lcs(X , Y):
    # find the length of the strings
    m = len(X)
    n = len(Y)

54
Chapter 4. DP-04 | Longest Common Subsequence

  
    # declaring the array for storing the dp values
    L = [[None]*(n+1) for i in xrange(m+1)]
  
    """Following steps build L[m+1][n+1] in bottom up fashion
    Note: L[i][j] contains length of LCS of X[0..i-1]
    and Y[0..j-1]"""
    for i in range(m+1):
        for j in range(n+1):
            if i == 0 or j == 0 :
                L[i][j] = 0
            elif X[i-1] == Y[j-1]:
                L[i][j] = L[i-1][j-1]+1
            else:
                L[i][j] = max(L[i-1][j] , L[i][j-1])
  
    # L[m][n] contains the length of LCS of X[0..n-1] & Y[0..m-1]
    return L[m][n]
#end of function lcs
  
  
# Driver program to test the above function
X = "AGGTAB"
Y = "GXTXAYB"
print "Length of LCS is ", lcs(X, Y)
  
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

C#

// Dynamic Programming C# implementation 


// of LCS problem 
using System;
  
class GFG
{
  
    /* Returns length of LCS for X[0..m-1], Y[0..n-1] */
    static int lcs( char[] X, char[] Y, int m, int n )
    {
        int [,]L = new int[m+1,n+1];
      
        /* Following steps build L[m+1][n+1] 
        in bottom up fashion. Note
        that L[i][j] contains length of 
        LCS of X[0..i-1] and Y[0..j-1] */
        for (int i = 0; i <= m; i++)
        {

55
Chapter 4. DP-04 | Longest Common Subsequence

            for (int j = 0; j <= n; j++)


            {
                if (i == 0 || j == 0)
                    L[i, j] = 0;
                else if (X[i - 1] == Y[j - 1])
                    L[i, j] = L[i - 1, j - 1] + 1;
                else
                    L[i, j] = max(L[i - 1, j], L[i, j - 1]);
            }
        }
        return L[m, n];
    }
      
    /* Utility function to get max of 2 integers */
    static int max(int a, int b)
    {
        return (a > b)? a : b;
    }
      
    // Driver code
    public static void Main()
    {
          
        String s1 = "AGGTAB";
        String s2 = "GXTXAYB";
      
        char[] X=s1.ToCharArray();
        char[] Y=s2.ToCharArray();
        int m = X.Length;
        int n = Y.Length;
      
        Console.Write("Length of LCS is" + " " +lcs( X, Y, m, n ) );
    }
}
// This Code is Contributed by Sam007 

PHP

<?php 
// Dynamic Programming C# 
// implementation of LCS problem 
function lcs($X , $Y)
{
// find the length of the strings 
$m = strlen($X); 
$n = strlen($Y) ;
  
// declaring the array for 

56
Chapter 4. DP-04 | Longest Common Subsequence

// storing the dp values 


  
/*Following steps build L[m+1][n+1] 
in bottom up fashion .
Note: L[i][j] contains length of 
LCS of X[0..i-1] and Y[0..j-1] */
for ($i = 0; $i <= $m; $i++) 

for ($j = 0; $j <= $n; $j++) 

    if ($i == 0 || $j == 0) 
    $L[$i][$j] = 0; 
  
    else if ($X[$i - 1] == $Y[$j - 1]) 
    $L[$i][$j] = $L[$i - 1][$j - 1] + 1; 
  
    else
    $L[$i][$j] = max($L[$i - 1][$j],
                     $L[$i][$j - 1]); 


  
// L[m][n] contains the length of
// LCS of X[0..n-1] & Y[0..m-1] 
  
return $L[$m][$n];
}
  
// Driver Code
$X = "AGGTAB";
$Y = "GXTXAYB";
echo "Length of LCS is ";
echo lcs($X, $Y); 
  
// This code is contributed
// by Shivi_Aggarwal
?>

Output:

Length of LCS is 4

Time Complexity of the above implementation is O(mn) which is much better than the
worst-case time complexity of Naive Recursive implementation.
The above algorithm/code returns only length of LCS. Please see the following post for
printing the LCS.
Printing Longest Common Subsequence

57
Chapter 4. DP-04 | Longest Common Subsequence

You can also check the space optimized version of LCS at


Space Optimized Solution of LCS
Recent Articles based on LCS!
References:
http://www.youtube.com/watch?v=V5hZoJ6uK-s
http://www.algorithmist.com/index.php/Longest_Common_Subsequence
http://www.ics.uci.edu/~eppstein/161/960229.html
http://en.wikipedia.org/wiki/Longest_common_subsequence_problem
Improved By : sirrobot, Shivi_Aggarwal

Source

https://www.geeksforgeeks.org/longest-common-subsequence-dp-4/

58
Chapter 5

DP-05 | Edit Distance

Edit Distance | DP-5 - GeeksforGeeks


Given two strings str1 and str2 and below operations that can performed on str1. Find
minimum number of edits (operations) required to convert ‘str1’ into ‘str2’.

1. Insert
2. Remove
3. Replace

All of the above operations are of equal cost.

Examples:

Input: str1 = "geek", str2 = "gesek"


Output: 1
We can convert str1 into str2 by inserting a 's'.

Input: str1 = "cat", str2 = "cut"


Output: 1
We can convert str1 into str2 by replacing 'a' with 'u'.

Input: str1 = "sunday", str2 = "saturday"


Output: 3
Last three and first characters are same. We basically
need to convert "un" to "atur". This can be done using
below three operations.
Replace 'n' with 'r', insert t, insert a

What are the subproblems in this case?


The idea is process all characters one by one staring from either from left or right sides of
both strings.

59
Chapter 5. DP-05 | Edit Distance

Let us traverse from right corner, there are two possibilities for every pair of character being
traversed.

m: Length of str1 (first string)


n: Length of str2 (second string)

1. If last characters of two strings are same, nothing much to do. Ignore last characters
and get count for remaining strings. So we recur for lengths m-1 and n-1.
2. Else (If last characters are not same), we consider all operations on ‘str1’, consider all
three operations on last character of first string, recursively compute minimum cost
for all three operations and take minimum of three values.
(a) Insert: Recur for m and n-1
(b) Remove: Recur for m-1 and n
(c) Replace: Recur for m-1 and n-1

Below is C++ implementation of above Naive recursive solution.


C++

// A Naive recursive C++ program to find minimum number


// operations to convert str1 to str2
#include<bits/stdc++.h>
using namespace std;
  
// Utility function to find minimum of three numbers
int min(int x, int y, int z)
{
   return min(min(x, y), z);
}
  
int editDist(string str1 , string str2 , int m ,int n)
{
    // If first string is empty, the only option is to
    // insert all characters of second string into first
    if (m == 0) return n;
  
    // If second string is empty, the only option is to
    // remove all characters of first string
    if (n == 0) return m;
  
    // If last characters of two strings are same, nothing
    // much to do. Ignore last characters and get count for
    // remaining strings.
    if (str1[m-1] == str2[n-1])
        return editDist(str1, str2, m-1, n-1);
  
    // If last characters are not same, consider all three

60
Chapter 5. DP-05 | Edit Distance

    // operations on last character of first string, recursively


    // compute minimum cost for all three operations and take
    // minimum of three values.
    return 1 + min ( editDist(str1,  str2, m, n-1),    // Insert
                     editDist(str1,  str2, m-1, n),   // Remove
                     editDist(str1,  str2, m-1, n-1) // Replace
                   );
}
  
// Driver program
int main()
{
    // your code goes here
    string str1 = "sunday";
    string str2 = "saturday";
  
    cout << editDist( str1 , str2 , str1.length(), str2.length());
  
    return 0;
}

Java

// A Naive recursive Java program to find minimum number


// operations to convert str1 to str2
class EDIST
{
    static int min(int x,int y,int z)
    {
        if (x<=y && x<=z) return x;
        if (y<=x && y<=z) return y;
        else return z;
    }
  
    static int editDist(String str1 , String str2 , int m ,int n)
    {
        // If first string is empty, the only option is to
    // insert all characters of second string into first
    if (m == 0) return n;
       
    // If second string is empty, the only option is to
    // remove all characters of first string
    if (n == 0) return m;
       
    // If last characters of two strings are same, nothing
    // much to do. Ignore last characters and get count for
    // remaining strings.
    if (str1.charAt(m-1) == str2.charAt(n-1))

61
Chapter 5. DP-05 | Edit Distance

        return editDist(str1, str2, m-1, n-1);


       
    // If last characters are not same, consider all three
    // operations on last character of first string, recursively
    // compute minimum cost for all three operations and take
    // minimum of three values.
    return 1 + min ( editDist(str1,  str2, m, n-1),    // Insert
                     editDist(str1,  str2, m-1, n),   // Remove
                     editDist(str1,  str2, m-1, n-1) // Replace                     
                   );
    }
  
    public static void main(String args[])
    {
        String str1 = "sunday";
        String str2 = "saturday";
   
        System.out.println( editDist( str1 , str2 , str1.length(), str2.length()) );
    }
}
/*This code is contributed by Rajat Mishra*/

Python

# A Naive recursive Python program to fin minimum number


# operations to convert str1 to str2
def editDistance(str1, str2, m , n):
  
    # If first string is empty, the only option is to
    # insert all characters of second string into first
    if m==0:
         return n
  
    # If second string is empty, the only option is to
    # remove all characters of first string
    if n==0:
        return m
  
    # If last characters of two strings are same, nothing
    # much to do. Ignore last characters and get count for
    # remaining strings.
    if str1[m-1]==str2[n-1]:
        return editDistance(str1,str2,m-1,n-1)
  
    # If last characters are not same, consider all three
    # operations on last character of first string, recursively
    # compute minimum cost for all three operations and take
    # minimum of three values.

62
Chapter 5. DP-05 | Edit Distance

    return 1 + min(editDistance(str1, str2, m, n-1),    # Insert


                   editDistance(str1, str2, m-1, n),    # Remove
                   editDistance(str1, str2, m-1, n-1)    # Replace
                   )
  
# Driver program to test the above function
str1 = "sunday"
str2 = "saturday"
print editDistance(str1, str2, len(str1), len(str2))
  
# This code is contributed by Bhavya Jain

C#

// A Naive recursive C# program to


// find minimum numberoperations 
// to convert str1 to str2
using System;
  
class GFG
{
    static int min(int x, int y, int z)
    {
        if (x <= y && x <= z) return x;
        if (y <= x && y <= z) return y;
        else return z;
    }
  
    static int editDist(String str1 , String str2 , int m ,int n)
    {
        // If first string is empty, the only option is to
        // insert all characters of second string into first
        if (m == 0) return n;
          
        // If second string is empty, the only option is to
        // remove all characters of first string
        if (n == 0) return m;
          
        // If last characters of two strings are same, nothing
        // much to do. Ignore last characters and get count for
        // remaining strings.
        if (str1[m - 1] == str2[n - 1])
            return editDist(str1, str2, m - 1, n - 1);
          
        // If last characters are not same, consider all three
        // operations on last character of first string, recursively
        // compute minimum cost for all three operations and take
        // minimum of three values.

63
Chapter 5. DP-05 | Edit Distance

        return 1 + min ( editDist(str1, str2, m, n - 1), // Insert


                        editDist(str1, str2, m - 1, n), // Remove
                        editDist(str1, str2, m - 1, n - 1) // Replace                     
                    );
    }
      
    // Driver code
    public static void Main()
    {
        String str1 = "sunday";
        String str2 = "saturday";
        Console.WriteLine( editDist( str1 , str2 , str1.Length, 
                                                 str2.Length ));
    }
}
  
// This Code is Contributed by Sam007

PHP

<?php 
// A Naive recursive Python program  
// to find minimum number operations 
// to convert str1 to str2 
function editDistance($str1, $str2, 
                      $m, $n)

    // If first string is empty, 
    // the only option is to insert.
    // all characters of second
    // string into first 
    if ($m == 0)
        return $n; 
  
    // If second string is empty,
    // the only option is to 
    // remove all characters of 
    // first string 
    if ($n == 0) 
        return $m; 
  
    // If last characters of two 
    // strings are same, nothing 
    // much to do. Ignore last 
    // characters and get count 
    // for remaining strings. 
    if ($str1[$m - 1] == $str2[$n - 1])
    { 

64
Chapter 5. DP-05 | Edit Distance

        return editDistance($str1, $str2, 


                            $m - 1, $n - 1); 
    }
      
    // If last characters are not same, 
    // consider all three operations on 
    // last character of first string, 
    // recursively compute minimum cost 
    // for all three operations and take 
    // minimum of three values. 
  
    return 1 + min(editDistance($str1, $str2, 
                                $m, $n - 1), // Insert 
                   editDistance($str1, $str2, 
                                $m - 1, $n), // Remove 
                   editDistance($str1, $str2, 
                                $m - 1, $n - 1)); // Replace 

  
// Driver Code
$str1 = "sunday";
$str2 = "saturday";
echo editDistance($str1, $str2, strlen($str1), 
                                strlen($str2)); 
  
// This code is contributed 
// by Shivi_Aggarwal
?>

Output:

The time complexity of above solution is exponential. In worst case, we may end up doing
O(3m ) operations. The worst case happens when none of characters of two strings match.
Below is a recursive call diagram for worst case.

65
Chapter 5. DP-05 | Edit Distance

We can see that many subproblems are solved, again and again, for example, eD(2,2) is
called three times. Since same suproblems are called again, this problem has Overlapping
Subprolems property. So Edit Distance problem has both properties (see thisand this) of a
dynamic programming problem. Like other typical Dynamic Programming(DP) problems,
recomputations of same subproblems can be avoided by constructing a temporary array that
stores results of subproblems.
C++

// A Dynamic Programming based C++ program to find minimum


// number operations to convert str1 to str2
#include<bits/stdc++.h>
using namespace std;
  
// Utility function to find the minimum of three numbers
int min(int x, int y, int z)
{
    return min(min(x, y), z);
}
  
int editDistDP(string str1, string str2, int m, int n)
{
    // Create a table to store results of subproblems
    int dp[m+1][n+1];
  
    // Fill d[][] in bottom up manner
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {

66
Chapter 5. DP-05 | Edit Distance

            // If first string is empty, only option is to


            // isnert all characters of second string
            if (i==0)
                dp[i][j] = j;  // Min. operations = j
  
            // If second string is empty, only option is to
            // remove all characters of second string
            else if (j==0)
                dp[i][j] = i; // Min. operations = i
  
            // If last characters are same, ignore last char
            // and recur for remaining string
            else if (str1[i-1] == str2[j-1])
                dp[i][j] = dp[i-1][j-1];
  
            // If the last character is different, consider all
            // possibilities and find the minimum
            else
                dp[i][j] = 1 + min(dp[i][j-1],  // Insert
                                   dp[i-1][j],  // Remove
                                   dp[i-1][j-1]); // Replace
        }
    }
  
    return dp[m][n];
}
  
// Driver program
int main()
{
    // your code goes here
    string str1 = "sunday";
    string str2 = "saturday";
  
    cout << editDistDP(str1, str2, str1.length(), str2.length());
  
    return 0;
}

Java

// A Dynamic Programming based Java program to find minimum


// number operations to convert str1 to str2
class EDIST
{
    static int min(int x,int y,int z)
    {
        if (x <= y && x <= z) return x;

67
Chapter 5. DP-05 | Edit Distance

        if (y <= x && y <= z) return y;


        else return z;
    }
  
    static int editDistDP(String str1, String str2, int m, int n)
    {
        // Create a table to store results of subproblems
        int dp[][] = new int[m+1][n+1];
       
        // Fill d[][] in bottom up manner
        for (int i=0; i<=m; i++)
        {
            for (int j=0; j<=n; j++)
            {
                // If first string is empty, only option is to
                // isnert all characters of second string
                if (i==0)
                    dp[i][j] = j;  // Min. operations = j
       
                // If second string is empty, only option is to
                // remove all characters of second string
                else if (j==0)
                    dp[i][j] = i; // Min. operations = i
       
                // If last characters are same, ignore last char
                // and recur for remaining string
                else if (str1.charAt(i-1) == str2.charAt(j-1))
                    dp[i][j] = dp[i-1][j-1];
       
                // If the last character is different, consider all
                // possibilities and find the minimum
                else
                    dp[i][j] = 1 + min(dp[i][j-1],  // Insert
                                       dp[i-1][j],  // Remove
                                       dp[i-1][j-1]); // Replace
            }
        }
   
        return dp[m][n];
    }
  
      
  
    public static void main(String args[])
    {
        String str1 = "sunday";
        String str2 = "saturday";
        System.out.println( editDistDP( str1 , str2 , str1.length(), str2.length()) );

68
Chapter 5. DP-05 | Edit Distance

    }
}/*This code is contributed by Rajat Mishra*/

Python

# A Dynamic Programming based Python program for edit


# distance problem
def editDistDP(str1, str2, m, n):
    # Create a table to store results of subproblems
    dp = [[0 for x in range(n+1)] for x in range(m+1)]
  
    # Fill d[][] in bottom up manner
    for i in range(m+1):
        for j in range(n+1):
  
            # If first string is empty, only option is to
            # isnert all characters of second string
            if i == 0:
                dp[i][j] = j    # Min. operations = j
  
            # If second string is empty, only option is to
            # remove all characters of second string
            elif j == 0:
                dp[i][j] = i    # Min. operations = i
  
            # If last characters are same, ignore last char
            # and recur for remaining string
            elif str1[i-1] == str2[j-1]:
                dp[i][j] = dp[i-1][j-1]
  
            # If last character are different, consider all
            # possibilities and find minimum
            else:
                dp[i][j] = 1 + min(dp[i][j-1],        # Insert
                                   dp[i-1][j],        # Remove
                                   dp[i-1][j-1])    # Replace
  
    return dp[m][n]
  
# Driver program
str1 = "sunday"
str2 = "saturday"
  
print(editDistDP(str1, str2, len(str1), len(str2)))
# This code is contributed by Bhavya Jain

C#

69
Chapter 5. DP-05 | Edit Distance

// A Dynamic Programming based 


// C# program to find minimum
// number operations to 
// convert str1 to str2
using System;
  
class GFG
{
    static int min(int x, int y, int z)
    {
        if (x <= y && x <= z) return x;
        if (y <= x && y <= z) return y;
        else return z;
    }
  
    static int editDistDP(String str1, String str2, int m, int n)
    {
        // Create a table to store
        // results of subproblems
        int [,]dp = new int[m + 1,n + 1];
      
        // Fill d[][] in bottom up manner
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                // If first string is empty, only option is to
                // isnert all characters of second string
                if (i == 0)
                  
                    // Min. operations = j
                    dp[i, j] = j; 
      
                // If second string is empty, only option is to
                // remove all characters of second string
                else if (j == 0)
                       
                     // Min. operations = i
                    dp[i,j] = i; 
      
                // If last characters are same, ignore last char
                // and recur for remaining string
                else if (str1[i - 1] == str2[j - 1])
                    dp[i, j] = dp[i - 1, j - 1];
      
                // If the last character is different, consider all
                // possibilities and find the minimum
                else

70
Chapter 5. DP-05 | Edit Distance

                    dp[i, j] = 1 + min(dp[i, j - 1], // Insert


                                    dp[i - 1, j], // Remove
                                    dp[i - 1, j - 1]); // Replace
            }
        }
  
        return dp[m, n];
    }
  
      
    // Driver code
    public static void Main()
    {
        String str1 = "sunday";
        String str2 = "saturday";
        Console.Write( editDistDP( str1 , str2 , str1.Length, 
                                               str2.Length ));
    }
}
// This Code is Contributed by Sam007

PHP

<?php
// A Dynamic Programming based 
// Python program for edit 
// distance problem 
function editDistDP($str1, $str2, 
                    $m, $n)

// Fill d[][] in bottom up manner 
for ($i = 0; $i <= $m; $i++) 
{  
    for ($j = 0; $j <= $n; $j++) 
    { 
  
        // If first string is empty, 
        // only option is to insert 
        // all characters of second string 
        if ($i == 0) 
            $dp[$i][$j] = $j ; // Min. operations = j 
  
        // If second string is empty, 
        // only option is to remove 
        // all characters of second string 
        else if($j == 0) 
            $dp[$i][$j] = $i; // Min. operations = i 
  

71
Chapter 5. DP-05 | Edit Distance

        // If last characters are same, 


        // ignore last char and recur 
        // for remaining string 
        else if($str1[$i - 1] == $str2[$j - 1]) 
            $dp[$i][$j] = $dp[$i - 1][$j - 1];
  
        // If last character are different, 
        // consider all possibilities and 
        // find minimum 
        else
        { 
            $dp[$i][$j] = 1 + min($dp[$i][$j - 1],     // Insert 
                                  $dp[$i - 1][$j],     // Remove 
                                  $dp[$i - 1][$j - 1]); // Replace 
        }
    }
}
return $dp[$m][$n] ;
}
  
// Driver Code 
$str1 = "sunday";
$str2 = "saturday";
  
echo editDistDP($str1, $str2, strlen($str1), 
                              strlen($str2));
  
// This code is contributed 
// by Shivi_Aggarwal
?>

Output:

Time Complexity: O(m x n)


Auxiliary Space: O(m x n)
Applications: There are many practical applications of edit distance algorithm, refer
Lucene API for sample. Another example, display all the words in a dictionary that are
near proximity to a given wordincorrectly spelled word.
Thanks to Vivek Kumar for suggesting updates.
Thanks to Venki for providing initial post. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : Shivi_Aggarwal

72
Chapter 5. DP-05 | Edit Distance

Source

https://www.geeksforgeeks.org/edit-distance-dp-5/

73
Chapter 6

DP-06 | Min Cost Path

Min Cost Path | DP-6 - GeeksforGeeks


Given a cost matrix cost[][] and a position (m, n) in cost[][], write a function that returns
cost of minimum cost path to reach (m, n) from (0, 0). Each cell of the matrix represents a
cost to traverse through that cell. Total cost of a path to reach (m, n) is sum of all the costs
on that path (including both source and destination). You can only traverse down, right
and diagonally lower cells from a given cell, i.e., from a given cell (i, j), cells (i+1, j), (i, j+1)
and (i+1, j+1) can be traversed. You may assume that all costs are positive integers.
For example, in the following figure, what is the minimum cost path to (2, 2)?

The path with minimum cost is highlighted in the following figure. The path is (0, 0) –>
(0, 1) –> (1, 2) –> (2, 2). The cost of the path is 8 (1 + 2 + 2 + 3).

74
Chapter 6. DP-06 | Min Cost Path

1) Optimal Substructure
The path to reach (m, n) must be through one of the 3 cells: (m-1, n-1) or (m-1, n) or
(m, n-1). So minimum cost to reach (m, n) can be written as “minimum of the 3 cells plus
cost[m][n]”.
minCost(m, n) = min (minCost(m-1, n-1), minCost(m-1, n), minCost(m, n-1)) + cost[m][n]
2) Overlapping Subproblems
Following is simple recursive implementation of the MCP (Minimum Cost Path) problem.
The implementation simply follows the recursive structure mentioned above.

/* A Naive recursive implementation of MCP(Minimum Cost Path) problem */


#include<stdio.h>
#include<limits.h>
#define R 3
#define C 3
  
int min(int x, int y, int z);
  
/* Returns cost of minimum cost path from (0,0) to (m, n) in mat[R][C]*/
int minCost(int cost[R][C], int m, int n)
{
   if (n < 0 || m < 0)
      return INT_MAX;
   else if (m == 0 && n == 0)
      return cost[m][n];
   else
      return cost[m][n] + min( minCost(cost, m-1, n-1),
                               minCost(cost, m-1, n), 
                               minCost(cost, m, n-1) );
}
  
/* A utility function that returns minimum of 3 integers */
int min(int x, int y, int z)
{
   if (x < y)
      return (x < z)? x : z;
   else
      return (y < z)? y : z;
}
  
/* Driver program to test above functions */
int main()
{
   int cost[R][C] = { {1, 2, 3},
                      {4, 8, 2},

75
Chapter 6. DP-06 | Min Cost Path

                      {1, 5, 3} };
   printf(" %d ", minCost(cost, 2, 2));
   return 0;
}

Java

/* A Naive recursive implementation of


MCP(Minimum Cost Path) problem */
public class GFG {
  
    /* A utility function that returns 
    minimum of 3 integers */
    static int min(int x, int y, int z)
    {
        if (x < y)
            return (x < z) ? x : z;
        else
            return (y < z) ? y : z;
    } 
      
    /* Returns cost of minimum cost path 
    from (0,0) to (m, n) in mat[R][C]*/
    static int minCost(int cost[][], int m,
                                     int n)
    {
        if (n < 0 || m < 0)
            return Integer.MAX_VALUE;
        else if (m == 0 && n == 0)
            return cost[m][n];
        else
            return cost[m][n] + 
                min( minCost(cost, m-1, n-1),
                     minCost(cost, m-1, n), 
                     minCost(cost, m, n-1) );
    }
  
    // Driver code
    public static void main(String args[]) 
    {
          
        int cost[][] = { {1, 2, 3},
                         {4, 8, 2},
                         {1, 5, 3} };
                           
        System.out.print(minCost(cost, 2, 2));
    }
}

76
Chapter 6. DP-06 | Min Cost Path

  
// This code is contributed by Sam007

Python3

# A Naive recursive implementation of MCP(Minimum Cost Path) problem


R = 3
C = 3
import sys
  
# Returns cost of minimum cost path from (0,0) to (m, n) in mat[R][C]
def minCost(cost, m, n):
    if (n < 0 or m < 0):
        return sys.maxsize
    elif (m == 0 and n == 0):
        return cost[m][n]
    else:
        return cost[m][n] + min( minCost(cost, m-1, n-1),
                                minCost(cost, m-1, n),
                                minCost(cost, m, n-1) )
  
#A utility function that returns minimum of 3 integers */
def min(x, y, z):
    if (x < y):
        return x if (x < z) else z
    else:
        return y if (y < z) else z
  
  
# Driver program to test above functions 
cost= [ [1, 2, 3],
        [4, 8, 2],
        [1, 5, 3] ]
print(minCost(cost, 2, 2))
  
# This code is contributed by
# Smitha Dinesh Semwal

C#

/* A Naive recursive implementation of


MCP(Minimum Cost Path) problem */
using System;
  
class GFG
{
  

77
Chapter 6. DP-06 | Min Cost Path

    /* A utility function that 


    returns minimum of 3 integers */
    static int min(int x, 
                   int y, int z)
    {
        if (x < y)
            return ((x < z) ? x : z);
        else
            return ((y < z) ? y : z);
    } 
      
    /* Returns cost of minimum 
    cost path from (0,0) to 
    (m, n) in mat[R][C]*/
    static int minCost(int [,]cost, 
                       int m , int n)
    {
        if (n < 0 || m < 0)
            return int.MaxValue;
        else if (m == 0 && n == 0)
            return cost[m, n];
        else
            return cost[m, n] + 
                   min(minCost(cost, m - 1, n - 1), 
                   minCost(cost, m - 1, n), 
                   minCost(cost, m, n - 1) );
    }
  
    // Driver code
    public static void Main() 
    {
          
        int [,]cost = {{1, 2, 3},
                       {4, 8, 2},
                       {1, 5, 3}};
                          
        Console.Write(minCost(cost, 2, 2));
    }
}
  
// This code is contributed
// by shiv_bhakt.

PHP

<?php
/* A Naive recursive implementation 
of MCP(Minimum Cost Path) problem */

78
Chapter 6. DP-06 | Min Cost Path

  
$R = 3;
$C = 3;
  
  
/* Returns cost of minimum  
cost path from (0,0) to 
(m, n) in mat[R][C]*/
function minCost($cost, $m, $n)
{
global $R;
global $C;
if ($n < 0 || $m < 0)
    return PHP_INT_MAX;
else if ($m == 0 && $n == 0)
    return $cost[$m][$n];
else
    return $cost[$m][$n] +  
            min1(minCost($cost, $m - 1, $n - 1),
            minCost($cost, $m - 1, $n), 
            minCost($cost, $m, $n - 1) );
}
  
/* A utility function that 
returns minimum of 3 integers */
function min1($x, $y, $z)
{
if ($x < $y)
    return ($x < $z)? $x : $z;
else
    return ($y < $z)? $y : $z;
}
  
// Driver Code
$cost = array(array(1, 2, 3),
              array (4, 8, 2),
              array (1, 5, 3));
echo minCost($cost, 2, 2);
  
// This code is contributed by mits.
?>

Output:

It should be noted that the above function computes the same subproblems again and again.

79
Chapter 6. DP-06 | Min Cost Path

See the following recursion tree, there are many nodes which apear more than once. Time
complexity of this naive recursive solution is exponential and it is terribly slow.

mC refers to minCost()
mC(2, 2)
/ | \
/ | \
mC(1, 1) mC(1, 2) mC(2, 1)
/ | \ / | \ / | \
/ | \ / | \ / | \
mC(0,0) mC(0,1) mC(1,0) mC(0,1) mC(0,2) mC(1,1) mC(1,0) mC(1,1) mC(2,0)

So the MCP problem has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, recomputations of same
subproblems can be avoided by constructing a temporary array tc[][] in bottom up manner.
C++

/* Dynamic Programming implementation of MCP problem */


#include<stdio.h>
#include<limits.h>
#define R 3
#define C 3
  
int min(int x, int y, int z);
  
int minCost(int cost[R][C], int m, int n)
{
     int i, j;
  
     // Instead of following line, we can use int tc[m+1][n+1] or 
     // dynamically allocate memory to save space. The following line is
     // used to keep the program simple and make it working on all compilers.
     int tc[R][C];  
  
     tc[0][0] = cost[0][0];
  
     /* Initialize first column of total cost(tc) array */
     for (i = 1; i <= m; i++)
        tc[i][0] = tc[i-1][0] + cost[i][0];
  
     /* Initialize first row of tc array */
     for (j = 1; j <= n; j++)
        tc[0][j] = tc[0][j-1] + cost[0][j];
  
     /* Construct rest of the tc array */
     for (i = 1; i <= m; i++)

80
Chapter 6. DP-06 | Min Cost Path

        for (j = 1; j <= n; j++)


            tc[i][j] = min(tc[i-1][j-1], 
                           tc[i-1][j], 
                           tc[i][j-1]) + cost[i][j];
  
     return tc[m][n];
}
  
/* A utility function that returns minimum of 3 integers */
int min(int x, int y, int z)
{
   if (x < y)
      return (x < z)? x : z;
   else
      return (y < z)? y : z;
}
  
/* Driver program to test above functions */
int main()
{
   int cost[R][C] = { {1, 2, 3},
                      {4, 8, 2},
                      {1, 5, 3} };
   printf(" %d ", minCost(cost, 2, 2));
   return 0;
}

Java

/* Java program for Dynamic Programming implementation


   of Min Cost Path problem */
import java.util.*;
  
class MinimumCostPath
{
    /* A utility function that returns minimum of 3 integers */
    private static int min(int x, int y, int z)
    {
        if (x < y)
            return (x < z)? x : z;
        else
            return (y < z)? y : z;
    }
  
    private static int minCost(int cost[][], int m, int n)
    {
        int i, j;
        int tc[][]=new int[m+1][n+1];

81
Chapter 6. DP-06 | Min Cost Path

  
        tc[0][0] = cost[0][0];
  
        /* Initialize first column of total cost(tc) array */
        for (i = 1; i <= m; i++)
            tc[i][0] = tc[i-1][0] + cost[i][0];
  
        /* Initialize first row of tc array */
        for (j = 1; j <= n; j++)
            tc[0][j] = tc[0][j-1] + cost[0][j];
  
        /* Construct rest of the tc array */
        for (i = 1; i <= m; i++)
            for (j = 1; j <= n; j++)
                tc[i][j] = min(tc[i-1][j-1], 
                               tc[i-1][j],
                               tc[i][j-1]) + cost[i][j];
  
        return tc[m][n];
    }
  
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        int cost[][]= {{1, 2, 3},
                       {4, 8, 2},
                       {1, 5, 3}};
        System.out.println(minCost(cost,2,2));
    }
}
// This code is contributed by Pankaj Kumar

Python

# Dynamic Programming Python implementation of Min Cost Path


# problem
R = 3
C = 3
  
def minCost(cost, m, n):
  
    # Instead of following line, we can use int tc[m+1][n+1] or
    # dynamically allocate memoery to save space. The following
    # line is used to keep te program simple and make it working
    # on all compilers.
    tc = [[0 for x in range(C)] for x in range(R)]
  
    tc[0][0] = cost[0][0]

82
Chapter 6. DP-06 | Min Cost Path

  
    # Initialize first column of total cost(tc) array
    for i in range(1, m+1):
        tc[i][0] = tc[i-1][0] + cost[i][0]
  
    # Initialize first row of tc array
    for j in range(1, n+1):
        tc[0][j] = tc[0][j-1] + cost[0][j]
  
    # Construct rest of the tc array
    for i in range(1, m+1):
        for j in range(1, n+1):
            tc[i][j] = min(tc[i-1][j-1], tc[i-1][j], tc[i][j-1]) + cost[i][j]
  
    return tc[m][n]
  
# Driver program to test above functions
cost = [[1, 2, 3],
        [4, 8, 2],
        [1, 5, 3]]
print(minCost(cost, 2, 2))
  
# This code is contributed by Bhavya Jain

C#

// C# program for Dynamic Programming implementation


// of Min Cost Path problem 
using System;
  
class GFG
{
    // A utility function that 
    // returns minimum of 3 integers 
    private static int min(int x, int y, int z)
    {
        if (x < y)
            return (x < z)? x : z;
        else
            return (y < z)? y : z;
    }
  
    private static int minCost(int [,]cost, int m, int n)
    {
        int i, j;
        int [,]tc=new int[m+1,n+1];
  
        tc[0,0] = cost[0,0];

83
Chapter 6. DP-06 | Min Cost Path

  
        /* Initialize first column of total cost(tc) array */
        for (i = 1; i <= m; i++)
            tc[i, 0] = tc[i - 1, 0] + cost[i, 0];
  
        /* Initialize first row of tc array */
        for (j = 1; j <= n; j++)
            tc[0, j] = tc[0, j - 1] + cost[0, j];
  
        /* Construct rest of the tc array */
        for (i = 1; i <= m; i++)
            for (j = 1; j <= n; j++)
                tc[i, j] = min(tc[i - 1, j - 1], 
                            tc[i - 1, j],
                            tc[i, j - 1]) + cost[i, j];
  
        return tc[m, n];
    }
  
    // Driver program 
    public static void Main()
    {
        int [,]cost= {{1, 2, 3},
                    {4, 8, 2},
                    {1, 5, 3}};
        Console.Write(minCost(cost,2,2));
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// DP implementation
// of MCP problem 
$R = 3;
$C = 3;
  
function minCost($cost, $m, $n)
{
    global $R;
    global $C;
    // Instead of following line, 
    // we can use int tc[m+1][n+1] 
    // or dynamically allocate 
    // memory to save space. The 
    // following line is used to keep 

84
Chapter 6. DP-06 | Min Cost Path

    // the program simple and make


    // it working on all compilers.
    $tc;
    for ($i = 0; $i <= $R; $i++)
    for ($j = 0; $j <= $C; $j++)
    $tc[$i][$j] = 0; 
  
    $tc[0][0] = $cost[0][0];
  
    /* Initialize first column of
       total cost(tc) array */
    for ($i = 1; $i <= $m; $i++)
        $tc[$i][0] = $tc[$i - 1][0] + 
                     $cost[$i][0];
  
    /* Initialize first 
       row of tc array */
    for ($j = 1; $j <= $n; $j++)
        $tc[0][$j] = $tc[0][$j - 1] + 
                     $cost[0][$j];
  
    /* Construct rest of
       the tc array */
    for ($i = 1; $i <= $m; $i++)
        for ($j = 1; $j <= $n; $j++)
          
            // returns minimum of 3 integers 
            $tc[$i][$j] = min($tc[$i - 1][$j - 1], 
                              $tc[$i - 1][$j], 
                              $tc[$i][$j - 1]) +
                              $cost[$i][$j];
  
    return $tc[$m][$n];
}
  
  
// Driver Code
$cost = array(array(1, 2, 3),
              array(4, 8, 2),
              array(1, 5, 3));
echo minCost($cost, 2, 2);
  
// This code is contributed by mits
?>

Output:

85
Chapter 6. DP-06 | Min Cost Path

Time Complexity of the DP implementation is O(mn) which is much better than Naive
Recursive implementation.
Improved By : Sam007, Mithun Kumar, shiv_bhakt, maveriek

Source

https://www.geeksforgeeks.org/min-cost-path-dp-6/

86
Chapter 7

DP-07 | Coin Change

Coin Change | DP-7 - GeeksforGeeks


Given a value N, if we want to make change for N cents, and we have infinite supply of each
of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order
of coins doesn’t matter.
For example, for N = 4 and S = {1,2,3}, there are four solutions: {1,1,1,1},{1,1,2},{2,2},{1,3}.
So output should be 4. For N = 10 and S = {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2},
{2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5.
1) Optimal Substructure
To count the total number of solutions, we can divide all set solutions into two sets.
1) Solutions that do not contain mth coin (or Sm).
2) Solutions that contain at least one Sm.
Let count(S[], m, n) be the function to count the number of solutions, then it can be written
as sum of count(S[], m-1, n) and count(S[], m, n-Sm).
Therefore, the problem has optimal substructure property as the problem can be solved
using solutions to subproblems.
2) Overlapping Subproblems
Following is a simple recursive implementation of the Coin Change problem. The implemen-
tation simply follows the recursive structure mentioned above.
C++

// Recursive C program for


// coin change problem.
#include<stdio.h>
  
// Returns the count of ways we can 
// sum S[0...m-1] coins to get sum n
int count( int S[], int m, int n )
{

87
Chapter 7. DP-07 | Coin Change

    // If n is 0 then there is 1 solution 


    // (do not include any coin)
    if (n == 0)
        return 1;
      
    // If n is less than 0 then no 
    // solution exists
    if (n < 0)
        return 0;
  
    // If there are no coins and n 
    // is greater than 0, then no
    // solution exist
    if (m <=0 && n >= 1)
        return 0;
  
    // count is sum of solutions (i) 
    // including S[m-1] (ii) excluding S[m-1]
    return count( S, m - 1, n ) + count( S, m, n-S[m-1] );
}
  
// Driver program to test above function
int main()
{
    int i, j;
    int arr[] = {1, 2, 3};
    int m = sizeof(arr)/sizeof(arr[0]);
    printf("%d ", count(arr, m, 4));
    getchar();
    return 0;
}

Java

// Recursive java program for


// coin change problem.
import java.io.*;
  
class GFG {
      
    // Returns the count of ways we can 
    // sum S[0...m-1] coins to get sum n
    static int count( int S[], int m, int n )
    {
        // If n is 0 then there is 1 solution 
        // (do not include any coin)
        if (n == 0)
            return 1;

88
Chapter 7. DP-07 | Coin Change

          
        // If n is less than 0 then no 
        // solution exists
        if (n < 0)
            return 0;
      
        // If there are no coins and n 
        // is greater than 0, then no
        // solution exist
        if (m <=0 && n >= 1)
            return 0;
      
        // count is sum of solutions (i) 
        // including S[m-1] (ii) excluding S[m-1]
        return count( S, m - 1, n ) +
               count( S, m, n-S[m-1] );
    }
      
    // Driver program to test above function
    public static void main(String[] args)
    {
        int i, j;
        int arr[] = {1, 2, 3};
        int m = arr.length;
        System.out.println( count(arr, m, 4));
          
          
    }
  
}
  
// This article is contributed by vt_m.

Python3

# Recursive Python3 program for


# coin change problem.
  
# Returns the count of ways we can sum
# S[0...m-1] coins to get sum n
def count(S, m, n ):
  
    # If n is 0 then there is 1
    # solution (do not include any coin)
    if (n == 0):
        return 1
  
    # If n is less than 0 then no

89
Chapter 7. DP-07 | Coin Change

    # solution exists


    if (n < 0):
        return 0;
  
    # If there are no coins and n
    # is greater than 0, then no
    # solution exist
    if (m <=0 and n >= 1):
        return 0
  
    # count is sum of solutions (i) 
    # including S[m-1] (ii) excluding S[m-1]
    return count( S, m - 1, n ) + count( S, m, n-S[m-1] );
  
# Driver program to test above function
arr = [1, 2, 3]
m = len(arr)
print(count(arr, m, 4))
  
# This code is contributed by Smitha Dinesh Semwal

C#

// Recursive C# program for


// coin change problem.
using System;
  
class GFG
{
    // Returns the count of ways we can 
    // sum S[0...m-1] coins to get sum n
    static int count( int []S, int m, int n )
    {
        // If n is 0 then there is 1 solution 
        // (do not include any coin)
        if (n == 0)
            return 1;
          
        // If n is less than 0 then no 
        // solution exists
        if (n < 0)
            return 0;
      
        // If there are no coins and n 
        // is greater than 0, then no
        // solution exist
        if (m <=0 && n >= 1)
            return 0;

90
Chapter 7. DP-07 | Coin Change

      
        // count is sum of solutions (i) 
        // including S[m-1] (ii) excluding S[m-1]
        return count( S, m - 1, n ) +
            count( S, m, n - S[m - 1] );
    }
      
    // Driver program
    public static void Main()
    {
          
        int []arr = {1, 2, 3};
        int m = arr.Length;
        Console.Write( count(arr, m, 4));
          
          
    }
}
// This code is contributed by Sam007

PHP

<?php
// Recursive PHP program for
// coin change problem.
  
// Returns the count of ways we can 
// sum S[0...m-1] coins to get sum n
function coun($S, $m, $n)
{
      
    // If n is 0 then there is 
    // 1 solution (do not include
    // any coin)
    if ($n == 0)
        return 1;
      
    // If n is less than 0 then no 
    // solution exists
    if ($n < 0)
        return 0;
  
    // If there are no coins and n 
    // is greater than 0, then no
    // solution exist
    if ($m <= 0 && $n >= 1)
        return 0;
  

91
Chapter 7. DP-07 | Coin Change

    // count is sum of solutions (i) 


    // including S[m-1] (ii) excluding S[m-1]
    return coun($S, $m - 1,$n ) + 
           coun($S, $m, $n - $S[$m - 1] );
}
  
    // Driver Code
    $arr = array(1, 2, 3);
    $m = count($arr);
    echo coun($arr, $m, 4); 
      
// This code is contributed by Sam007
?>

Output :

It should be noted that the above function computes the same subproblems again and again.
See the following recursion tree for S = {1, 2, 3} and n = 5.
The function C({1}, 3) is called two times. If we draw the complete tree, then we can see
that there are many subproblems being called more than once.

C() --> count()


C({1,2,3}, 5)
/ \
/ \
C({1,2,3}, 2) C({1,2}, 5)
/ \ / \
/ \ / \
C({1,2,3}, -1) C({1,2}, 2) C({1,2}, 3) C({1}, 5)
/ \ / \ / \
/ \ / \ / \
C({1,2},0) C({1},2) C({1,2},1) C({1},3) C({1}, 4) C({}, 5)
/ \ / \ /\ / \
/ \ / \ / \ / \
. . . . . . C({1}, 3) C({}, 4)
/ \
/ \
. .

Since same suproblems are called again, this problem has Overlapping Subprolems property.
So the Coin Change problem has both properties (see thisand this) of a dynamic program-
ming problem. Like other typical Dynamic Programming(DP) problems, recomputations of

92
Chapter 7. DP-07 | Coin Change

same subproblems can be avoided by constructing a temporary array table[][] in bottom up


manner.
Dynamic Programming Solution

// C program for coin change problem.


#include<stdio.h>
  
int count( int S[], int m, int n )
{
    int i, j, x, y;
  
    // We need n+1 rows as the table is constructed 
    // in bottom up manner using the base case 0
    // value case (n = 0)
    int table[n+1][m];
     
    // Fill the enteries for 0 value case (n = 0)
    for (i=0; i<m; i++)
        table[0][i] = 1;
  
    // Fill rest of the table entries in bottom 
    // up manner  
    for (i = 1; i < n+1; i++)
    {
        for (j = 0; j < m; j++)
        {
            // Count of solutions including S[j]
            x = (i-S[j] >= 0)? table[i - S[j]][j]: 0;
  
            // Count of solutions excluding S[j]
            y = (j >= 1)? table[i][j-1]: 0;
  
            // total count
            table[i][j] = x + y;
        }
    }
    return table[n][m-1];
}
  
// Driver program to test above function
int main()
{
    int arr[] = {1, 2, 3};
    int m = sizeof(arr)/sizeof(arr[0]);
    int n = 4;

93
Chapter 7. DP-07 | Coin Change

    printf(" %d ", count(arr, m, n));


    return 0;
}

Java

/* Dynamic Programming Java implementation of Coin


   Change problem */
import java.util.Arrays;
  
class CoinChange
{
    static long countWays(int S[], int m, int n)
    {
        //Time complexity of this function: O(mn)
        //Space Complexity of this function: O(n)
  
        // table[i] will be storing the number of solutions
        // for value i. We need n+1 rows as the table is
        // constructed in bottom up manner using the base
        // case (n = 0)
        long[] table = new long[n+1];
  
        // Initialize all table values as 0
        Arrays.fill(table, 0);   //O(n)
  
        // Base case (If given value is 0)
        table[0] = 1;
  
        // Pick all coins one by one and update the table[]
        // values after the index greater than or equal to
        // the value of the picked coin
        for (int i=0; i<m; i++)
            for (int j=S[i]; j<=n; j++)
                table[j] += table[j-S[i]];
  
        return table[n];
    }
  
    // Driver Function to test above function
    public static void main(String args[])
    {
        int arr[] = {1, 2, 3};
        int m = arr.length;
        int n = 4;
        System.out.println(countWays(arr, m, n));
    }
}

94
Chapter 7. DP-07 | Coin Change

// This code is contributed by Pankaj Kumar

Python

# Dynamic Programming Python implementation of Coin 


# Change problem
def count(S, m, n):
    # We need n+1 rows as the table is constructed 
    # in bottom up manner using the base case 0 value
    # case (n = 0)
    table = [[0 for x in range(m)] for x in range(n+1)]
  
    # Fill the entries for 0 value case (n = 0)
    for i in range(m):
        table[0][i] = 1
  
    # Fill rest of the table entries in bottom up manner
    for i in range(1, n+1):
        for j in range(m):
  
            # Count of solutions including S[j]
            x = table[i - S[j]][j] if i-S[j] >= 0 else 0
  
            # Count of solutions excluding S[j]
            y = table[i][j-1] if j >= 1 else 0
  
            # total count
            table[i][j] = x + y
  
    return table[n][m-1]
  
# Driver program to test above function
arr = [1, 2, 3]
m = len(arr)
n = 4
print(count(arr, m, n))
  
# This code is contributed by Bhavya Jain

C#

/* Dynamic Programming C# implementation of Coin


Change problem */
using System;
  
class GFG
{

95
Chapter 7. DP-07 | Coin Change

    static long countWays(int []S, int m, int n)


    {
        //Time complexity of this function: O(mn)
        //Space Complexity of this function: O(n)
  
        // table[i] will be storing the number of solutions
        // for value i. We need n+1 rows as the table is
        // constructed in bottom up manner using the base
        // case (n = 0)
        int[] table = new int[n+1];
  
        // Initialize all table values as 0
        for(int i = 0; i < table.Length; i++) 
        {
            table[i] = 0;
        }
  
        // Base case (If given value is 0)
        table[0] = 1;
  
        // Pick all coins one by one and update the table[]
        // values after the index greater than or equal to
        // the value of the picked coin
        for (int i = 0; i < m; i++)
            for (int j = S[i]; j <= n; j++)
                table[j] += table[j - S[i]];
  
        return table[n];
    }
  
    // Driver Function
    public static void Main()
    {
        int []arr = {1, 2, 3};
        int m = arr.Length;
        int n = 4;
        Console.Write(countWays(arr, m, n));
    }
}
// This code is contributed by Sam007

PHP

<?php
// PHP program for 
// coin change problem.
  
function count1($S, $m, $n)

96
Chapter 7. DP-07 | Coin Change

{
    // We need n+1 rows as 
    // the table is constructed 
    // in bottom up manner 
    // using the base case 0
    // value case (n = 0)
    $table;
    for ($i = 0; $i < $n + 1; $i++)
    for ($j = 0; $j < $m; $j++)
        $table[$i][$j] = 0;
      
    // Fill the enteries for
    // 0 value case (n = 0)
    for ($i = 0; $i < $m; $i++)
        $table[0][$i] = 1;
  
    // Fill rest of the table 
    // entries in bottom up manner 
    for ($i = 1; $i < $n + 1; $i++)
    {
        for ($j = 0; $j < $m; $j++)
        {
            // Count of solutions
            // including S[j]
            $x = ($i-$S[$j] >= 0) ? 
                  $table[$i - $S[$j]][$j] : 0;
  
            // Count of solutions
            // excluding S[j]
            $y = ($j >= 1) ? 
                  $table[$i][$j - 1] : 0;
  
            // total count
            $table[$i][$j] = $x + $y;
        }
    }
    return $table[$n][$m-1];
}
  
// Driver Code
$arr = array(1, 2, 3);
$m = count($arr);
$n = 4;
echo count1($arr, $m, $n);
  
// This code is contributed by mits
?>

97
Chapter 7. DP-07 | Coin Change

Output:

Time Complexity: O(mn)


Following is a simplified version of method 2. The auxiliary space required here is O(n) only.

int count( int S[], int m, int n )


{
    // table[i] will be storing the number of solutions for
    // value i. We need n+1 rows as the table is constructed
    // in bottom up manner using the base case (n = 0)
    int table[n+1];
  
    // Initialize all table values as 0
    memset(table, 0, sizeof(table));
  
    // Base case (If given value is 0)
    table[0] = 1;
  
    // Pick all coins one by one and update the table[] values
    // after the index greater than or equal to the value of the
    // picked coin
    for(int i=0; i<m; i++)
        for(int j=S[i]; j<=n; j++)
            table[j] += table[j-S[i]];
  
    return table[n];
}

Java

public static int count( int S[], int m, int n )


{
    // table[i] will be storing the number of solutions for
    // value i. We need n+1 rows as the table is constructed
    // in bottom up manner using the base case (n = 0)
    int table[]=new int[n+1];
  
    // Base case (If given value is 0)
    table[0] = 1;
  
    // Pick all coins one by one and update the table[] values
    // after the index greater than or equal to the value of the

98
Chapter 7. DP-07 | Coin Change

    // picked coin


    for(int i=0; i<m; i++)
        for(int j=S[i]; j<=n; j++)
            table[j] += table[j-S[i]];
  
    return table[n];
}

Python

# Dynamic Programming Python implementation of Coin 


# Change problem
def count(S, m, n):
  
    # table[i] will be storing the number of solutions for
    # value i. We need n+1 rows as the table is constructed
    # in bottom up manner using the base case (n = 0)
    # Initialize all table values as 0
    table = [0 for k in range(n+1)]
  
    # Base case (If given value is 0)
    table[0] = 1
  
    # Pick all coins one by one and update the table[] values
    # after the index greater than or equal to the value of the
    # picked coin
    for i in range(0,m):
        for j in range(S[i],n+1):
            table[j] += table[j-S[i]]
  
    return table[n]
  
# Driver program to test above function
arr = [1, 2, 3]
m = len(arr)
n = 4
x = count(arr, m, n)
print (x)
  
# This code is contributed by Afzal Ansari

Thanks to Rohan Laishram for suggesting this space optimized version.


References:
http://www.algorithmist.com/index.php/Coin_Change
Improved By : Sam007, khyatigrover, Mithun Kumar

99
Chapter 7. DP-07 | Coin Change

Source

https://www.geeksforgeeks.org/coin-change-dp-7/

100
Chapter 8

DP-08 | Matrix Chain


Multiplication

Matrix Chain Multiplication | DP-8 - GeeksforGeeks


Given a sequence of matrices, find the most efficient way to multiply these matrices together.
The problem is not actually to perform the multiplications, but merely to decide in which
order to perform the multiplications.
We have many options to multiply a chain of matrices because matrix multiplication is
associative. In other words, no matter how we parenthesize the product, the result will be
the same. For example, if we had four matrices A, B, C, and D, we would have:

(ABC)D = (AB)(CD) = A(BCD) = ....

However, the order in which we parenthesize the product affects the number of simple arith-
metic operations needed to compute the product, or the efficiency. For example, suppose A
is a 10 × 30 matrix, B is a 30 × 5 matrix, and C is a 5 × 60 matrix. Then,

(AB)C = (10×30×5) + (10×5×60) = 1500 + 3000 = 4500 operations


A(BC) = (30×5×60) + (10×30×60) = 9000 + 18000 = 27000 operations.

Clearly the first parenthesization requires less number of operations.


Given an array p[] which represents the chain of matrices such that the ith matrix Ai is of
dimension p[i-1] x p[i]. We need to write a function MatrixChainOrder() that should return
the minimum number of multiplications needed to multiply the chain.

Input: p[] = {40, 20, 30, 10, 30}


Output: 26000
There are 4 matrices of dimensions 40x20, 20x30, 30x10 and 10x30.
Let the input 4 matrices be A, B, C and D. The minimum number of

101
Chapter 8. DP-08 | Matrix Chain Multiplication

multiplications are obtained by putting parenthesis in following way


(A(BC))D --> 20*30*10 + 40*20*10 + 40*10*30

Input: p[] = {10, 20, 30, 40, 30}


Output: 30000
There are 4 matrices of dimensions 10x20, 20x30, 30x40 and 40x30.
Let the input 4 matrices be A, B, C and D. The minimum number of
multiplications are obtained by putting parenthesis in following way
((AB)C)D --> 10*20*30 + 10*30*40 + 10*40*30

Input: p[] = {10, 20, 30}


Output: 6000
There are only two matrices of dimensions 10x20 and 20x30. So there
is only one way to multiply the matrices, cost of which is 10*20*30

1) Optimal Substructure:
A simple solution is to place parenthesis at all possible places, calculate the cost for each
placement and return the minimum value. In a chain of matrices of size n, we can place
the first set of parenthesis in n-1 ways. For example, if the given chain is of 4 matrices.
let the chain be ABCD, then there are 3 ways to place first set of parenthesis outer side:
(A)(BCD), (AB)(CD) and (ABC)(D). So when we place a set of parenthesis, we divide the
problem into subproblems of smaller size. Therefore, the problem has optimal substructure
property and can be easily solved using recursion.
Minimum number of multiplication needed to multiply a chain of size n = Minimum of all
n-1 placements (these placements create subproblems of smaller size)
2) Overlapping Subproblems
Following is a recursive implementation that simply follows the above optimal substructure
property.

/* A naive recursive implementation that simply


  follows the above optimal substructure property */
#include<stdio.h>
#include<limits.h>
  
// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
int MatrixChainOrder(int p[], int i, int j)
{
    if(i == j)
        return 0;
    int k;
    int min = INT_MAX;
    int count;
  
    // place parenthesis at different places between first

102
Chapter 8. DP-08 | Matrix Chain Multiplication

    // and last matrix, recursively calculate count of


    // multiplications for each parenthesis placement and
    // return the minimum count
    for (k = i; k <j; k++)
    {
        count = MatrixChainOrder(p, i, k) +
                MatrixChainOrder(p, k+1, j) +
                p[i-1]*p[k]*p[j];
  
        if (count < min)
            min = count;
    }
  
    // Return minimum count
    return min;
}
  
// Driver program to test above function
int main()
{
    int arr[] = {1, 2, 3, 4, 3};
    int n = sizeof(arr)/sizeof(arr[0]);
  
    printf("Minimum number of multiplications is %d ",
                          MatrixChainOrder(arr, 1, n-1));
  
    getchar();
    return 0;
}

Java

/* A naive recursive implementation that simply follows


   the above optimal substructure property */
class MatrixChainMultiplication
{
    // Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
    static int MatrixChainOrder(int p[], int i, int j)
    {
        if (i == j)
            return 0;
  
        int min = Integer.MAX_VALUE;
  
        // place parenthesis at different places between first
        // and last matrix, recursively calculate count of
        // multiplications for each parenthesis placement and
        // return the minimum count

103
Chapter 8. DP-08 | Matrix Chain Multiplication

        for (int k=i; k<j; k++)


        {
            int count = MatrixChainOrder(p, i, k) +
                        MatrixChainOrder(p, k+1, j) +
                        p[i-1]*p[k]*p[j];
  
            if (count < min)
                min = count;
        }
  
        // Return minimum count
        return min;
    }
  
    // Driver program to test above function
    public static void main(String args[])
    {
        int arr[] = new int[] {1, 2, 3, 4, 3};
        int n = arr.length;
  
        System.out.println("Minimum number of multiplications is "+
                           MatrixChainOrder(arr, 1, n-1));
  
    }
}
/* This code is contributed by Rajat Mishra*/

Python3

# A naive recursive implementation that


# simply follows the above optimal 
# substructure property 
import sys
  
# Matrix A[i] has dimension p[i-1] x p[i]
# for i = 1..n
def MatrixChainOrder(p, i, j):
  
    if i == j:
        return 0
  
    _min = sys.maxsize
      
    # place parenthesis at different places 
    # between first and last matrix, 
    # recursively calculate count of
    # multiplications for each parenthesis
    # placement and return the minimum count

104
Chapter 8. DP-08 | Matrix Chain Multiplication

    for k in range(i, j):


      
        count = (MatrixChainOrder(p, i, k) 
             + MatrixChainOrder(p, k+1, j)
                   + p[i-1] * p[k] * p[j])
  
        if count < _min:
            _min = count;
      
  
    # Return minimum count
    return _min;
  
  
# Driver program to test above function
arr = [1, 2, 3, 4, 3];
n = len(arr);
  
print("Minimum number of multiplications is ",
                MatrixChainOrder(arr, 1, n-1));
  
# This code is contributed by Aryan Garg

C#

/* C# code for naive recursive implementation 


that simply follows the above optimal 
substructure property */
using System;
  
class GFG {
      
    // Matrix Ai has dimension p[i-1] x p[i]
    // for i = 1..n
    static int MatrixChainOrder(int[] p, int i, int j)
    {
          
        if (i == j)
            return 0;
  
        int min = int.MaxValue;
  
        // place parenthesis at different places 
        // between first and last matrix, recursively 
        // calculate count of multiplications for each
        // parenthesis placement and return the 
        // minimum count
        for (int k = i; k < j; k++) {

105
Chapter 8. DP-08 | Matrix Chain Multiplication

            int count = MatrixChainOrder(p, i, k) +


            MatrixChainOrder(p, k + 1, j) + p[i - 1] 
                                       * p[k] * p[j];
  
            if (count < min)
                min = count;
        }
  
        // Return minimum count
        return min;
    }
  
    // Driver program to test above function
    public static void Main()
    {
        int[] arr = new int[]{ 1, 2, 3, 4, 3 };
        int n = arr.Length;
  
        Console.Write("Minimum number of multiplications is "
                          + MatrixChainOrder(arr, 1, n - 1));
    }
}
  
// This code is contributed by Sam007.

Time complexity of the above naive recursive approach is exponential. It should be noted
that the above function computes the same subproblems again and again. See the following
recursion tree for a matrix chain of size 4. The function MatrixChainOrder(p, 3, 4) is called
two times. We can see that there are many subproblems being called more than once.

106
Chapter 8. DP-08 | Matrix Chain Multiplication

Since same suproblems are called again, this problem has Overlapping Subprolems property.
So Matrix Chain Multiplication problem has both properties (see thisand this) of a dynamic
programming problem. Like other typical Dynamic Programming(DP) problems, recompu-
tations of same subproblems can be avoided by constructing a temporary array m[][] in
bottom up manner.
Dynamic Programming Solution
Following is C/C++ implementation for Matrix Chain Multiplication problem using
Dynamic Programming.

// See the Cormen book for details of the following algorithm


#include<stdio.h>
#include<limits.h>
  
// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
int MatrixChainOrder(int p[], int n)
{
  
    /* For simplicity of the program, one extra row and one
       extra column are allocated in m[][].  0th row and 0th
       column of m[][] are not used */
    int m[n][n];
  
    int i, j, k, L, q;
  
    /* m[i,j] = Minimum number of scalar multiplications needed
       to compute the matrix A[i]A[i+1]...A[j] = A[i..j] where
       dimension of A[i] is p[i-1] x p[i] */
  
    // cost is zero when multiplying one matrix.
    for (i=1; i<n; i++)
        m[i][i] = 0;
  
    // L is chain length.
    for (L=2; L<n; L++)
    {
        for (i=1; i<n-L+1; i++)
        {
            j = i+L-1;
            m[i][j] = INT_MAX;
            for (k=i; k<=j-1; k++)
            {
                // q = cost/scalar multiplications
                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if (q < m[i][j])
                    m[i][j] = q;

107
Chapter 8. DP-08 | Matrix Chain Multiplication

            }
        }
    }
  
    return m[1][n-1];
}
  
int main()
{
    int arr[] = {1, 2, 3, 4};
    int size = sizeof(arr)/sizeof(arr[0]);
  
    printf("Minimum number of multiplications is %d ",
                       MatrixChainOrder(arr, size));
  
    getchar();
    return 0;
}

Java

// Dynamic Programming Python implementation of Matrix


// Chain Multiplication.
// See the Cormen book for details of the following algorithm
class MatrixChainMultiplication
{
    // Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
    static int MatrixChainOrder(int p[], int n)
    {
        /* For simplicity of the program, one extra row and one
        extra column are allocated in m[][].  0th row and 0th
        column of m[][] are not used */
        int m[][] = new int[n][n];
  
        int i, j, k, L, q;
  
        /* m[i,j] = Minimum number of scalar multiplications needed
        to compute the matrix A[i]A[i+1]...A[j] = A[i..j] where
        dimension of A[i] is p[i-1] x p[i] */
  
        // cost is zero when multiplying one matrix.
        for (i = 1; i < n; i++)
            m[i][i] = 0;
  
        // L is chain length.
        for (L=2; L<n; L++)
        {
            for (i=1; i<n-L+1; i++)

108
Chapter 8. DP-08 | Matrix Chain Multiplication

            {
                j = i+L-1;
                if(j == n) continue;
                m[i][j] = Integer.MAX_VALUE;
                for (k=i; k<=j-1; k++)
                {
                    // q = cost/scalar multiplications
                    q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                    if (q < m[i][j])
                        m[i][j] = q;
                }
            }
        }
  
        return m[1][n-1];
    }
  
    // Driver program to test above function
    public static void main(String args[])
    {
        int arr[] = new int[] {1, 2, 3, 4};
        int size = arr.length;
  
        System.out.println("Minimum number of multiplications is "+
                           MatrixChainOrder(arr, size));
    }
}
/* This code is contributed by Rajat Mishra*/

Python

# Dynamic Programming Python implementation of Matrix


# Chain Multiplication. See the Cormen book for details
# of the following algorithm
import sys
  
# Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
def MatrixChainOrder(p, n):
    # For simplicity of the program, one extra row and one
    # extra column are allocated in m[][].  0th row and 0th
    # column of m[][] are not used
    m = [[0 for x in range(n)] for x in range(n)]
  
    # m[i,j] = Minimum number of scalar multiplications needed
    # to compute the matrix A[i]A[i+1]...A[j] = A[i..j] where
    # dimension of A[i] is p[i-1] x p[i]
  
    # cost is zero when multiplying one matrix.

109
Chapter 8. DP-08 | Matrix Chain Multiplication

    for i in range(1, n):


        m[i][i] = 0
  
    # L is chain length.
    for L in range(2, n):
        for i in range(1, n-L+1):
            j = i+L-1
            m[i][j] = sys.maxint
            for k in range(i, j):
  
                # q = cost/scalar multiplications
                q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j]
                if q < m[i][j]:
                    m[i][j] = q
  
    return m[1][n-1]
  
# Driver program to test above function
arr = [1, 2, 3 ,4]
size = len(arr)
  
print("Minimum number of multiplications is " +
       str(MatrixChainOrder(arr, size)))
# This Code is contributed by Bhavya Jain

C#

// Dynamic Programming C# implementation of 


// Matrix Chain Multiplication.
// See the Cormen book for details of the 
// following algorithm
using System;
  
class GFG
{
      
    // Matrix Ai has dimension p[i-1] x p[i] 
    // for i = 1..n
    static int MatrixChainOrder(int []p, int n)
    {
          
        /* For simplicity of the program, one 
        extra row and one extra column are 
        allocated in m[][]. 0th row and 0th
        column of m[][] are not used */
        int [ , ]m = new int[n, n];
  
        int i, j, k, L, q;

110
Chapter 8. DP-08 | Matrix Chain Multiplication

  
        /* m[i,j] = Minimum number of scalar 
        multiplications needed
        to compute the matrix A[i]A[i+1]...A[j]
        = A[i..j] where dimension of A[i] is 
        p[i-1] x p[i] */
  
        // cost is zero when multiplying 
        // one matrix.
        for (i = 1; i < n; i++)
            m[i, i] = 0;
  
        // L is chain length.
        for (L = 2; L < n; L++)
        {
            for (i = 1; i < n-L+1; i++)
            {
                j = i+L-1;
                if(j == n) continue;
                m[i, j] = int.MaxValue;
                for (k = i; k <= j-1; k++)
                {
                    // q = cost/scalar multiplications
                    q = m[i, k] + m[k+1, j] + 
                                     p[i-1]*p[k]*p[j];
                    if (q < m[i, j])
                        m[i, j] = q;
                }
            }
        }
  
        return m[1, n-1];
    }
  
    // Driver program to test above function
    public static void Main()
    {
        int []arr = new int[] {1, 2, 3, 4};
        int size = arr.Length;
  
        Console.Write("Minimum number of " + 
                             "multiplications is "+
                        MatrixChainOrder(arr, size));
    }
}
  
// This code is contributed by Sam007

111
Chapter 8. DP-08 | Matrix Chain Multiplication

Output:

Minimum number of multiplications is 18

Time Complexity: O(n^3)


Auxiliary Space: O(n^2)
Printing brackets in Matrix Chain Multiplication Problem
Applications:
Minimum and Maximum values of an expression with * and +
References:
http://en.wikipedia.org/wiki/Matrix_chain_multiplication
http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/Dynamic/
chainMatrixMult.htm
Improved By : aryan21

Source

https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/

112
Chapter 9

DP-09 | Binomial Coefficient

Binomial Coefficient | DP-9 - GeeksforGeeks


Following are common definition of Binomial Coefficients.

1. A binomial coefficient C(n, k) can be defined as the coefficient of X^k in the expansion
of (1 + X)^n.
2. A binomial coefficient C(n, k) also gives the number of ways, disregarding order, that
k objects can be chosen from among n objects; more formally, the number of k-element
subsets (or k-combinations) of an n-element set.

The Problem
Write a function that takes two parameters n and k and returns the value of Binomial
Coefficient C(n, k). For example, your function should return 6 for n = 4 and k = 2, and it
should return 10 for n = 5 and k = 2.
1) Optimal Substructure
The value of C(n, k) can be recursively calculated using following standard formula for
Binomial Coefficients.

C(n, k) = C(n-1, k-1) + C(n-1, k)


C(n, 0) = C(n, n) = 1

Following is a simple recursive implementation that simply follows the recursive structure
mentioned above.
C/C++

// A Naive Recursive Implementation


#include<stdio.h>
  
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)

113
Chapter 9. DP-09 | Binomial Coefficient

{
  // Base Cases
  if (k==0 || k==n)
    return 1;
  
  // Recur
  return  binomialCoeff(n-1, k-1) + binomialCoeff(n-1, k);
}
  
/* Driver program to test above function*/
int main()
{
    int n = 5, k = 2;
    printf("Value of C(%d, %d) is %d ", n, k, binomialCoeff(n, k));
    return 0;
}

Java

// JAVA Code for Dynamic Programming |


// Set 9 (Binomial Coefficient)
import java.util.*;
  
class GFG {
      
    // Returns value of Binomial 
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k) 
    {
      
        // Base Cases
        if (k == 0 || k == n)
            return 1;
          
        // Recur
        return binomialCoeff(n - 1, k - 1) + 
                    binomialCoeff(n - 1, k);
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
   {
        int n = 5, k = 2;
        System.out.printf("Value of C(%d, %d) is %d ",
                        n, k, binomialCoeff(n, k));
    }
}
  

114
Chapter 9. DP-09 | Binomial Coefficient

// This code is contributed by Arnav Kr. Mandal.

Python

# A naive recursive Python implementation


  
def binomialCoeff(n , k):
  
    if k==0 or k ==n :
        return 1
  
    # Recursive Call
    return binomialCoeff(n-1 , k-1) + binomialCoeff(n-1 , k)
  
# Driver Program to test ht above function
n = 5
k = 2
print "Value of C(%d,%d) is (%d)" %(n , k , binomialCoeff(n , k))
  
# This code is contributed by Nikhil Kumar Singh (nickzuck_007)

C#

// C# Code for Dynamic Programming |


// Set 9 (Binomial Coefficient)
using System;
  
class GFG {
      
    // Returns value of Binomial 
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k) 
    {
          
        // Base Cases
        if (k == 0 || k == n)
            return 1;
          
        // Recur
        return binomialCoeff(n - 1, k - 1) + 
                    binomialCoeff(n - 1, k);
    }
      
    /* Driver program to test above function */
    public static void Main() 
    {
        int n = 5, k = 2;

115
Chapter 9. DP-09 | Binomial Coefficient

        Console.Write("Value of C(" + n + "," 


                            + k + ") is " +
                        binomialCoeff(n, k));
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP Code for Dynamic Programming |
// Set 9 (Binomial Coefficient)
  
// Returns value of 
// Binomial Coefficient C(n, k)
function binomialCoeff($n, $k)
{
    // Base Cases
    if ($k==0 || $k==$n)
        return 1;
      
    // Recur
    return binomialCoeff($n - 1, $k - 1) + 
               binomialCoeff($n - 1, $k);
}
  
    // Driver Code
    $n = 5; 
    $k = 2;
    echo "Value of C","(",$n ,$k,") is "
               , binomialCoeff($n, $k);
  
// This code is contributed by aj_36
?>

Output:

Value of C(52) is 10

2) Overlapping Subproblems
It should be noted that the above function computes the same subproblems again and again.
See the following recursion tree for n = 5 an k = 2. The function C(3, 1) is called two times.
For large values of n, there will be many common subproblems.

C(5, 2)

116
Chapter 9. DP-09 | Binomial Coefficient

/ \
C(4, 1) C(4, 2)
/ \ / \
C(3, 0) C(3, 1) C(3, 1) C(3, 2)
/ \ / \ / \
C(2, 0) C(2, 1) C(2, 0) C(2, 1) C(2, 1) C(2, 2)
/ \ / \ / \
C(1, 0) C(1, 1) C(1, 0) C(1, 1) C(1, 0) C(1, 1)

Since same suproblems are called again, this problem has Overlapping Subproblems prop-
erty. So the Binomial Coefficient problem has both properties (see thisand this) of a dy-
namic programming problem. Like other typical Dynamic Programming(DP) problems,
re-computations of same subproblems can be avoided by constructing a temporary array
C[][] in bottom up manner. Following is Dynamic Programming based implementation.
C

// A Dynamic Programming based solution that uses table C[][] to


// calculate the Binomial Coefficient
#include<stdio.h>
  
// Prototype of a utility function that returns minimum of two integers
int min(int a, int b);
  
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    int C[n+1][k+1];
    int i, j;
  
    // Caculate value of Binomial Coefficient in bottom up manner
    for (i = 0; i <= n; i++)
    {
        for (j = 0; j <= min(i, k); j++)
        {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
  
            // Calculate value using previosly stored values
            else
                C[i][j] = C[i-1][j-1] + C[i-1][j];
        }
    }
  
    return C[n][k];
}
  

117
Chapter 9. DP-09 | Binomial Coefficient

// A utility function to return minimum of two integers


int min(int a, int b)
{
    return (a<b)? a: b;
}
  
/* Drier program to test above function*/
int main()
{
    int n = 5, k = 2;
    printf ("Value of C(%d, %d) is %d ", n, k, binomialCoeff(n, k) );
    return 0;
}

Java

// A Dynamic Programming based solution that uses table C[][] to 


// calculate the Binomial Coefficient 
  
class BinomialCoefficient
{
    // Returns value of Binomial Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {
    int C[][] = new int[n+1][k+1];
    int i, j;
      
        // Calculate  value of Binomial Coefficient in bottom up manner
    for (i = 0; i <= n; i++)
    {
        for (j = 0; j <= min(i, k); j++)
        {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
       
            // Calculate value using previosly stored values
            else
                C[i][j] = C[i-1][j-1] + C[i-1][j];
          }
     }
       
    return C[n][k];
    }
  
    // A utility function to return minimum of two integers
    static int min(int a, int b)
    {

118
Chapter 9. DP-09 | Binomial Coefficient

    return (a<b)? a: b; 


    }
  
    /* Driver program to test above function*/
    public static void main(String args[])
    {
    int n = 5, k = 2;
    System.out.println("Value of C("+n+","+k+") is "+binomialCoeff(n, k));
    }
}
/*This code is contributed by Rajat Mishra*/

Python

# A Dynamic Programming based Python Program that uses table C[][]


# to calculate the Binomial Coefficient
  
# Returns value of Binomial Coefficient C(n, k)
def binomialCoef(n, k):
    C = [[0 for x in range(k+1)] for x in range(n+1)]
  
    # Calculate value of Binomial Coefficient in bottom up manner
    for i in range(n+1):
        for j in range(min(i, k)+1):
            # Base Cases
            if j == 0 or j == i:
                C[i][j] = 1
  
            # Calculate value using previosly stored values
            else:
                C[i][j] = C[i-1][j-1] + C[i-1][j]
  
    return C[n][k]
  
# Driver program to test above function
n = 5
k = 2
print("Value of C[" + str(n) + "][" + str(k) + "] is "
      + str(binomialCoef(n,k)))
  
# This code is contributed by Bhavya Jain

C#

// A Dynamic Programming based solution that


// uses table C[][] to calculate the Binomial
// Coefficient 

119
Chapter 9. DP-09 | Binomial Coefficient

using System;
  
class GFG {
      
    // Returns value of Binomial Coefficient
    // C(n, k)
    static int binomialCoeff(int n, int k)
    {
        int [,]C = new int[n+1,k+1];
        int i, j;
          
        // Calculate value of Binomial 
        // Coefficient in bottom up manner
        for (i = 0; i <= n; i++)
        {
            for (j = 0; j <= Math.Min(i, k); j++)
            {
                // Base Cases
                if (j == 0 || j == i)
                    C[i,j] = 1;
          
                // Calculate value using previosly
                // stored values
                else
                    C[i,j] = C[i-1,j-1] + C[i-1,j];
            }
        }
          
        return C[n,k];
    }
  
    // A utility function to return minimum
    // of two integers
    static int min(int a, int b)
    {
        return (a < b) ? a : b; 
    }
  
    /* Driver program to test above function*/
    public static void Main()
    {
        int n = 5, k = 2;
        Console.WriteLine("Value of C(" + n
                        + "," + k + ") is "
                    + binomialCoeff(n, k));
    }
}
  

120
Chapter 9. DP-09 | Binomial Coefficient

// This code is contributed by anuj_67.

PHP

<?php
// A Dynamic Programming based 
// solution that uses table C[][] to
// calculate the Binomial Coefficient
  
// Returns value of Binomial 
// Coefficient C(n, k)
function binomialCoeff( $n, $k)
{
    $C = array(array());
    $i; $j;
  
    // Caculate value of Binomial
    // Coefficient in bottom up manner
    for ($i = 0; $i <= $n; $i++)
    {
        for ($j = 0; $j <= min($i, $k); $j++)
        {
              
            // Base Cases
            if ($j == 0 || $j == $i)
                $C[$i][$j] = 1;
  
            // Calculate value using 
            // previosly stored values
            else
                $C[$i][$j] = $C[$i - 1][$j - 1] + 
                                 $C[$i - 1][$j];
        }
    }
  
    return $C[$n][$k];
}
  
    // Driver Code
    $n = 5; 
    $k = 2;
    echo "Value of C(" ,$n," ",$k, ") is"," "
                 , binomialCoeff($n, $k) ;
  
// This code is contributed by anuj_67.
?>

Output:

121
Chapter 9. DP-09 | Binomial Coefficient

Value of C[5][2] is 10

Time Complexity: O(n*k)


Auxiliary Space: O(n*k)
Following is a space optimized version of the above code. The following code only uses
O(k). Thanks to AK for suggesting this method.

C/C++

// C++ program for space optimized Dynamic Programming


// Solution of Binomial Coefficient
#include<bits/stdc++.h>
using namespace std;
  
int binomialCoeff(int n, int k)
{
    int C[k+1];
    memset(C, 0, sizeof(C));
  
    C[0] = 1;  // nC0 is 1
  
    for (int i = 1; i <= n; i++)
    {
        // Compute next row of pascal triangle using
        // the previous row
        for (int j = min(i, k); j > 0; j--)
            C[j] = C[j] + C[j-1];
    }
    return C[k];
}
  
/* Drier program to test above function*/
int main()
{
    int n = 5, k = 2;
    printf ("Value of C(%d, %d) is %d ",
            n, k, binomialCoeff(n, k) );
    return 0;
}

Java

// JAVA Code for Dynamic Programming | 


// Set 9 (Binomial Coefficient)
import java.util.*;
  

122
Chapter 9. DP-09 | Binomial Coefficient

class GFG {
      
    static int binomialCoeff(int n, int k)
    {
        int C[] = new int[k + 1];
         
        // nC0 is 1
        C[0] = 1;  
       
        for (int i = 1; i <= n; i++)
        {
            // Compute next row of pascal 
            // triangle using the previous row
            for (int j = Math.min(i, k); j > 0; j--)
                C[j] = C[j] + C[j-1];
        }
        return C[k];
    }
      
    /* Driver program  */
    public static void main(String[] args) 
    {
         int n = 5, k = 2;
            System.out.printf("Value of C(%d, %d) is %d "
                                , n, k, binomialCoeff(n, k));
    }
}

Python

# Python program for Optimized Dynamic Programming solution to


# Binomail Coefficient. This one uses the concept of pascal
# Triangle and less memory
  
def binomialCoeff(n , k):
  
    # Declaring an empty array
    C = [0 for i in xrange(k+1)]
    C[0] = 1 #since nC0 is 1
  
    for i in range(1,n+1):
  
        # Compute next row of pascal triangle using
        # the previous row
        j = min(i ,k)
        while (j>0):
            C[j] = C[j] + C[j-1]
            j -= 1

123
Chapter 9. DP-09 | Binomial Coefficient

  
    return C[k]
  
# Driver Program to test the above function
n = 5
k = 2
print "Value of C(%d,%d) is %d" %(n,k,binomialCoeff(n,k))
  
# This code is contribtued by Nikhil Kumar Singh(nickzuck_007)

C#

// C# Code for Dynamic Programming | 


// Set 9 (Binomial Coefficient)
using System;
  
class GFG {
      
    static int binomialCoeff(int n, int k)
    {
        int[] C = new int[k + 1];
          
        // nC0 is 1
        C[0] = 1; 
      
        for (int i = 1; i <= n; i++)
        {
            // Compute next row of pascal 
            // triangle using the previous
            // row
            for (int j = Math.Min(i, k);
                              j > 0; j--)
                C[j] = C[j] + C[j-1];
        }
        return C[k];
    }
      
    /* Driver program */
    public static void Main() 
    {
        int n = 5, k = 2;
        Console.WriteLine("Value of C(" 
                + n + " " + k + ") is " 
                + binomialCoeff(n, k));
    }
}
  
// This code is contribtued by anuj_67.

124
Chapter 9. DP-09 | Binomial Coefficient

PHP

<?php
// PHP program for space optimized 
// Dynamic Programming Solution of 
// Binomial Coefficient
function binomialCoeff($n, $k)
{
    $C = array_fill(0, $k + 1, 0);
  
    $C[0] = 1; // nC0 is 1
  
    for ($i = 1; $i <= $n; $i++)
    {
        // Compute next row of pascal 
        // triangle using the previous row
        for ($j = min($i, $k); $j > 0; $j--)
            $C[$j] = $C[$j] + $C[$j - 1];
    }
    return $C[$k];
}
  
// Driver Code
$n = 5; $k = 2;
echo "Value of C[$n, $k] is ". 
        binomialCoeff($n, $k);
      
// This code is contributed by mits.
?>

Output:

Value of C[5][2] is 10

Time Complexity: O(n*k)


Auxiliary Space: O(k)
Explanation:
1==========>> n = 0, C(0,0) = 1
1–1========>> n = 1, C(1,0) = 1, C(1,1) = 1
1–2–1======>> n = 2, C(2,0) = 1, C(2,1) = 2, C(2,2) = 1
1–3–3–1====>> n = 3, C(3,0) = 1, C(3,1) = 3, C(3,2) = 3, C(3,3)=1
1–4–6–4–1==>> n = 4, C(4,0) = 1, C(4,1) = 4, C(4,2) = 6, C(4,3)=4, C(4,4)=1
So here every loop on i, builds i’th row of pascal triangle, using (i-1)th row
At any time, every element of array C will have some value (ZERO or more) and in next
iteration, value for those elements comes from previous iteration.
In statement,

125
Chapter 9. DP-09 | Binomial Coefficient

C[j] = C[j] + C[j-1]


Right hand side represents the value coming from previous iteration (A row of Pascal’s
triangle depends on previous row). Left Hand side represents the value of current iteration
which will be obtained by this statement.

Let's say we want to calculate C(4, 3),


i.e. n=4, k=3:

All elements of array C of size 4 (k+1) are


initialized to ZERO.

i.e. C[0] = C[1] = C[2] = C[3] = C[4] = 0;


Then C[0] is set to 1

For i = 1:
C[1] = C[1] + C[0] = 0 + 1 = 1 ==>> C(1,1) = 1

For i = 2:
C[2] = C[2] + C[1] = 0 + 1 = 1 ==>> C(2,2) = 1
C[1] = C[1] + C[0] = 1 + 1 = 2 ==>> C(2,2) = 2

For i=3:
C[3] = C[3] + C[2] = 0 + 1 = 1 ==>> C(3,3) = 1
C[2] = C[2] + C[1] = 1 + 2 = 3 ==>> C(3,2) = 3
C[1] = C[1] + C[0] = 2 + 1 = 3 ==>> C(3,1) = 3

For i=4:
C[4] = C[4] + C[3] = 0 + 1 = 1 ==>> C(4,4) = 1
C[3] = C[3] + C[2] = 1 + 3 = 4 ==>> C(4,3) = 4
C[2] = C[2] + C[1] = 3 + 3 = 6 ==>> C(4,2) = 6
C[1] = C[1] + C[0] = 3 + 1 = 4 ==>> C(4,1) = 4

C(4,3) = 4 is would be the answer in our example.

See this for Space and time efficient Binomial Coefficient


References:
http://www.csl.mtu.edu/cs4321/www/Lectures/Lecture%2015%20-%20Dynamic%
20Programming%20Binomial%20Coefficients.htm
Improved By : jit_t, vt_m, Mithun Kumar

Source

https://www.geeksforgeeks.org/binomial-coefficient-dp-9/

126
Chapter 10

DP-10 | 0-1 Knapsack Problem

0-1 Knapsack Problem | DP-10 - GeeksforGeeks


Given weights and values of n items, put these items in a knapsack of capacity W to get the
maximum total value in the knapsack. In other words, given two integer arrays val[0..n-1]
and wt[0..n-1] which represent values and weights associated with n items respectively. Also
given an integer W which represents knapsack capacity, find out the maximum value subset
of val[] such that sum of the weights of this subset is smaller than or equal to W. You cannot
break an item, either pick the complete item, or don’t pick it (0-1 property).

A simple solution is to consider all subsets of items and calculate the total weight and value
of all subsets. Consider the only subsets whose total weight is smaller than W. From all
such subsets, pick the maximum value subset.
1) Optimal Substructure:
To consider all subsets of items, there can be two cases for every item: (1) the item is
included in the optimal subset, (2) not included in the optimal set.
Therefore, the maximum value that can be obtained from n items is max of following two
values.
1) Maximum value obtained by n-1 items and W weight (excluding nth item).

127
Chapter 10. DP-10 | 0-1 Knapsack Problem

2) Value of nth item plus maximum value obtained by n-1 items and W minus weight of the
nth item (including nth item).
If weight of nth item is greater than W, then the nth item cannot be included and case 1 is
the only possibility.
2) Overlapping Subproblems
Following is recursive implementation that simply follows the recursive structure mentioned
above.

C/C++

/* A Naive recursive implementation of 0-1 Knapsack problem */


#include<stdio.h>
  
// A utility function that returns maximum of two integers
int max(int a, int b) { return (a > b)? a : b; }
  
// Returns the maximum value that can be put in a knapsack of capacity W
int knapSack(int W, int wt[], int val[], int n)
{
   // Base Case
   if (n == 0 || W == 0)
       return 0;
  
   // If weight of the nth item is more than Knapsack capacity W, then
   // this item cannot be included in the optimal solution
   if (wt[n-1] > W)
       return knapSack(W, wt, val, n-1);
  
   // Return the maximum of two cases: 
   // (1) nth item included 
   // (2) not included
   else return max( val[n-1] + knapSack(W-wt[n-1], wt, val, n-1),
                    knapSack(W, wt, val, n-1)
                  );
}
  
// Driver program to test above function
int main()
{
    int val[] = {60, 100, 120};
    int wt[] = {10, 20, 30};
    int  W = 50;
    int n = sizeof(val)/sizeof(val[0]);
    printf("%d", knapSack(W, wt, val, n));
    return 0;
}

128
Chapter 10. DP-10 | 0-1 Knapsack Problem

Java

/* A Naive recursive implementation of 0-1 Knapsack problem */


class Knapsack
{
  
    // A utility function that returns maximum of two integers
     static int max(int a, int b) { return (a > b)? a : b; }
       
     // Returns the maximum value that can be put in a knapsack of capacity W
     static int knapSack(int W, int wt[], int val[], int n)
     {
        // Base Case
    if (n == 0 || W == 0)
        return 0;
       
    // If weight of the nth item is more than Knapsack capacity W, then
    // this item cannot be included in the optimal solution
    if (wt[n-1] > W)
       return knapSack(W, wt, val, n-1);
       
    // Return the maximum of two cases: 
    // (1) nth item included 
    // (2) not included
    else return max( val[n-1] + knapSack(W-wt[n-1], wt, val, n-1),
                     knapSack(W, wt, val, n-1)
                      );
      }
  
    
   // Driver program to test above function
   public static void main(String args[])
   {
        int val[] = new int[]{60, 100, 120};
        int wt[] = new int[]{10, 20, 30};
    int  W = 50;
    int n = val.length;
    System.out.println(knapSack(W, wt, val, n));
    }
}
/*This code is contributed by Rajat Mishra */

Python

#A naive recursive implementation of 0-1 Knapsack Problem


  
# Returns the maximum value that can be put in a knapsack of

129
Chapter 10. DP-10 | 0-1 Knapsack Problem

# capacity W
def knapSack(W , wt , val , n):
  
    # Base Case
    if n == 0 or W == 0 :
        return 0
  
    # If weight of the nth item is more than Knapsack of capacity
    # W, then this item cannot be included in the optimal solution
    if (wt[n-1] > W):
        return knapSack(W , wt , val , n-1)
  
    # return the maximum of two cases:
    # (1) nth item included
    # (2) not included
    else:
        return max(val[n-1] + knapSack(W-wt[n-1] , wt , val , n-1),
                   knapSack(W , wt , val , n-1))
  
# end of function knapSack
  
# To test above function
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print knapSack(W , wt , val , n)
  
# This code is contributed by Nikhil Kumar Singh

C#

/* A Naive recursive implementation of 


0-1 Knapsack problem */
using System;
  
class GFG {
      
    // A utility function that returns
    // maximum of two integers
    static int max(int a, int b) 
    {
        return (a > b)? a : b; 
    }
      
    // Returns the maximum value that can 
    // be put in a knapsack of capacity W
    static int knapSack(int W, int []wt, 

130
Chapter 10. DP-10 | 0-1 Knapsack Problem

                        int []val, int n)


    {
          
        // Base Case
        if (n == 0 || W == 0)
            return 0;
      
        // If weight of the nth item is 
        // more than Knapsack capacity W,
        // then this item cannot be 
        // included in the optimal solution
        if (wt[n-1] > W)
            return knapSack(W, wt, val, n-1);
          
        // Return the maximum of two cases: 
        // (1) nth item included 
        // (2) not included
        else return max( val[n-1] +
            knapSack(W-wt[n-1], wt, val, n-1),
                   knapSack(W, wt, val, n-1));
    }
  
    // Driver function
    public static void Main()
    {
        int []val = new int[]{60, 100, 120};
        int []wt = new int[]{10, 20, 30};
        int W = 50;
        int n = val.Length;
          
        Console.WriteLine(knapSack(W, wt, val, n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// A Naive recursive implementation
// of 0-1 Knapsack problem 
  
// Returns the maximum value that
// can be put in a knapsack of 
// capacity W
function knapSack($W, $wt, $val, $n)
{
    // Base Case

131
Chapter 10. DP-10 | 0-1 Knapsack Problem

    if ($n == 0 || $W == 0)
        return 0;
      
    // If weight of the nth item is 
    // more than Knapsack capacity 
    // W, then this item cannot be
    // included in the optimal solution
    if ($wt[$n - 1] > $W)
        return knapSack($W, $wt, $val, $n - 1);
      
    // Return the maximum of two cases: 
    // (1) nth item included 
    // (2) not included
    else
        return max($val[$n - 1] + 
               knapSack($W - $wt[$n - 1], 
               $wt, $val, $n - 1), 
               knapSack($W, $wt, $val, $n-1));
}
  
    // Driver Code
    $val = array(60, 100, 120);
    $wt = array(10, 20, 30);
    $W = 50;
    $n = count($val);
    echo knapSack($W, $wt, $val, $n);
  
// This code is contributed by Sam007
?>

Output:

220

It should be noted that the above function computes the same subproblems again and again.
See the following recursion tree, K(1, 1) is being evaluated twice. Time complexity of this
naive recursive solution is exponential (2^n).

In the following recursion tree, K() refers to knapSack(). The two


parameters indicated in the following recursion tree are n and W.
The recursion tree is for following sample inputs.
wt[] = {1, 1, 1}, W = 2, val[] = {10, 20, 30}

K(3, 2) ---------> K(n, W)


/ \
/ \
K(2,2) K(2,1)

132
Chapter 10. DP-10 | 0-1 Knapsack Problem

/ \ / \
/ \ / \
K(1,2) K(1,1) K(1,1) K(1,0)
/ \ / \ / \
/ \ / \ / \
K(0,2) K(0,1) K(0,1) K(0,0) K(0,1) K(0,0)
Recursion tree for Knapsack capacity 2 units and 3 items of 1 unit weight.

Since suproblems are evaluated again, this problem has Overlapping Subprolems property.
So the 0-1 Knapsack problem has both properties (see thisand this) of a dynamic program-
ming problem. Like other typical Dynamic Programming(DP) problems, recomputations
of same subproblems can be avoided by constructing a temporary array K[][] in bottom up
manner. Following is Dynamic Programming based implementation.
C++

// A Dynamic Programming based solution for 0-1 Knapsack problem


#include<stdio.h>
  
// A utility function that returns maximum of two integers
int max(int a, int b) { return (a > b)? a : b; }
  
// Returns the maximum value that can be put in a knapsack of capacity W
int knapSack(int W, int wt[], int val[], int n)
{
   int i, w;
   int K[n+1][W+1];
  
   // Build table K[][] in bottom up manner
   for (i = 0; i <= n; i++)
   {
       for (w = 0; w <= W; w++)
       {
           if (i==0 || w==0)
               K[i][w] = 0;
           else if (wt[i-1] <= w)
                 K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]],  K[i-1][w]);
           else
                 K[i][w] = K[i-1][w];
       }
   }
  
   return K[n][W];
}
  
int main()
{
    int val[] = {60, 100, 120};

133
Chapter 10. DP-10 | 0-1 Knapsack Problem

    int wt[] = {10, 20, 30};


    int  W = 50;
    int n = sizeof(val)/sizeof(val[0]);
    printf("%d", knapSack(W, wt, val, n));
    return 0;
}

Java

// A Dynamic Programming based solution for 0-1 Knapsack problem


class Knapsack
{
  
    // A utility function that returns maximum of two integers
    static int max(int a, int b) { return (a > b)? a : b; }
       
   // Returns the maximum value that can be put in a knapsack of capacity W
    static int knapSack(int W, int wt[], int val[], int n)
    {
         int i, w;
     int K[][] = new int[n+1][W+1];
       
     // Build table K[][] in bottom up manner
     for (i = 0; i <= n; i++)
     {
         for (w = 0; w <= W; w++)
         {
             if (i==0 || w==0)
                  K[i][w] = 0;
             else if (wt[i-1] <= w)
                   K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]],  K[i-1][w]);
             else
                   K[i][w] = K[i-1][w];
         }
      }
       
      return K[n][W];
    }
  
    
    // Driver program to test above function
    public static void main(String args[])
    {
        int val[] = new int[]{60, 100, 120};
    int wt[] = new int[]{10, 20, 30};
    int  W = 50;
    int n = val.length;
    System.out.println(knapSack(W, wt, val, n));

134
Chapter 10. DP-10 | 0-1 Knapsack Problem

    }
}
/*This code is contributed by Rajat Mishra */

Python

# A Dynamic Programming based Python Program for 0-1 Knapsack problem


# Returns the maximum value that can be put in a knapsack of capacity W
def knapSack(W, wt, val, n):
    K = [[0 for x in range(W+1)] for x in range(n+1)]
  
    # Build table K[][] in bottom up manner
    for i in range(n+1):
        for w in range(W+1):
            if i==0 or w==0:
                K[i][w] = 0
            elif wt[i-1] <= w:
                K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]],  K[i-1][w])
            else:
                K[i][w] = K[i-1][w]
  
    return K[n][W]
  
# Driver program to test above function
val = [60, 100, 120]
wt = [10, 20, 30]
W = 50
n = len(val)
print(knapSack(W, wt, val, n))
  
# This code is contributed by Bhavya Jain

C#

// A Dynamic Programming based solution for


// 0-1 Knapsack problem
using System;
  
class GFG {
      
    // A utility function that returns 
    // maximum of two integers
    static int max(int a, int b)
    {
        return (a > b) ? a : b;
    }
      

135
Chapter 10. DP-10 | 0-1 Knapsack Problem

    // Returns the maximum value that


    // can be put in a knapsack of 
    // capacity W
    static int knapSack(int W, int []wt, 
                         int []val, int n)
    {
        int i, w;
        int [,]K = new int[n+1,W+1];
          
        // Build table K[][] in bottom 
        // up manner
        for (i = 0; i <= n; i++)
        {
            for (w = 0; w <= W; w++)
            {
                if (i == 0 || w == 0)
                    K[i,w] = 0;
                else if (wt[i-1] <= w)
                    K[i,w] = Math.Max(val[i-1] 
                           + K[i-1,w-wt[i-1]],
                                    K[i-1,w]);
                else
                    K[i,w] = K[i-1,w];
            }
        }
          
        return K[n,W];
    }
      
    // Driver code
    static void Main()
    {
        int []val = new int[]{60, 100, 120};
        int []wt = new int[]{10, 20, 30};
        int W = 50;
        int n = val.Length;
          
        Console.WriteLine(
                  knapSack(W, wt, val, n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// A Dynamic Programming based solution

136
Chapter 10. DP-10 | 0-1 Knapsack Problem

// for 0-1 Knapsack problem


  
// Returns the maximum value that
// can be put in a knapsack of 
// capacity W
function knapSack($W, $wt, $val, $n)
{
      
    $K = array(array());
      
    // Build table K[][] in
    // bottom up manner
    for ($i = 0; $i <= $n; $i++)
    {
        for ($w = 0; $w <= $W; $w++)
        {
            if ($i == 0 || $w == 0)
                $K[$i][$w] = 0;
            else if ($wt[$i - 1] <= $w)
                    $K[$i][$w] = max($val[$i - 1] + 
                                     $K[$i - 1][$w - 
                                     $wt[$i - 1]], 
                                     $K[$i - 1][$w]);
            else
                    $K[$i][$w] = $K[$i - 1][$w];
        }
    }
      
    return $K[$n][$W];
}
  
    // Driver Code
    $val = array(60, 100, 120);
    $wt = array(10, 20, 30);
    $W = 50;
    $n = count($val);
    echo knapSack($W, $wt, $val, $n);
      
// This code is contributed by Sam007.
?>

Output:

220

Time Complexity: O(nW) where n is the number of items and W is the capacity of knapsack.
References:
http://www.es.ele.tue.nl/education/5MC10/Solutions/knapsack.pdf

137
Chapter 10. DP-10 | 0-1 Knapsack Problem

http://www.cse.unl.edu/~goddard/Courses/CSCE310J/Lectures/Lecture8-DynamicProgramming.
pdf
Improved By : Sam007

Source

https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/

138
Chapter 11

DP-11 | Egg Dropping Puzzle

Egg Dropping Puzzle | DP-11 - GeeksforGeeks


The following is a description of the instance of this famous puzzle involving n=2 eggs and
a building with k=36 floors.
Suppose that we wish to know which stories in a 36-story building are safe to drop eggs
from, and which will cause the eggs to break on landing. We make a few assumptions:
…..An egg that survives a fall can be used again.
…..A broken egg must be discarded.
…..The effect of a fall is the same for all eggs.
…..If an egg breaks when dropped, then it would break if dropped from a higher floor.
…..If an egg survives a fall then it would survive a shorter fall.
…..It is not ruled out that the first-floor windows break eggs, nor is it ruled out that the
36th-floor do not cause an egg to break.
If only one egg is available and we wish to be sure of obtaining the right result, the experiment
can be carried out in only one way. Drop the egg from the first-floor window; if it survives,
drop it from the second floor window. Continue upward until it breaks. In the worst case,
this method may require 36 droppings. Suppose 2 eggs are available. What is the least
number of egg-droppings that is guaranteed to work in all cases?
The problem is not actually to find the critical floor, but merely to decide floors from which
eggs should be dropped so that total number of trials are minimized.
Source: Wiki for Dynamic Programming
In this post, we will discuss solution to a general problem with n eggs and k floors. The
solution is to try dropping an egg from every floor (from 1 to k) and recursively calculate the
minimum number of droppings needed in worst case. The floor which gives the minimum
value in worst case is going to be part of the solution.
In the following solutions, we return the minimum number of trials in worst case; these
solutions can be easily modified to print floor numbers of every trials also.
1) Optimal Substructure:
When we drop an egg from a floor x, there can be two cases (1) The egg breaks (2) The egg
doesn’t break.

139
Chapter 11. DP-11 | Egg Dropping Puzzle

1) If the egg breaks after dropping from xth floor, then we only need to check for floors
lower than x with remaining eggs; so the problem reduces to x-1 floors and n-1 eggs
2) If the egg doesn’t break after dropping from the xth floor, then we only need to check for
floors higher than x; so the problem reduces to k-x floors and n eggs.
Since we need to minimize the number of trials in worst case, we take the maximum of two
cases. We consider the max of above two cases for every floor and choose the floor which
yields minimum number of trials.

k ==> Number of floors


n ==> Number of Eggs
eggDrop(n, k) ==> Minimum number of trials needed to find the critical
floor in worst case.
eggDrop(n, k) = 1 + min{max(eggDrop(n - 1, x - 1), eggDrop(n, k - x)):
x in {1, 2, ..., k}}

2) Overlapping Subproblems
Following is recursive implementation that simply follows the recursive structure mentioned
above.
C

# include <stdio.h>
# include <limits.h>
  
// A utility function to get maximum of two integers
int max(int a, int b) { return (a > b)? a: b; }
  
/* Function to get minimum number of trials needed in worst
  case with n eggs and k floors */
int eggDrop(int n, int k)
{
    // If there are no floors, then no trials needed. OR if there is
    // one floor, one trial needed.
    if (k == 1 || k == 0)
        return k;
  
    // We need k trials for one egg and k floors
    if (n == 1)
        return k;
  
    int min = INT_MAX, x, res;
  
    // Consider all droppings from 1st floor to kth floor and
    // return the minimum of these values plus 1.
    for (x = 1; x <= k; x++)
    {

140
Chapter 11. DP-11 | Egg Dropping Puzzle

        res = max(eggDrop(n-1, x-1), eggDrop(n, k-x));


        if (res < min)
            min = res;
    }
  
    return min + 1;
}
  
/* Driver program to test to pront printDups*/
int main()
{
    int n = 2, k = 10;
    printf ("nMinimum number of trials in worst case with %d eggs and "
             "%d floors is %d \n", n, k, eggDrop(n, k));
    return 0;
}

C#

using System;
  
class GFG {
      
    /* Function to get minimum number of 
    trials needed in worst case with n 
    eggs and k floors */
    static int eggDrop(int n, int k)
    {
        // If there are no floors, then 
        // no trials needed. OR if there
        // is one floor, one trial needed.
        if (k == 1 || k == 0)
            return k;
      
        // We need k trials for one egg
        // and k floors
        if (n == 1)
            return k;
      
        int min = int.MaxValue;
        int x, res;
      
        // Consider all droppings from 
        //1st floor to kth floor and
        // return the minimum of these
        // values plus 1.
        for (x = 1; x <= k; x++)
        {

141
Chapter 11. DP-11 | Egg Dropping Puzzle

            res = Math.Max(eggDrop(n-1, x-1), 


                           eggDrop(n, k-x));
            if (res < min)
                min = res;
        }
      
        return min + 1;
    }
      
    // Driver code
    static void Main()
    {
        int n = 2, k = 10;
        Console.Write("Minimum number of "
            + "trials in worst case with "
                   + n + " eggs and " + k
          + " floors is " + eggDrop(n, k));
    }
}
  
// This code is contributed by Sam007.

Output:
Minimum number of trials in worst case with 2 eggs and 10 floors is 4

It should be noted that the above function computes the same subproblems again and again.
See the following partial recursion tree, E(2, 2) is being evaluated twice. There will many
repeated subproblems when you draw the complete recursion tree even for small values of
n and k.

E(2,4)
|
-------------------------------------
| | | |
| | | |
x=1/ x=2/ x=3/ x=4/
/ / .... ....
/ /
E(1,0) E(2,3) E(1,1) E(2,2)
/ /... /
x=1/ .....
/
E(1,0) E(2,2)
/

142
Chapter 11. DP-11 | Egg Dropping Puzzle

......

Partial recursion tree for 2 eggs and 4 floors.

Since same suproblems are called again, this problem has Overlapping Subprolems property.
So Egg Dropping Puzzle has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, recomputations of same
subproblems can be avoided by constructing a temporary array eggFloor[][] in bottom up
manner.
Dynamic Programming Solution
Following are the implementations for Egg Dropping problem using Dynamic Programming.

C++

// A Dynamic Programming based C++ Program for the Egg Dropping Puzzle
# include <stdio.h>
# include <limits.h>
  
// A utility function to get maximum of two integers
int max(int a, int b) { return (a > b)? a: b; }
  
/* Function to get minimum number of trials needed in worst
  case with n eggs and k floors */
int eggDrop(int n, int k)
{
    /* A 2D table where entery eggFloor[i][j] will represent minimum
       number of trials needed for i eggs and j floors. */
    int eggFloor[n+1][k+1];
    int res;
    int i, j, x;
  
    // We need one trial for one floor and0 trials for 0 floors
    for (i = 1; i <= n; i++)
    {
        eggFloor[i][1] = 1;
        eggFloor[i][0] = 0;
    }
  
    // We always need j trials for one egg and j floors.
    for (j = 1; j <= k; j++)
        eggFloor[1][j] = j;
  
    // Fill rest of the entries in table using optimal substructure
    // property
    for (i = 2; i <= n; i++)
    {
        for (j = 2; j <= k; j++)

143
Chapter 11. DP-11 | Egg Dropping Puzzle

        {
            eggFloor[i][j] = INT_MAX;
            for (x = 1; x <= j; x++)
            {
                res = 1 + max(eggFloor[i-1][x-1], eggFloor[i][j-x]);
                if (res < eggFloor[i][j])
                    eggFloor[i][j] = res;
            }
        }
    }
  
    // eggFloor[n][k] holds the result
    return eggFloor[n][k];
}
  
/* Driver program to test to pront printDups*/
int main()
{
    int n = 2, k = 36;
    printf ("nMinimum number of trials in worst case with %d eggs and "
             "%d floors is %d \n", n, k, eggDrop(n, k));
    return 0;
}

Java

//A Dynamic Programming based Python Program for the Egg Dropping Puzzle
class EggDrop
{
    // A utility function to get maximum of two integers
    static int max(int a, int b) { return (a > b)? a: b; }
       
    /* Function to get minimum number of trials needed in worst
    case with n eggs and k floors */
    static int eggDrop(int n, int k)
    {
       /* A 2D table where entery eggFloor[i][j] will represent minimum
       number of trials needed for i eggs and j floors. */
        int eggFloor[][] = new int[n+1][k+1];
        int res;
        int i, j, x;
           
        // We need one trial for one floor and0 trials for 0 floors
        for (i = 1; i <= n; i++)
        {
            eggFloor[i][1] = 1;
            eggFloor[i][0] = 0;
        }

144
Chapter 11. DP-11 | Egg Dropping Puzzle

           
       // We always need j trials for one egg and j floors.
        for (j = 1; j <= k; j++)
            eggFloor[1][j] = j;
           
        // Fill rest of the entries in table using optimal substructure
        // property
        for (i = 2; i <= n; i++)
        {
            for (j = 2; j <= k; j++)
            {
                eggFloor[i][j] = Integer.MAX_VALUE;
                for (x = 1; x <= j; x++)
                {
                     res = 1 + max(eggFloor[i-1][x-1], eggFloor[i][j-x]);
                     if (res < eggFloor[i][j])
                        eggFloor[i][j] = res;
                }
            }
        }
           
        // eggFloor[n][k] holds the result
        return eggFloor[n][k];
  
    }
           
    /* Driver program to test to pront printDups*/
    public static void  main(String args[] )
    {
        int n = 2, k = 10;
        System.out.println("Minimum number of trials in worst case with "+n+"  eggs and "+k+
                 " floors is "+eggDrop(n, k));   
    }
}
/*This code is contributed by Rajat Mishra*/

Python

# A Dynamic Programming based Python Program for the Egg Dropping Puzzle
INT_MAX = 32767
  
# Function to get minimum number of trials needed in worst
# case with n eggs and k floors
def eggDrop(n, k):
    # A 2D table where entery eggFloor[i][j] will represent minimum
    # number of trials needed for i eggs and j floors.
    eggFloor = [[0 for x in range(k+1)] for x in range(n+1)]
  

145
Chapter 11. DP-11 | Egg Dropping Puzzle

    # We need one trial for one floor and0 trials for 0 floors
    for i in range(1, n+1):
        eggFloor[i][1] = 1
        eggFloor[i][0] = 0
  
    # We always need j trials for one egg and j floors.
    for j in range(1, k+1):
        eggFloor[1][j] = j
  
    # Fill rest of the entries in table using optimal substructure
    # property
    for i in range(2, n+1):
        for j in range(2, k+1):
            eggFloor[i][j] = INT_MAX
            for x in range(1, j+1):
                res = 1 + max(eggFloor[i-1][x-1], eggFloor[i][j-x])
                if res < eggFloor[i][j]:
                    eggFloor[i][j] = res
  
    # eggFloor[n][k] holds the result
    return eggFloor[n][k]
  
# Driver program to test to pront printDups
n = 2
k = 36
print("Minimum number of trials in worst case with" + str(n) + "eggs and " 
       + str(k) + " floors is " + str(eggDrop(n, k)))
  
# This code is contributed by Bhavya Jain

C#

// A Dynamic Programming based Python Program


// for the Egg Dropping Puzzle
using System;
  
class GFG {
      
    // A utility function to get maximum of 
    // two integers
    static int max(int a, int b) 
    {
        return (a > b) ? a: b;
    }
      
    /* Function to get minimum number of 
    trials needed in worst case with n
    eggs and k floors */

146
Chapter 11. DP-11 | Egg Dropping Puzzle

    static int eggDrop(int n, int k)


    {
          
        /* A 2D table where entery eggFloor[i][j]
        will represent minimum number of trials
        needed for i eggs and j floors. */
        int [,]eggFloor = new int[n+1,k+1];
        int res;
        int i, j, x;
          
        // We need one trial for one floor and0
        // trials for 0 floors
        for (i = 1; i <= n; i++)
        {
            eggFloor[i,1] = 1;
            eggFloor[i,0] = 0;
        }
          
        // We always need j trials for one egg
        // and j floors.
        for (j = 1; j <= k; j++)
            eggFloor[1,j] = j;
          
        // Fill rest of the entries in table 
        // using optimal substructure property
        for (i = 2; i <= n; i++)
        {
            for (j = 2; j <= k; j++)
            {
                eggFloor[i,j] = int.MaxValue;
                for (x = 1; x <= j; x++)
                {
                    res = 1 + max(eggFloor[i-1,x-1],
                                  eggFloor[i,j-x]);
                    if (res < eggFloor[i,j])
                        eggFloor[i,j] = res;
                }
            }
        }
          
        // eggFloor[n][k] holds the result
        return eggFloor[n,k];
  
    }
  
    // Driver function
    public static void Main()
    {

147
Chapter 11. DP-11 | Egg Dropping Puzzle

        int n = 2, k = 36;
        Console.WriteLine("Minimum number of trials "
           + "in worst case with " + n + " eggs and "
                 + k + "floors is " + eggDrop(n, k)); 
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// A Dynamic Programming based PHP 
// Program for the Egg Dropping Puzzle
  
/* Function to get minimum number
   of trials needed in worst
   case with n eggs and k floors */
function eggDrop($n, $k)
{
      
    /* A 2D table where entery eggFloor[i][j]
       will represent minimum number of 
       trials needed for i eggs and j floors. */
    $eggFloor = array(array());;
      
    // We need one trial for one 
    // floor and0 trials for 0 floors
    for ($i = 1; $i <=$n;$i++)
    {
        $eggFloor[$i][1] = 1;
        $eggFloor[$i][0] = 0;
    }
  
    // We always need j trials
    // for one egg and j floors.
    for ($j = 1; $j <= $k; $j++)
        $eggFloor[1][$j] = $j;
  
    // Fill rest of the entries in 
    // table using optimal substructure
    // property
    for ($i = 2; $i <= $n; $i++)
    {
        for ($j = 2; $j <= $k; $j++)
        {
            $eggFloor[$i][$j] = 999999;
            for ($x = 1; $x <= $j; $x++)

148
Chapter 11. DP-11 | Egg Dropping Puzzle

            {
                $res = 1 + max($eggFloor[$i - 1][$x - 1], 
                                 $eggFloor[$i][$j - $x]);
                if ($res < $eggFloor[$i][$j])
                    $eggFloor[$i][$j] = $res;
            }
        }
    }
  
    // eggFloor[n][k] holds the result
    return $eggFloor[$n][$k];
}
  
    // Driver Code
    $n = 2;
    $k = 36;
    echo "Minimum number of trials in worst case with " .$n. " eggs and "
                                    .$k. " floors is " .eggDrop($n, $k) ;
                                      
// This code is contributed by Sam007
?>

Output :

Minimum number of trials in worst case with 2 eggs and 36 floors is 8

Time Complexity: O(nk^2)


Auxiliary Space: O(nk)
As an exercise, you may try modifying the above DP solution to print all intermediate floors
(The floors used for minimum trial solution).
More Efficient Solution : Eggs dropping puzzle (Binomial Coefficient and Binary Search
Solution)
Egg Dropping Puzzle with 2 Eggs and K Floors
2 Eggs and 100 Floor Puzzle
References:
http://archive.ite.journal.informs.org/Vol4No1/Sniedovich/index.php
Improved By : Sam007

Source

https://www.geeksforgeeks.org/egg-dropping-puzzle-dp-11/

149
Chapter 12

DP-12 | Longest Palindromic


Subsequence

Longest Palindromic Subsequence | DP-12 - GeeksforGeeks


Given a sequence, find the length of the longest palindromic subsequence in it.

As another example, if the given sequence is “BBABCBCAB”, then the output should be 7
as “BABCBAB” is the longest palindromic subseuqnce in it. “BBBBB” and “BBCBB” are
also palindromic subsequences of the given sequence, but not the longest ones.
The naive solution for this problem is to generate all subsequences of the given sequence
and find the longest palindromic subsequence. This solution is exponential in term of time
complexity. Let us see how this problem possesses both important properties of a Dynamic
Programming (DP) Problem and can efficiently solved using Dynamic Programming.
1) Optimal Substructure:
Let X[0..n-1] be the input sequence of length n and L(0, n-1) be the length of the longest
palindromic subsequence of X[0..n-1].
If last and first characters of X are same, then L(0, n-1) = L(1, n-2) + 2.
Else L(0, n-1) = MAX (L(1, n-1), L(0, n-2)).
Following is a general recursive solution with all cases handled.

150
Chapter 12. DP-12 | Longest Palindromic Subsequence

// Every single character is a palindrome of length 1


L(i, i) = 1 for all indexes i in given sequence

// IF first and last characters are not same


If (X[i] != X[j]) L(i, j) = max{L(i + 1, j),L(i, j - 1)}

// If there are only 2 characters and both are same


Else if (j == i + 1) L(i, j) = 2

// If there are more than two characters, and first and last
// characters are same
Else L(i, j) = L(i + 1, j - 1) + 2

2) Overlapping Subproblems
Following is simple recursive implementation of the LPS problem. The implementation
simply follows the recursive structure mentioned above.

#include<stdio.h>
#include<string.h>
  
// A utility function to get max of two integers
int max (int x, int y) { return (x > y)? x : y; }
  
// Returns the length of the longest palindromic subsequence in seq
int lps(char *seq, int i, int j)
{
   // Base Case 1: If there is only 1 character
   if (i == j)
     return 1;
  
   // Base Case 2: If there are only 2 characters and both are same
   if (seq[i] == seq[j] && i + 1 == j)
     return 2;
  
   // If the first and last characters match
   if (seq[i] == seq[j])
      return lps (seq, i+1, j-1) + 2;
  
   // If the first and last characters do not match
   return max( lps(seq, i, j-1), lps(seq, i+1, j) );
}
  
/* Driver program to test above functions */
int main()
{
    char seq[] = "GEEKSFORGEEKS";
    int n = strlen(seq);
    printf ("The length of the LPS is %d", lps(seq, 0, n-1));

151
Chapter 12. DP-12 | Longest Palindromic Subsequence

    getchar();
    return 0;
}

Output:

The length of the LPS is 5

Considering the above implementation, following is a partial recursion tree for a sequence
of length 6 with all different characters.

L(0, 5)
/ \
/ \
L(1,5) L(0,4)
/ \ / \
/ \ / \
L(2,5) L(1,4) L(1,4) L(0,3)

In the above partial recursion tree, L(1, 4) is being solved twice. If we draw the complete
recursion tree, then we can see that there are many subproblems which are solved again and
again. Since same suproblems are called again, this problem has Overlapping Subprolems
property. So LPS problem has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, recomputations of same
subproblems can be avoided by constructing a temporary array L[][] in bottom up manner.
Dynamic Programming Solution

C++

// A Dynamic Programming based C++ program for LPS problem


// Returns the length of the longest palindromic subsequence in seq
#include<stdio.h>
#include<string.h>
  
// A utility function to get max of two integers
int max (int x, int y) { return (x > y)? x : y; }
  
// Returns the length of the longest palindromic subsequence in seq
int lps(char *str)
{
   int n = strlen(str);
   int i, j, cl;
   int L[n][n];  // Create a table to store results of subproblems

152
Chapter 12. DP-12 | Longest Palindromic Subsequence

  
  
   // Strings of length 1 are palindrome of lentgh 1
   for (i = 0; i < n; i++)
      L[i][i] = 1;
  
    // Build the table. Note that the lower diagonal values of table are
    // useless and not filled in the process. The values are filled in a
    // manner similar to Matrix Chain Multiplication DP solution (See
    // https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/). cl is length of
    // substring
    for (cl=2; cl<=n; cl++)
    {
        for (i=0; i<n-cl+1; i++)
        {
            j = i+cl-1;
            if (str[i] == str[j] && cl == 2)
               L[i][j] = 2;
            else if (str[i] == str[j])
               L[i][j] = L[i+1][j-1] + 2;
            else
               L[i][j] = max(L[i][j-1], L[i+1][j]);
        }
    }
  
    return L[0][n-1];
}
  
/* Driver program to test above functions */
int main()
{
    char seq[] = "GEEKS FOR GEEKS";
    int n = strlen(seq);
    printf ("The lnegth of the LPS is %d", lps(seq));
    getchar();
    return 0;
}

Java

//A Dynamic Programming based Python Program for the Egg Dropping Puzzle
class LPS
{
  
    // A utility function to get max of two integers
    static int max (int x, int y) { return (x > y)? x : y; }
       
    // Returns the length of the longest palindromic subsequence in seq

153
Chapter 12. DP-12 | Longest Palindromic Subsequence

    static int lps(String seq)


    {
       int n = seq.length();
       int i, j, cl;
       int L[][] = new int[n][n];  // Create a table to store results of subproblems
       
       // Strings of length 1 are palindrome of lentgh 1
       for (i = 0; i < n; i++)
           L[i][i] = 1;
               
        // Build the table. Note that the lower diagonal values of table are
        // useless and not filled in the process. The values are filled in a
        // manner similar to Matrix Chain Multiplication DP solution (See
        // https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/). cl is length of
        // substring
        for (cl=2; cl<=n; cl++)
        {
            for (i=0; i<n-cl+1; i++)
            {
                j = i+cl-1;
                if (seq.charAt(i) == seq.charAt(j) && cl == 2)
                   L[i][j] = 2;
                else if (seq.charAt(i) == seq.charAt(j))
                   L[i][j] = L[i+1][j-1] + 2;
                else
                   L[i][j] = max(L[i][j-1], L[i+1][j]);
            }
        }
               
        return L[0][n-1];
    }
           
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        String seq = "GEEKSFORGEEKS";
        int n = seq.length();
        System.out.println("The lnegth of the lps is "+ lps(seq));
    }
}
/* This code is contributed by Rajat Mishra */

Python

# A Dynamic Programming based Python program for LPS problem


# Returns the length of the longest palindromic subsequence in seq
def lps(str):
    n = len(str)

154
Chapter 12. DP-12 | Longest Palindromic Subsequence

  
    # Create a table to store results of subproblems
    L = [[0 for x in range(n)] for x in range(n)]
  
    # Strings of length 1 are palindrome of length 1
    for i in range(n):
        L[i][i] = 1
  
    # Build the table. Note that the lower diagonal values of table are
    # useless and not filled in the process. The values are filled in a
    # manner similar to Matrix Chain Multiplication DP solution (See
    # https://www.geeksforgeeks.org/dynamic-programming-set-8-matrix-chain-multiplication/
    # cl is length of substring
    for cl in range(2, n+1):
        for i in range(n-cl+1):
            j = i+cl-1
            if str[i] == str[j] and cl == 2:
                L[i][j] = 2
            elif str[i] == str[j]:
                L[i][j] = L[i+1][j-1] + 2
            else:
                L[i][j] = max(L[i][j-1], L[i+1][j]);
  
    return L[0][n-1]
  
# Driver program to test above functions
seq = "GEEKS FOR GEEKS"
n = len(seq)
print("The length of the LPS is " + str(lps(seq)))
  
# This code is contributed by Bhavya Jain

C#

// A Dynamic Programming based C# Program


// for the Egg Dropping Puzzle
using System;
  
class GFG {
  
    // A utility function to get max of
    // two integers
    static int max (int x, int y) 
    { 
        return (x > y)? x : y;
    }
      
    // Returns the length of the longest

155
Chapter 12. DP-12 | Longest Palindromic Subsequence

    // palindromic subsequence in seq


    static int lps(string seq)
    {
    int n = seq.Length;
    int i, j, cl;
      
    // Create a table to store results
    // of subproblems
    int [,]L = new int[n,n];
      
    // Strings of length 1 are 
    // palindrome of lentgh 1
    for (i = 0; i < n; i++)
        L[i,i] = 1;
              
        // Build the table. Note that the 
        // lower diagonal values of table
        // are useless and not filled in
        // the process. The values are 
        // filled in a manner similar to
        // Matrix Chain Multiplication DP
        // solution (See
        // https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/
        // cl is length of substring
        for (cl = 2; cl <= n; cl++)
        {
            for (i = 0; i < n-cl+1; i++)
            {
                j = i + cl - 1;
                  
                if (seq[i] == seq[j] &&
                                  cl == 2)
                    L[i,j] = 2;
                else if (seq[i] == seq[j])
                    L[i,j] = L[i+1,j-1] + 2;
                else
                    L[i,j] = 
                     max(L[i,j-1], L[i+1,j]);
            }
        }
              
        return L[0,n-1];
    }
          
    /* Driver program to test above 
    functions */
    public static void Main()
    {

156
Chapter 12. DP-12 | Longest Palindromic Subsequence

        string seq = "GEEKS FOR GEEKS";


        int n = seq.Length;
        Console.Write("The lnegth of the "
                  + "lps is "+ lps(seq));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// A Dynamic Programming based 
// PHP program for LPS problem
// Returns the length of the 
// longest palindromic 
// subsequence in seq
  
// A utility function to get
// max of two integers
// function max( $x, $y)
// { return ($x > $y)? $x : $y; }
  
// Returns the length of the
// longest palindromic 
// subsequence in seq
function lps($str)
{
$n = strlen($str);
$i; $j; $cl;
  
// Create a table to store
// results of subproblems
$L[][] = array(array()); 
  
  
// Strings of length 1 are
// palindrome of lentgh 1
for ($i = 0; $i < $n; $i++)
    $L[$i][$i] = 1;
  
    // Build the table. Note that 
    // the lower diagonal values 
    // of table are useless and 
    // not filled in the process. 
    // The values are filled in a 
    // manner similar to Matrix 
    // Chain Multiplication DP 

157
Chapter 12. DP-12 | Longest Palindromic Subsequence

    // solution (See 


    // https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/).
    // cl is length of substring
    for ($cl = 2; $cl <= $n; $cl++)
    {
        for ($i = 0; $i < $n - $cl + 1; $i++)
        {
            $j = $i + $cl - 1;
            if ($str[$i] == $str[$j] && 
                            $cl == 2)
            $L[$i][$j] = 2;
            else if ($str[$i] == $str[$j])
            $L[$i][$j] = $L[$i + 1][$j - 1] + 2;
            else
            $L[$i][$j] = max($L[$i][$j - 1], 
                             $L[$i + 1][$j]);
        }
    }
  
    return $L[0][$n - 1];
}
  
// Driver Code
$seq = 'GEEKS FOR GEEKS';
$n = strlen($seq);
echo "The lnegth of the " . 
      "LPS is ", lps($seq);
  
// This code is contributed
// by shiv_bhakt.
?>

Output:

The lnegth of the LPS is 7

Time Complexity of the above implementation is O(n^2) which is much better than the
worst case time complexity of Naive Recursive implementation.
This problem is close to the Longest Common Subsequence (LCS) problem. In fact, we can
use LCS as a subroutine to solve this problem. Following is the two step solution that uses
LCS.
1) Reverse the given sequence and store the reverse in another array say rev[0..n-1]
2) LCS of the given sequence and rev[] will be the longest palindromic sequence.
This solution is also a O(n^2) solution.

Print Longest Palindromic Subsequence


Longest palindrome subsequence with O(n) space

158
Chapter 12. DP-12 | Longest Palindromic Subsequence

References:
http://users.eecs.northwestern.edu/~dda902/336/hw6-sol.pdf
Improved By : nitin mittal, shiv_bhakt

Source

https://www.geeksforgeeks.org/longest-palindromic-subsequence-dp-12/

159
Chapter 13

DP-13 | Cutting a Rod

Cutting a Rod | DP-13 - GeeksforGeeks


Given a rod of length n inches and an array of prices that contains prices of all pieces of
size smaller than n. Determine the maximum value obtainable by cutting up the rod and
selling the pieces. For example, if length of the rod is 8 and the values of different pieces
are given as following, then the maximum obtainable value is 22 (by cutting in two pieces
of lengths 2 and 6)

length | 1 2 3 4 5 6 7 8
--------------------------------------------
price | 1 5 8 9 10 17 17 20

And if the prices are as following, then the maximum obtainable value is 24 (by cutting in
eight pieces of length 1)

length | 1 2 3 4 5 6 7 8
--------------------------------------------
price | 3 5 8 9 10 17 17 20

A naive solution for this problem is to generate all configurations of different pieces and find
the highest priced configuration. This solution is exponential in term of time complexity.
Let us see how this problem possesses both important properties of a Dynamic Programming
(DP) Problem and can efficiently solved using Dynamic Programming.
1) Optimal Substructure:
We can get the best price by making a cut at different positions and comparing the values
obtained after a cut. We can recursively call the same function for a piece obtained after a
cut.

160
Chapter 13. DP-13 | Cutting a Rod

Let cutRod(n) be the required (best possible price) value for a rod of length n. cutRod(n)
can be written as following.
cutRod(n) = max(price[i] + cutRod(n-i-1)) for all i in {0, 1 .. n-1}
2) Overlapping Subproblems
Following is simple recursive implementation of the Rod Cutting problem. The implemen-
tation simply follows the recursive structure mentioned above.

C++

// A Naive recursive solution for Rod cutting problem


#include<stdio.h>
#include<limits.h>
  
// A utility function to get the maximum of two integers
int max(int a, int b) { return (a > b)? a : b;}
  
/* Returns the best obtainable price for a rod of length n and
   price[] as prices of different pieces */
int cutRod(int price[], int n)
{
   if (n <= 0)
     return 0;
   int max_val = INT_MIN;
  
   // Recursively cut the rod in different pieces and compare different 
   // configurations
   for (int i = 0; i<n; i++)
         max_val = max(max_val, price[i] + cutRod(price, n-i-1));
  
   return max_val;
}
  
/* Driver program to test above functions */
int main()
{
    int arr[] = {1, 5, 8, 9, 10, 17, 17, 20};
    int size = sizeof(arr)/sizeof(arr[0]);
    printf("Maximum Obtainable Value is %dn", cutRod(arr, size));
    getchar();
    return 0;
}

Java

// // A Naive recursive solution for Rod cutting problem


class RodCutting

161
Chapter 13. DP-13 | Cutting a Rod

{
    /* Returns the best obtainable price for a rod of length
       n and price[] as prices of different pieces */
    static int cutRod(int price[], int n)
    {
        if (n <= 0)
            return 0;
        int max_val = Integer.MIN_VALUE;
  
        // Recursively cut the rod in different pieces and
        // compare different configurations
        for (int i = 0; i<n; i++)
            max_val = Math.max(max_val,
                              price[i] + cutRod(price, n-i-1));
  
        return max_val;
    }
  
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        int arr[] = new int[] {1, 5, 8, 9, 10, 17, 17, 20};
        int size = arr.length;
        System.out.println("Maximum Obtainable Value is "+
                            cutRod(arr, size));
  
    }
}
/* This code is contributed by Rajat Mishra */

Python

# A Naive recursive solution 


# for Rod cutting problem
import sys
  
# A utility function to get the
# maximum of two integers
def max(a, b):
    return a if (a > b) else b
      
# Returns the best obtainable price for a rod of length n 
# and price[] as prices of different pieces
def cutRod(price, n):
    if(n <= 0):
        return 0
    max_val = -sys.maxsize-1
      

162
Chapter 13. DP-13 | Cutting a Rod

    # Recursively cut the rod in different pieces  


    # and compare different configurations
    for i in range(0, n):
        max_val = max(max_val, price[i] + 
                      cutRod(price, n - i - 1))
    return max_val
  
# Driver code
arr = [1, 5, 8, 9, 10, 17, 17, 20]
size = len(arr)
print("Maximum Obtainable Value is", cutRod(arr, size))
  
# This code is contributed by 'Smitha Dinesh Semwal'

C#

// A Naive recursive solution for


// Rod cutting problem
using System;
class GFG {
      
    /* Returns the best obtainable 
       price for a rod of length
       n and price[] as prices of 
       different pieces */
    static int cutRod(int []price, int n)
    {
        if (n <= 0)
            return 0;
        int max_val = int.MinValue;
  
        // Recursively cut the rod in
        // different pieces and compare
        // different configurations
        for (int i = 0; i < n; i++)
            max_val = Math.Max(max_val, price[i] + 
                        cutRod(price, n - i - 1));
  
        return max_val;
    }
  
    // Driver Code
    public static void Main()
    {
        int []arr = new int[] {1, 5, 8, 9, 10, 17, 17, 20};
        int size = arr.Length;
        Console.WriteLine("Maximum Obtainable Value is "+
                                        cutRod(arr, size));

163
Chapter 13. DP-13 | Cutting a Rod

    }
}
  
// This code is contributed by Sam007

PHP

<?php
// A Naive recursive solution for 
// Rod cutting problem
  
/* Returns the best obtainable
   price for a rod of length n and 
   price[] as prices of different 
   pieces */
function cutRod( $price, $n)
{
  
    if ($n <= 0)
        return 0;
    $max_val = PHP_INT_MIN;
      
    // Recursively cut the rod in different
    // pieces and compare different 
    // configurations
    for ($i = 0; $i < $n; $i++)
            $max_val = max($max_val, $price[$i] + 
                    cutRod($price, $n - $i - 1));
      
    return $max_val;
}
  
    // Driver Code
    $arr = array(1, 5, 8, 9, 10, 17, 17, 20);
    $size =count($arr);
    echo "Maximum Obtainable Value is "
               , cutRod($arr, $size);
  
// This code is contributed anuj_67.
?>

Output:

Maximum Obtainable Value is 22

Considering the above implementation, following is recursion tree for a Rod of length 4.

164
Chapter 13. DP-13 | Cutting a Rod

cR() ---> cutRod()

cR(4)
/ /
/ /
cR(3) cR(2) cR(1) cR(0)
/ | / |
/ | / |
cR(2) cR(1) cR(0) cR(1) cR(0) cR(0)
/ | |
/ | |
cR(1) cR(0) cR(0) cR(0)
/
/
CR(0)

In the above partial recursion tree, cR(2) is being solved twice. We can see that there are
many subproblems which are solved again and again. Since same suproblems are called
again, this problem has Overlapping Subprolems property. So the Rod Cutting problem has
both properties (see thisand this) of a dynamic programming problem. Like other typical
Dynamic Programming(DP) problems, recomputations of same subproblems can be avoided
by constructing a temporary array val[] in bottom up manner.
C++

// A Dynamic Programming solution for Rod cutting problem


#include<stdio.h>
#include<limits.h>
  
// A utility function to get the maximum of two integers
int max(int a, int b) { return (a > b)? a : b;}
  
/* Returns the best obtainable price for a rod of length n and
   price[] as prices of different pieces */
int cutRod(int price[], int n)
{
   int val[n+1];
   val[0] = 0;
   int i, j;
  
   // Build the table val[] in bottom up manner and return the last entry
   // from the table
   for (i = 1; i<=n; i++)
   {
       int max_val = INT_MIN;
       for (j = 0; j < i; j++)
         max_val = max(max_val, price[j] + val[i-j-1]);

165
Chapter 13. DP-13 | Cutting a Rod

       val[i] = max_val;
   }
  
   return val[n];
}
  
/* Driver program to test above functions */
int main()
{
    int arr[] = {1, 5, 8, 9, 10, 17, 17, 20};
    int size = sizeof(arr)/sizeof(arr[0]);
    printf("Maximum Obtainable Value is %dn", cutRod(arr, size));
    getchar();
    return 0;
}

Java

// A Dynamic Programming solution for Rod cutting problem


class RodCutting
{
    /* Returns the best obtainable price for a rod of
       length n and price[] as prices of different pieces */
    static int cutRod(int price[],int n)
    {
        int val[] = new int[n+1];
        val[0] = 0;
  
        // Build the table val[] in bottom up manner and return
        // the last entry from the table
        for (int i = 1; i<=n; i++)
        {
            int max_val = Integer.MIN_VALUE;
            for (int j = 0; j < i; j++)
                max_val = Math.max(max_val, 
                                   price[j] + val[i-j-1]);
            val[i] = max_val;
        }
  
        return val[n];
    }
  
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        int arr[] = new int[] {1, 5, 8, 9, 10, 17, 17, 20};
        int size = arr.length;
        System.out.println("Maximum Obtainable Value is " +

166
Chapter 13. DP-13 | Cutting a Rod

                            cutRod(arr, size));
    }
}
/* This code is contributed by Rajat Mishra */

Python

# A Dynamic Programming solution for Rod cutting problem


INT_MIN = -32767
  
# Returns the best obtainable price for a rod of length n and
# price[] as prices of different pieces
def cutRod(price, n):
    val = [0 for x in range(n+1)]
    val[0] = 0
  
    # Build the table val[] in bottom up manner and return
    # the last entry from the table
    for i in range(1, n+1):
        max_val = INT_MIN
        for j in range(i):
             max_val = max(max_val, price[j] + val[i-j-1])
        val[i] = max_val
  
    return val[n]
  
# Driver program to test above functions
arr = [1, 5, 8, 9, 10, 17, 17, 20]
size = len(arr)
print("Maximum Obtainable Value is " + str(cutRod(arr, size)))
  
# This code is contributed by Bhavya Jain

C#

// A Dynamic Programming solution 


// for Rod cutting problem
using System;
class GFG {
  
    /* Returns the best obtainable 
       price for a rod of length n
       and price[] as prices of 
       different pieces */
    static int cutRod(int []price,int n)
    {
        int []val = new int[n + 1];

167
Chapter 13. DP-13 | Cutting a Rod

        val[0] = 0;
  
        // Build the table val[] in
        // bottom up manner and return
        // the last entry from the table
        for (int i = 1; i<=n; i++)
        {
            int max_val = int.MinValue;
            for (int j = 0; j < i; j++)
                max_val = Math.Max(max_val, 
                          price[j] + val[i - j - 1]);
            val[i] = max_val;
        }
  
        return val[n];
    }
      
    // Driver Code
    public static void Main()
    {
        int []arr = new int[] {1, 5, 8, 9, 10, 17, 17, 20};
        int size = arr.Length;
        Console.WriteLine("Maximum Obtainable Value is " +
                                        cutRod(arr, size));
          
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// A Dynamic Programming solution for
// Rod cutting problem
  
/* Returns the best obtainable price 
for a rod of length n and price[] as
prices of different pieces */
function cutRod( $price, $n)
{
    $val = array();
    $val[0] = 0;
    $i; $j;
      
    // Build the table val[] in bottom 
    // up manner and return the last
    // entry from the table

168
Chapter 13. DP-13 | Cutting a Rod

    for ($i = 1; $i <= $n; $i++)


    {
        $max_val = PHP_INT_MIN;
          
        for ($j = 0; $j < $i; $j++)
            $max_val = max($max_val, 
             $price[$j] + $val[$i-$j-1]);
        $val[$i] = $max_val;
    }
      
    return $val[$n];
}
  
// Driver program to test above functions
$arr = array(1, 5, 8, 9, 10, 17, 17, 20);
$size = count($arr);
echo "Maximum Obtainable Value is ", 
                      cutRod($arr, $size);
      
// This code is contributed by anuj_67.
?>

Output:

Maximum Obtainable Value is 22

Time Complexity of the above implementation is O(n^2) which is much better than the
worst-case time complexity of Naive Recursive implementation.
Improved By : Sam007, vt_m, aniketmaurya

Source

https://www.geeksforgeeks.org/cutting-a-rod-dp-13/

169
Chapter 14

DP-14 | Maximum Sum


Increasing Subsequence

Maximum Sum Increasing Subsequence | DP-14 - GeeksforGeeks


Given an array of n positive integers. Write a program to find the sum of maximum sum
subsequence of the given array such that the intgers in the subsequence are sorted in in-
creasing order. For example, if input is {1, 101, 2, 3, 100, 4, 5}, then output should be 106
(1 + 2 + 3 + 100), if the input array is {3, 4, 5, 10}, then output should be 22 (3 + 4 + 5
+ 10) and if the input array is {10, 5, 4, 3}, then output should be 10

Solution
This problem is a variation of standard Longest Increasing Subsequence (LIS) problem. We
need a slight change in the Dynamic Programming solution of LIS problem. All we need to
change is to use sum as a criteria instead of length of increasing subsequence.
Following are the Dynamic Programming solution to the problem :
C/C++

/* Dynamic Programming implementation 


of Maximum Sum Increasing Subsequence 
(MSIS) problem */
#include<stdio.h>
  
/* maxSumIS() returns the maximum 
   sum of increasing subsequence
   in arr[] of size n */
int maxSumIS(int arr[], int n)
{
    int i, j, max = 0;
    int msis[n];
  

170
Chapter 14. DP-14 | Maximum Sum Increasing Subsequence

    /* Initialize msis values


       for all indexes */
    for ( i = 0; i < n; i++ )
        msis[i] = arr[i];
  
    /* Compute maximum sum values 
       in bottom up manner */
    for ( i = 1; i < n; i++ )
        for ( j = 0; j < i; j++ )
            if (arr[i] > arr[j] && 
                msis[i] < msis[j] + arr[i])
                msis[i] = msis[j] + arr[i];
  
    /* Pick maximum of
       all msis values */
    for ( i = 0; i < n; i++ )
        if ( max < msis[i] )
            max = msis[i];
  
    return max;
}
  
// Driver Code
int main()
{
    int arr[] = {1, 101, 2, 3, 100, 4, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Sum of maximum sum increasing " 
            "subsequence is %d\n",
              maxSumIS( arr, n ) );
    return 0;
}

Java

/* Dynamic Programming Java 


   implementation of Maximum Sum
   Increasing Subsequence (MSIS)
   problem */
class GFG
{
    /* maxSumIS() returns the 
    maximum sum of increasing
    subsequence in arr[] of size n */
    static int maxSumIS(int arr[], int n)
    {
        int i, j, max = 0;
        int msis[] = new int[n];

171
Chapter 14. DP-14 | Maximum Sum Increasing Subsequence

  
        /* Initialize msis values 
           for all indexes */
        for (i = 0; i < n; i++)
            msis[i] = arr[i];
  
        /* Compute maximum sum values
           in bottom up manner */
        for (i = 1; i < n; i++)
            for (j = 0; j < i; j++)
                if (arr[i] > arr[j] &&
                    msis[i] < msis[j] + arr[i])
                    msis[i] = msis[j] + arr[i];
  
        /* Pick maximum of all
           msis values */
        for (i = 0; i < n; i++)
            if (max < msis[i])
                max = msis[i];
  
        return max;
    }
  
    // Driver code
    public static void main(String args[])
    {
        int arr[] = new int[]{1, 101, 2, 3, 100, 4, 5};
        int n = arr.length;
        System.out.println("Sum of maximum sum "+
                            "increasing subsequence is "+
                              maxSumIS(arr, n));
    }
}
  
// This code is contributed 
// by Rajat Mishra 

Python

# Dynamic Programming bsed Python 


# implementation of Maximum Sum 
# Increasing Subsequence (MSIS)
# problem
  
# maxSumIS() returns the maximum 
# sum of increasing subsequence 
# in arr[] of size n
def maxSumIS(arr, n):

172
Chapter 14. DP-14 | Maximum Sum Increasing Subsequence

    max = 0
    msis = [0 for x in range(n)]
  
    # Initialize msis values
    # for all indexes
    for i in range(n):
        msis[i] = arr[i]
  
    # Compute maximum sum 
    # values in bottom up manner
    for i in range(1, n):
        for j in range(i):
            if (arr[i] > arr[j] and
                msis[i] < msis[j] + arr[i]):
                msis[i] = msis[j] + arr[i]
  
    # Pick maximum of
    # all msis values
    for i in range(n):
        if max < msis[i]:
            max = msis[i]
  
    return max
  
# Driver Code
arr = [1, 101, 2, 3, 100, 4, 5]
n = len(arr)
print("Sum of maximum sum increasing " + 
                     "subsequence is " +
                  str(maxSumIS(arr, n)))
  
# This code is contributed 
# by Bhavya Jain

C#

// Dynamic Programming C# implementation


// of Maximum Sum Increasing Subsequence
// (MSIS) problem 
using System;
class GFG {
      
    // maxSumIS() returns the 
    // maximum sum of increasing
    // subsequence in arr[] of size n 
    static int maxSumIS( int []arr, int n )
    {
        int i, j, max = 0;

173
Chapter 14. DP-14 | Maximum Sum Increasing Subsequence

        int []msis = new int[n];


  
        /* Initialize msis values
           for all indexes */
        for ( i = 0; i < n; i++ )
            msis[i] = arr[i];
  
        /* Compute maximum sum values
           in bottom up manner */
        for ( i = 1; i < n; i++ )
            for ( j = 0; j < i; j++ )
                if ( arr[i] > arr[j] &&
                    msis[i] < msis[j] + arr[i])
                    msis[i] = msis[j] + arr[i];
  
        /* Pick maximum of all 
           msis values */
        for ( i = 0; i < n; i++ )
            if ( max < msis[i] )
                max = msis[i];
  
        return max;
    }
      
    // Driver Code
    public static void Main()
    {
        int []arr = new int[]{1, 101, 2, 3, 100, 4, 5};
        int n = arr.Length;
        Console.WriteLine("Sum of maximum sum increasing "+
                                        " subsequence is "+
        maxSumIS(arr, n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// Dynamic Programming implementation
// of Maximum Sum Increasing
// Subsequence (MSIS) problem 
  
// maxSumIS() returns the maximum 
// sum of increasing subsequence
// in arr[] of size n 
function maxSumIS($arr, $n)

174
Chapter 14. DP-14 | Maximum Sum Increasing Subsequence

{
    $max = 0;
    $msis= array($n);
  
    // Initialize msis values
    // for all indexes 
    for($i = 0; $i < $n; $i++ )
        $msis[$i] = $arr[$i];
  
    // Compute maximum sum values
    // in bottom up manner 
    for($i = 1; $i < $n; $i++)
        for($j = 0; $j < $i; $j++)
            if ($arr[$i] > $arr[$j] && 
                $msis[$i] < $msis[$j] + $arr[$i])
                $msis[$i] = $msis[$j] + $arr[$i];
  
    // Pick maximum of all msis values
    for($i = 0;$i < $n; $i++ )
        if ($max < $msis[$i] )
            $max = $msis[$i];
  
    return $max;
}
  
    // Driver Code
    $arr = array(1, 101, 2, 3, 100, 4, 5);
    $n = count($arr);
    echo "Sum of maximum sum increasing subsequence is " 
                                   .maxSumIS( $arr, $n );
          
// This code is contributed by Sam007
?>

Output :

Sum of maximum sum increasing subsequence is 106

Time Complexity: O(n^2)

Improved By : Sam007, ParulShandilya

175
Chapter 14. DP-14 | Maximum Sum Increasing Subsequence

Source

https://www.geeksforgeeks.org/maximum-sum-increasing-subsequence-dp-14/

176
Chapter 15

DP-15 | Longest Bitonic


Subsequence

Longest Bitonic Subsequence | DP-15 - GeeksforGeeks


Given an array arr[0 … n-1] containing n positive integers, a subsequenceof arr[] is called
Bitonic if it is first increasing, then decreasing. Write a function that takes an array as
argument and returns the length of the longest bitonic subsequence.
A sequence, sorted in increasing order is considered Bitonic with the decreasing part as
empty. Similarly, decreasing order sequence is considered Bitonic with the increasing part
as empty.
Examples:

Input arr[] = {1, 11, 2, 10, 4, 5, 2, 1};


Output: 6 (A Longest Bitonic Subsequence of length 6 is 1, 2, 10, 4, 2, 1)

Input arr[] = {12, 11, 40, 5, 3, 1}


Output: 5 (A Longest Bitonic Subsequence of length 5 is 12, 11, 5, 3, 1)

Input arr[] = {80, 60, 30, 40, 20, 10}


Output: 5 (A Longest Bitonic Subsequence of length 5 is 80, 60, 30, 20, 10)

Source: Microsoft Interview Question


Solution
This problem is a variation of standard Longest Increasing Subsequence (LIS) problem.
Let the input array be arr[] of length n. We need to construct two arrays lis[] and lds[]
using Dynamic Programming solution of LIS problem. lis[i] stores the length of the Longest
Increasing subsequence ending with arr[i]. lds[i] stores the length of the longest Decreasing
subsequence starting from arr[i]. Finally, we need to return the max value of lis[i] + lds[i] –
1 where i is from 0 to n-1.

177
Chapter 15. DP-15 | Longest Bitonic Subsequence

Following is C++ implementation of the above Dynamic Programming solution.

C++

/* Dynamic Programming implementation of longest bitonic subsequence problem */


#include<stdio.h>
#include<stdlib.h>
  
/* lbs() returns the length of the Longest Bitonic Subsequence in
    arr[] of size n. The function mainly creates two temporary arrays
    lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.
  
    lis[i] ==> Longest Increasing subsequence ending with arr[i]
    lds[i] ==> Longest decreasing subsequence starting with arr[i]
*/
int lbs( int arr[], int n )
{
   int i, j;
  
   /* Allocate memory for LIS[] and initialize LIS values as 1 for
      all indexes */
   int *lis = new int[n];
   for (i = 0; i < n; i++)
      lis[i] = 1;
  
   /* Compute LIS values from left to right */
   for (i = 1; i < n; i++)
      for (j = 0; j < i; j++)
         if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
            lis[i] = lis[j] + 1;
  
   /* Allocate memory for lds and initialize LDS values for
      all indexes */
   int *lds = new int [n];
   for (i = 0; i < n; i++)
      lds[i] = 1;
  
   /* Compute LDS values from right to left */
   for (i = n-2; i >= 0; i--)
      for (j = n-1; j > i; j--)
         if (arr[i] > arr[j] && lds[i] < lds[j] + 1)
            lds[i] = lds[j] + 1;
  
  
   /* Return the maximum value of lis[i] + lds[i] - 1*/
   int max = lis[0] + lds[0] - 1;
   for (i = 1; i < n; i++)
     if (lis[i] + lds[i] - 1 > max)

178
Chapter 15. DP-15 | Longest Bitonic Subsequence

         max = lis[i] + lds[i] - 1;


   return max;
}
  
/* Driver program to test above function */
int main()
{
  int arr[] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5,
              13, 3, 11, 7, 15};
  int n = sizeof(arr)/sizeof(arr[0]);
  printf("Length of LBS is %d\n", lbs( arr, n ) );
  return 0;
}

Java

/* Dynamic Programming implementation in Java for longest bitonic


   subsequence problem */
import java.util.*;
import java.lang.*;
import java.io.*;
  
class LBS
{
    /* lbs() returns the length of the Longest Bitonic Subsequence in
    arr[] of size n. The function mainly creates two temporary arrays
    lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.
  
    lis[i] ==> Longest Increasing subsequence ending with arr[i]
    lds[i] ==> Longest decreasing subsequence starting with arr[i]
    */
    static int lbs( int arr[], int n )
    {
        int i, j;
  
        /* Allocate memory for LIS[] and initialize LIS values as 1 for
            all indexes */
        int[] lis = new int[n];
        for (i = 0; i < n; i++)
            lis[i] = 1;
  
        /* Compute LIS values from left to right */
        for (i = 1; i < n; i++)
            for (j = 0; j < i; j++)
                if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
                    lis[i] = lis[j] + 1;
  
        /* Allocate memory for lds and initialize LDS values for

179
Chapter 15. DP-15 | Longest Bitonic Subsequence

            all indexes */
        int[] lds = new int [n];
        for (i = 0; i < n; i++)
            lds[i] = 1;
  
        /* Compute LDS values from right to left */
        for (i = n-2; i >= 0; i--)
            for (j = n-1; j > i; j--)
                if (arr[i] > arr[j] && lds[i] < lds[j] + 1)
                    lds[i] = lds[j] + 1;
  
  
        /* Return the maximum value of lis[i] + lds[i] - 1*/
        int max = lis[0] + lds[0] - 1;
        for (i = 1; i < n; i++)
            if (lis[i] + lds[i] - 1 > max)
                max = lis[i] + lds[i] - 1;
  
        return max;
    }
  
    public static void main (String[] args)
    {
        int arr[] = {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5,
                    13, 3, 11, 7, 15};
        int n = arr.length;
        System.out.println("Length of LBS is "+ lbs( arr, n ));
    }
}

Python

# Dynamic Programming implementation of longest bitonic subsequence problem


"""
lbs() returns the length of the Longest Bitonic Subsequence in
arr[] of size n. The function mainly creates two temporary arrays
lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.
  
lis[i] ==> Longest Increasing subsequence ending with arr[i]
lds[i] ==> Longest decreasing subsequence starting with arr[i]
"""
  
def lbs(arr):
    n = len(arr)
  
  
    # allocate memory for LIS[] and initialize LIS values as 1
    # for all indexes

180
Chapter 15. DP-15 | Longest Bitonic Subsequence

    lis = [1 for i in range(n+1)]


  
    # Compute LIS values from left to right
    for i in range(1 , n):
        for j in range(0 , i):
            if ((arr[i] > arr[j]) and (lis[i] < lis[j] +1)):
                lis[i] = lis[j] + 1
  
    # allocate memory for LDS and initialize LDS values for
    # all indexes
    lds = [1 for i in range(n+1)]
      
    # Compute LDS values from right to left
    for i in reversed(range(n-1)): #loop from n-2 downto 0
        for j in reversed(range(i-1 ,n)): #loop from n-1 downto i-1
            if(arr[i] > arr[j] and lds[i] < lds[j] + 1):
                lds[i] = lds[j] + 1 
  
  
    # Return the maximum value of (lis[i] + lds[i] - 1)
    maximum = lis[0] + lds[0] - 1
    for i in range(1 , n):
        maximum = max((lis[i] + lds[i]-1), maximum)
      
    return maximum
  
# Driver program to test the above function
arr =  [0 , 8 , 4, 12, 2, 10 , 6 , 14 , 1 , 9 , 5 , 13,
        3, 11 , 7 , 15]
print "Length of LBS is",lbs(arr)
  
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

C#

/* Dynamic Programming implementation in 


   C# for longest bitonic subsequence problem */
using System;
  
class LBS {
      
    /* lbs() returns the length of the Longest Bitonic Subsequence in
    arr[] of size n. The function mainly creates two temporary arrays
    lis[] and lds[] and returns the maximum lis[i] + lds[i] - 1.
  
    lis[i] ==> Longest Increasing subsequence ending with arr[i]
    lds[i] ==> Longest decreasing subsequence starting with arr[i]
    */

181
Chapter 15. DP-15 | Longest Bitonic Subsequence

    static int lbs(int[] arr, int n)


    {
        int i, j;
  
        /* Allocate memory for LIS[] and initialize 
           LIS values as 1 for all indexes */
        int[] lis = new int[n];
        for (i = 0; i < n; i++)
            lis[i] = 1;
  
        /* Compute LIS values from left to right */
        for (i = 1; i < n; i++)
            for (j = 0; j < i; j++)
                if (arr[i] > arr[j] && lis[i] < lis[j] + 1)
                    lis[i] = lis[j] + 1;
  
        /* Allocate memory for lds and initialize LDS values for
            all indexes */
        int[] lds = new int[n];
        for (i = 0; i < n; i++)
            lds[i] = 1;
  
        /* Compute LDS values from right to left */
        for (i = n - 2; i >= 0; i--)
            for (j = n - 1; j > i; j--)
                if (arr[i] > arr[j] && lds[i] < lds[j] + 1)
                    lds[i] = lds[j] + 1;
  
        /* Return the maximum value of lis[i] + lds[i] - 1*/
        int max = lis[0] + lds[0] - 1;
        for (i = 1; i < n; i++)
            if (lis[i] + lds[i] - 1 > max)
                max = lis[i] + lds[i] - 1;
  
        return max;
    }
      
    // Driver code
    public static void Main()
    {
        int[] arr = { 0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5,
                                      13, 3, 11, 7, 15 };
        int n = arr.Length;
        Console.WriteLine("Length of LBS is " + lbs(arr, n));
    }
}
  
// This code is contributed by vt_m.

182
Chapter 15. DP-15 | Longest Bitonic Subsequence

Output:

Length of LBS is 7

Time Complexity: O(n^2)


Auxiliary Space: O(n)

Source

https://www.geeksforgeeks.org/longest-bitonic-subsequence-dp-15/

183
Chapter 16

DP-16 | Floyd Warshall


Algorithm

Floyd Warshall Algorithm | DP-16 - GeeksforGeeks


The Floyd Warshall Algorithm is for solving the All Pairs Shortest Path problem. The
problem is to find shortest distances between every pair of vertices in a given edge weighted
directed Graph.
Example:

Input:
graph[][] = { {0, 5, INF, 10},
{INF, 0, 3, INF},
{INF, INF, 0, 1},
{INF, INF, INF, 0} }
which represents the following graph
10
(0)------->(3)
| /|\
5 | |
| | 1
\|/ |
(1)------->(2)
3
Note that the value of graph[i][j] is 0 if i is equal to j
And graph[i][j] is INF (infinite) if there is no edge from vertex i to j.

Output:
Shortest distance matrix
0 5 8 9
INF 0 3 4

184
Chapter 16. DP-16 | Floyd Warshall Algorithm

INF INF 0 1
INF INF INF 0

Floyd Warshall Algorithm


We initialize the solution matrix same as the input graph matrix as a first step. Then we
update the solution matrix by considering all vertices as an intermediate vertex. The idea
is to one by one pick all vertices and updates all shortest paths which include the picked
vertex as an intermediate vertex in the shortest path. When we pick vertex number k as
an intermediate vertex, we already have considered vertices {0, 1, 2, .. k-1} as intermediate
vertices. For every pair (i, j) of the source and destination vertices respectively, there are
two possible cases.
1) k is not an intermediate vertex in shortest path from i to j. We keep the value of dist[i][j]
as it is.
2) k is an intermediate vertex in shortest path from i to j. We update the value of dist[i][j]
as dist[i][k] + dist[k][j].
The following figure shows the above optimal substructure property in the all-pairs shortest
path problem.

Following is implementations of the Floyd Warshall algorithm.

C/C++

// C Program for Floyd Warshall Algorithm


#include<stdio.h>
  
// Number of vertices in the graph
#define V 4
  
/* Define Infinite as a large enough value. This value will be used
  for vertices not connected to each other */
#define INF 99999
  
// A function to print the solution matrix
void printSolution(int dist[][V]);
  
// Solves the all-pairs shortest path problem using Floyd Warshall algorithm
void floydWarshall (int graph[][V])
{
    /* dist[][] will be the output matrix that will finally have the shortest 
      distances between every pair of vertices */
    int dist[V][V], i, j, k;

185
Chapter 16. DP-16 | Floyd Warshall Algorithm

  
    /* Initialize the solution matrix same as input graph matrix. Or 
       we can say the initial values of shortest distances are based
       on shortest paths considering no intermediate vertex. */
    for (i = 0; i < V; i++)
        for (j = 0; j < V; j++)
            dist[i][j] = graph[i][j];
  
    /* Add all vertices one by one to the set of intermediate vertices.
      ---> Before start of an iteration, we have shortest distances between all
      pairs of vertices such that the shortest distances consider only the
      vertices in set {0, 1, 2, .. k-1} as intermediate vertices.
      ----> After the end of an iteration, vertex no. k is added to the set of
      intermediate vertices and the set becomes {0, 1, 2, .. k} */
    for (k = 0; k < V; k++)
    {
        // Pick all vertices as source one by one
        for (i = 0; i < V; i++)
        {
            // Pick all vertices as destination for the
            // above picked source
            for (j = 0; j < V; j++)
            {
                // If vertex k is on the shortest path from
                // i to j, then update the value of dist[i][j]
                if (dist[i][k] + dist[k][j] < dist[i][j])
                    dist[i][j] = dist[i][k] + dist[k][j];
            }
        }
    }
  
    // Print the shortest distance matrix
    printSolution(dist);
}
  
/* A utility function to print solution */
void printSolution(int dist[][V])
{
    printf ("The following matrix shows the shortest distances"
            " between every pair of vertices \n");
    for (int i = 0; i < V; i++)
    {
        for (int j = 0; j < V; j++)
        {
            if (dist[i][j] == INF)
                printf("%7s", "INF");
            else
                printf ("%7d", dist[i][j]);

186
Chapter 16. DP-16 | Floyd Warshall Algorithm

        }
        printf("\n");
    }
}
  
// driver program to test above function
int main()
{
    /* Let us create the following weighted graph
            10
       (0)------->(3)
        |         /|\
      5 |          |
        |          | 1
       \|/         |
       (1)------->(2)
            3           */
    int graph[V][V] = { {0,   5,  INF, 10},
                        {INF, 0,   3, INF},
                        {INF, INF, 0,   1},
                        {INF, INF, INF, 0}
                      };
  
    // Print the solution
    floydWarshall(graph);
    return 0;
}

Java

// A Java program for Floyd Warshall All Pairs Shortest


// Path algorithm.
import java.util.*;
import java.lang.*;
import java.io.*;
  
  
class AllPairShortestPath
{
    final static int INF = 99999, V = 4;
  
    void floydWarshall(int graph[][])
    {
        int dist[][] = new int[V][V];
        int i, j, k;
  
        /* Initialize the solution matrix same as input graph matrix.
           Or we can say the initial values of shortest distances

187
Chapter 16. DP-16 | Floyd Warshall Algorithm

           are based on shortest paths considering no intermediate


           vertex. */
        for (i = 0; i < V; i++)
            for (j = 0; j < V; j++)
                dist[i][j] = graph[i][j];
  
        /* Add all vertices one by one to the set of intermediate
           vertices.
          ---> Before start of an iteration, we have shortest
               distances between all pairs of vertices such that
               the shortest distances consider only the vertices in
               set {0, 1, 2, .. k-1} as intermediate vertices.
          ----> After the end of an iteration, vertex no. k is added
                to the set of intermediate vertices and the set
                becomes {0, 1, 2, .. k} */
        for (k = 0; k < V; k++)
        {
            // Pick all vertices as source one by one
            for (i = 0; i < V; i++)
            {
                // Pick all vertices as destination for the
                // above picked source
                for (j = 0; j < V; j++)
                {
                    // If vertex k is on the shortest path from
                    // i to j, then update the value of dist[i][j]
                    if (dist[i][k] + dist[k][j] < dist[i][j])
                        dist[i][j] = dist[i][k] + dist[k][j];
                }
            }
        }
  
        // Print the shortest distance matrix
        printSolution(dist);
    }
  
    void printSolution(int dist[][])
    {
        System.out.println("The following matrix shows the shortest "+
                         "distances between every pair of vertices");
        for (int i=0; i<V; ++i)
        {
            for (int j=0; j<V; ++j)
            {
                if (dist[i][j]==INF)
                    System.out.print("INF ");
                else
                    System.out.print(dist[i][j]+"   ");

188
Chapter 16. DP-16 | Floyd Warshall Algorithm

            }
            System.out.println();
        }
    }
  
    // Driver program to test above function
    public static void main (String[] args)
    {
        /* Let us create the following weighted graph
           10
        (0)------->(3)
        |         /|\
        5 |          |
        |          | 1
        \|/         |
        (1)------->(2)
           3           */
        int graph[][] = { {0,   5,  INF, 10},
                          {INF, 0,   3, INF},
                          {INF, INF, 0,   1},
                          {INF, INF, INF, 0}
                        };
        AllPairShortestPath a = new AllPairShortestPath();
  
        // Print the solution
        a.floydWarshall(graph);
    }
}
  
// Contributed by Aakash Hasija

Python

# Python Program for Floyd Warshall Algorithm


  
# Number of vertices in the graph
V = 4 
  
# Define infinity as the large enough value. This value will be
# used for vertices not connected to each other
INF  = 99999
  
# Solves all pair shortest path via Floyd Warshall Algorithm
def floydWarshall(graph):
  
    """ dist[][] will be the output matrix that will finally
        have the shortest distances between every pair of vertices """
    """ initializing the solution matrix same as input graph matrix

189
Chapter 16. DP-16 | Floyd Warshall Algorithm

    OR we can say that the initial values of shortest distances


    are based on shortest paths considering no 
    intermediate vertices """
    dist = map(lambda i : map(lambda j : j , i) , graph)
      
    """ Add all vertices one by one to the set of intermediate
     vertices.
     ---> Before start of an iteration, we have shortest distances
     between all pairs of vertices such that the shortest
     distances consider only the vertices in the set 
    {0, 1, 2, .. k-1} as intermediate vertices.
      ----> After the end of a iteration, vertex no. k is
     added to the set of intermediate vertices and the 
    set becomes {0, 1, 2, .. k}
    """
    for k in range(V):
  
        # pick all vertices as source one by one
        for i in range(V):
  
            # Pick all vertices as destination for the
            # above picked source
            for j in range(V):
  
                # If vertex k is on the shortest path from 
                # i to j, then update the value of dist[i][j]
                dist[i][j] = min(dist[i][j] ,
                                  dist[i][k]+ dist[k][j]
                                )
    printSolution(dist)
  
  
# A utility function to print the solution
def printSolution(dist):
    print "Following matrix shows the shortest distances\
 between every pair of vertices"
    for i in range(V):
        for j in range(V):
            if(dist[i][j] == INF):
                print "%7s" %("INF"),
            else:
                print "%7d\t" %(dist[i][j]),
            if j == V-1:
                print ""
  
  
  
# Driver program to test the above program

190
Chapter 16. DP-16 | Floyd Warshall Algorithm

# Let us create the following weighted graph


"""
            10
       (0)------->(3)
        |         /|\
      5 |          |
        |          | 1
       \|/         |
       (1)------->(2)
            3           """
graph = [[0,5,INF,10],
             [INF,0,3,INF],
             [INF, INF, 0,   1],
             [INF, INF, INF, 0]
        ]
# Print the solution
floydWarshall(graph);
# This code is contributed by Nikhil Kumar Singh(nickzuck_007)

C#

// A C# program for Floyd Warshall All 


// Pairs Shortest Path algorithm.
  
using System;
  
public class AllPairShortestPath
{
    readonly static int INF = 99999, V = 4;
  
    void floydWarshall(int[,] graph)
    {
        int[,] dist = new int[V, V];
        int i, j, k;
  
        // Initialize the solution matrix 
        // same as input graph matrix
        // Or we can say the initial 
        // values of shortest distances
        // are based on shortest paths 
        // considering no intermediate
        // vertex
        for (i = 0; i < V; i++) {
            for (j = 0; j < V; j++) {
                dist[i, j] = graph[i, j];
            }
        }
  

191
Chapter 16. DP-16 | Floyd Warshall Algorithm

        /* Add all vertices one by one to 


        the set of intermediate vertices.
        ---> Before start of a iteration,
             we have shortest distances
             between all pairs of vertices
             such that the shortest distances
             consider only the vertices in
             set {0, 1, 2, .. k-1} as 
             intermediate vertices.
        ---> After the end of a iteration, 
             vertex no. k is added
             to the set of intermediate
             vertices and the set
             becomes {0, 1, 2, .. k} */
        for (k = 0; k < V; k++)
        {
            // Pick all vertices as source
            // one by one
            for (i = 0; i < V; i++)
            {
                // Pick all vertices as destination
                // for the above picked source
                for (j = 0; j < V; j++)
                {
                    // If vertex k is on the shortest
                    // path from i to j, then update
                    // the value of dist[i][j]
                    if (dist[i, k] + dist[k, j] < dist[i, j]) 
                    {
                        dist[i, j] = dist[i, k] + dist[k, j];
                    }
                }
            }
        }
  
        // Print the shortest distance matrix
        printSolution(dist);
    }
  
    void printSolution(int[,] dist)
    {
        Console.WriteLine("Following matrix shows the shortest "+
                        "distances between every pair of vertices");
        for (int i = 0; i < V; ++i)
        {
            for (int j = 0; j < V; ++j)
            {
                if (dist[i, j] == INF) {

192
Chapter 16. DP-16 | Floyd Warshall Algorithm

                    Console.Write("INF ");
                } else {
                    Console.Write(dist[i, j] + " ");
                }
            }
              
            Console.WriteLine();
        }
    }
  
    // Driver Code
    public static void Main(string[] args)
    {
        /* Let us create the following
           weighted graph
              10
        (0)------->(3)
        |         /|\
        5 |         |
        |         | 1
        \|/         |
        (1)------->(2)
             3             */
        int[,] graph = { {0, 5, INF, 10},
                        {INF, 0, 3, INF},
                        {INF, INF, 0, 1},
                        {INF, INF, INF, 0}
                        };
          
        AllPairShortestPath a = new AllPairShortestPath();
  
        // Print the solution
        a.floydWarshall(graph);
    }
}
  
// This article is contributed by 
// Abdul Mateen Mohammed

Output:

Following matrix shows the shortest distances between every pair of vertices
0 5 8 9
INF 0 3 4
INF INF 0 1
INF INF INF 0

193
Chapter 16. DP-16 | Floyd Warshall Algorithm

Time Complexity: O(V^3)


The above program only prints the shortest distances. We can modify the solution to print
the shortest paths also by storing the predecessor information in a separate 2D matrix.
Also, the value of INF can be taken as INT_MAX from limits.h to make sure that we
handle maximum possible value. When we take INF as INT_MAX, we need to change the
if condition in the above program to avoid arithmetic overflow.

#include

#define INF INT_MAX


..........................
if ( dist[i][k] != INF &&
dist[k][j] != INF &&
dist[i][k] + dist[k][j] < dist[i][j]
)
dist[i][j] = dist[i][k] + dist[k][j];
...........................

Improved By : Abdul Mateen Mohammed

Source

https://www.geeksforgeeks.org/floyd-warshall-algorithm-dp-16/

194
Chapter 17

DP-17 | Palindrome
Partitioning

Palindrome Partitioning | DP-17 - GeeksforGeeks


Given a string, a partitioning of the string is a palindrome partitioning if every substring of
the partition is a palindrome. For example, “aba|b|bbabb|a|b|aba” is a palindrome partition-
ing of “ababbbabbababa”. Determine the fewest cuts needed for palindrome partitioning of
a given string. For example, minimum 3 cuts are needed for “ababbbabbababa”. The three
cuts are “a|babbbab|b|ababa”. If a string is palindrome, then minimum 0 cuts are needed.
If a string of length n containing all different characters, then minimum n-1 cuts are needed.

This problem is a variation of Matrix Chain Multiplication problem. If the string is palin-
drome, then we simply return 0. Else, like the Matrix Chain Multiplication problem, we try
making cuts at all possible places, recursively calculate the cost for each cut and return the
minimum value.
Let the given string be str and minPalPartion() be the function that returns the fewest cuts
needed for palindrome partitioning. following is the optimal substructure property.

// i is the starting index and j is the ending index. i must be passed as 0 and j as n-1
minPalPartion(str, i, j) = 0 if i == j. // When string is of length 1.
minPalPartion(str, i, j) = 0 if str[i..j] is palindrome.

195
Chapter 17. DP-17 | Palindrome Partitioning

// If none of the above conditions is true, then minPalPartion(str, i, j) can be


// calculated recursively using the following formula.
minPalPartion(str, i, j) = Min { minPalPartion(str, i, k) + 1 +
minPalPartion(str, k+1, j) }
where k varies from i to j-1

Following is Dynamic Programming solution. It stores the solutions to subproblems in two


arrays P[][] and C[][], and reuses the calculated values.

C/C++

// Dynamic Programming Solution for Palindrome Partitioning Problem


#include <stdio.h>
#include <string.h>
#include <limits.h>
   
// A utility function to get minimum of two integers
int min (int a, int b) { return (a < b)? a : b; }
   
// Returns the minimum number of cuts needed to partition a string
// such that every part is a palindrome
int minPalPartion(char *str)
{
    // Get the length of the string
    int n = strlen(str);
   
    /* Create two arrays to build the solution in bottom up manner
       C[i][j] = Minimum number of cuts needed for palindrome partitioning
                 of substring str[i..j]
       P[i][j] = true if substring str[i..j] is palindrome, else false
       Note that C[i][j] is 0 if P[i][j] is true */
    int C[n][n];
    bool P[n][n];
   
    int i, j, k, L; // different looping variables
   
    // Every substring of length 1 is a palindrome
    for (i=0; i<n; i++)
    {
        P[i][i] = true;
        C[i][i] = 0;
    }
   
    /* L is substring length. Build the solution in bottom up manner by
       considering all substrings of length starting from 2 to n.
       The loop structure is same as Matrx Chain Multiplication problem (
       See https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ )*/

196
Chapter 17. DP-17 | Palindrome Partitioning

    for (L=2; L<=n; L++)


    {
        // For substring of length L, set different possible starting indexes
        for (i=0; i<n-L+1; i++)
        {
            j = i+L-1; // Set ending index
   
            // If L is 2, then we just need to compare two characters. Else
            // need to check two corner characters and value of P[i+1][j-1]
            if (L == 2)
                P[i][j] = (str[i] == str[j]);
            else
                P[i][j] = (str[i] == str[j]) && P[i+1][j-1];
   
            // IF str[i..j] is palindrome, then C[i][j] is 0
            if (P[i][j] == true)
                C[i][j] = 0;
            else
            {
                // Make a cut at every possible location starting from i to j,
                // and get the minimum cost cut.
                C[i][j] = INT_MAX;
                for (k=i; k<=j-1; k++)
                    C[i][j] = min (C[i][j], C[i][k] + C[k+1][j]+1);
            }
        }
    }
   
    // Return the min cut value for complete string. i.e., str[0..n-1]
    return C[0][n-1];
}
   
// Driver program to test above function
int main()
{
   char str[] = "ababbbabbababa";
   printf("Min cuts needed for Palindrome Partitioning is %d",
           minPalPartion(str));
   return 0;
}

Java

// Java Code for Palindrome Partitioning 


// Problem
public class GFG 
{              
    // Returns the minimum number of cuts needed

197
Chapter 17. DP-17 | Palindrome Partitioning

    // to partition a string such that every 


    // part is a palindrome
    static int minPalPartion(String str)
    {
        // Get the length of the string
        int n = str.length();
        
        /* Create two arrays to build the solution
           in bottom up manner
           C[i][j] = Minimum number of cuts needed 
                     for palindrome partitioning
                     of substring str[i..j]
           P[i][j] = true if substring str[i..j] is
                     palindrome, else false
           Note that C[i][j] is 0 if P[i][j] is
           true */
        int[][] C = new int[n][n];
        boolean[][] P = new boolean[n][n];
        
        int i, j, k, L; // different looping variables
        
        // Every substring of length 1 is a palindrome
        for (i = 0; i < n; i++)
        {
            P[i][i] = true;
            C[i][i] = 0;
        }
        
        /* L is substring length. Build the solution in
         bottom up manner by considering all substrings
         of length starting from 2 to n. The loop 
         structure is same as Matrx Chain Multiplication
         problem (
        See https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ )*/
        for (L = 2; L <= n; L++)
        {
            // For substring of length L, set different
            // possible starting indexes
            for (i = 0; i < n - L + 1; i++)
            {
                j = i + L - 1; // Set ending index
        
                // If L is 2, then we just need to 
                // compare two characters. Else need to
                // check two corner characters and value 
                // of P[i+1][j-1]
                if (L == 2)
                    P[i][j] = (str.charAt(i) == 

198
Chapter 17. DP-17 | Palindrome Partitioning

                                str.charAt(j));
                else
                    P[i][j] = (str.charAt(i) == 
                            str.charAt(j)) && P[i+1][j-1];
        
                // IF str[i..j] is palindrome, then 
                // C[i][j] is 0
                if (P[i][j] == true)
                    C[i][j] = 0;
                else
                {
                    // Make a cut at every possible
                    // localtion starting from i to j,
                    // and get the minimum cost cut.
                    C[i][j] = Integer.MAX_VALUE;
                    for (k = i; k <= j - 1; k++)
                        C[i][j] = Integer.min(C[i][j], 
                                C[i][k] + C[k+1][j] + 1);
                }
            }
        }
        
        // Return the min cut value for complete 
        // string. i.e., str[0..n-1]
        return C[0][n-1];
    }
        
    // Driver program to test above function
    public static void main(String args[])
    {
       String str = "ababbbabbababa";
       System.out.println("Min cuts needed for "+
                       "Palindrome Partitioning is "+
                          minPalPartion(str));
    }
}
// This code is contributed by Sumit Ghosh

C#

// C# Code for Palindrome Partitioning 


// Problem
using System;
  
class GFG
{
    // Returns the minimum number of cuts needed
    // to partition a string such that every 

199
Chapter 17. DP-17 | Palindrome Partitioning

    // part is a palindrome


    static int minPalPartion(String str)
    {
        // Get the length of the string
        int n = str.Length;
          
        /* Create two arrays to build the solution
        in bottom up manner
        C[i][j] = Minimum number of cuts needed 
                    for palindrome partitioning
                    of substring str[i..j]
        P[i][j] = true if substring str[i..j] is
                    palindrome, else false
        Note that C[i][j] is 0 if P[i][j] is
        true */
        int[,] C = new int[n, n];
        bool[,] P = new bool[n, n];
          
        int i, j, k, L; // different looping variables
          
        // Every substring of length 1 is a palindrome
        for (i = 0; i < n; i++)
        {
            P[i, i] = true;
            C[i, i] = 0;
        }
          
        /* L is substring length. Build the solution in
        bottom up manner by considering all substrings
        of length starting from 2 to n. The loop 
        structure is same as Matrx Chain Multiplication
        problem (
        See https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ )*/
        for (L = 2; L <= n; L++)
        {
            // For substring of length L, set different
            // possible starting indexes
            for (i = 0; i < n - L + 1; i++)
            {
                j = i + L - 1; // Set ending index
          
                // If L is 2, then we just need to 
                // compare two characters. Else need to
                // check two corner characters and value 
                // of P[i+1][j-1]
                if (L == 2)
                    P[i,j] = (str[i] == str[j]);
                else

200
Chapter 17. DP-17 | Palindrome Partitioning

                    P[i,j] = (str[i] == str[j]) &&


                             P[i + 1, j - 1];
          
                // IF str[i..j] is palindrome, then 
                // C[i][j] is 0
                if (P[i, j] == true)
                    C[i, j] = 0;
                else
                {
                    // Make a cut at every possible
                    // localtion starting from i to j,
                    // and get the minimum cost cut.
                    C[i, j] = int.MaxValue;
                    for (k = i; k <= j - 1; k++)
                        C[i, j] = Math.Min(C[i, j], C[i, k] 
                                  + C[k + 1, j] + 1);
                }
            }
        }
          
        // Return the min cut value for complete 
        // string. i.e., str[0..n-1]
        return C[0, n - 1];
    }
          
    // Driver program 
    public static void Main()
    {
    String str = "ababbbabbababa";
    Console.Write("Min cuts needed for "+
                  "Palindrome Partitioning is "+
                  minPalPartion(str));
    }
}
  
// This code is contributed by Sam007

Output:

Min cuts needed for Palindrome Partitioning is 3

Time Complexity: O(n3 )


An optimization to above approach
In above approach, we can calculate minimum cut while finding all palindromic substring.
If we find all palindromic substring 1st and then we calculate minimum cut, time complexity
will reduce to O(n2 ).

201
Chapter 17. DP-17 | Palindrome Partitioning

Thanks for Vivek for suggesting this optimization.

C++

// Dynamic Programming Solution for Palindrome Partitioning Problem


#include <stdio.h>
#include <string.h>
#include <limits.h>
   
// A utility function to get minimum of two integers
int min (int a, int b) { return (a < b)? a : b; }
   
// Returns the minimum number of cuts needed to partition a string
// such that every part is a palindrome
int minPalPartion(char *str)
{
    // Get the length of the string
    int n = strlen(str);
   
    /* Create two arrays to build the solution in bottom up manner
       C[i] = Minimum number of cuts needed for palindrome partitioning
                 of substring str[0..i]
       P[i][j] = true if substring str[i..j] is palindrome, else false
       Note that C[i] is 0 if P[0][i] is true */
    int C[n];
    bool P[n][n];
   
    int i, j, k, L; // different looping variables
   
    // Every substring of length 1 is a palindrome
    for (i=0; i<n; i++)
    {
        P[i][i] = true;
    }
   
    /* L is substring length. Build the solution in bottom up manner by
       considering all substrings of length starting from 2 to n. */
    for (L=2; L<=n; L++)
    {
        // For substring of length L, set different possible starting indexes
        for (i=0; i<n-L+1; i++)
        {
            j = i+L-1; // Set ending index
   
            // If L is 2, then we just need to compare two characters. Else
            // need to check two corner characters and value of P[i+1][j-1]
            if (L == 2)
                P[i][j] = (str[i] == str[j]);

202
Chapter 17. DP-17 | Palindrome Partitioning

            else
                P[i][j] = (str[i] == str[j]) && P[i+1][j-1];
        }
    }
  
    for (i=0; i<n; i++)
    {
        if (P[0][i] == true)
            C[i] = 0;
        else
        {
            C[i] = INT_MAX;
            for(j=0;j<i;j++)
            {
                if(P[j+1][i] == true && 1+C[j]<C[i])
                    C[i]=1+C[j];
            }
        }
    }
   
    // Return the min cut value for complete string. i.e., str[0..n-1]
    return C[n-1];
}
   
// Driver program to test above function
int main()
{
   char str[] = "ababbbabbababa";
   printf("Min cuts needed for Palindrome Partitioning is %d",
           minPalPartion(str));
   return 0;
}

Java

// Java Code for Palindrome Partitioning 


// Problem
public class GFG 
{            
    // Returns the minimum number of cuts needed
    // to partition a string such that every part
    // is a palindrome
    static int minPalPartion(String str)
    {
        // Get the length of the string
        int n = str.length();
        
        /* Create two arrays to build the solution

203
Chapter 17. DP-17 | Palindrome Partitioning

        in bottom up manner


           C[i] = Minimum number of cuts needed for
           palindrome partitioning of substring
           str[0..i]
           P[i][j] = true if substring str[i..j] is 
           palindrome, else false
           Note that C[i] is 0 if P[0][i] is true */
        int[] C = new int[n];
        boolean[][] P = new boolean[n][n];
        
        int i, j, k, L; // different looping variables
        
        // Every substring of length 1 is a palindrome
        for (i = 0; i < n; i++)
        {
            P[i][i] = true;
        }
        
        /* L is substring length. Build the solution 
        in bottom up manner by considering all substrings 
        of length starting from 2 to n. */
        for (L = 2; L <= n; L++)
        {
            // For substring of length L, set different 
            // possible starting indexes
            for (i = 0; i < n - L + 1; i++)
            {
                j = i + L - 1; // Set ending index
        
                // If L is 2, then we just need to 
                // compare two characters. Else need to 
                // check two corner characters and value
                // of P[i+1][j-1]
                if (L == 2)
                    P[i][j] = (str.charAt(i) ==
                                 str.charAt(j));
                else
                    P[i][j] = (str.charAt(i) == 
                           str.charAt(j)) && P[i+1][j-1];
            }
        }
       
        for (i = 0; i < n; i++)
        {
            if (P[0][i] == true)
                C[i] = 0;
            else
            {

204
Chapter 17. DP-17 | Palindrome Partitioning

                C[i] = Integer.MAX_VALUE;
                for(j = 0; j < i; j++)
                {
                    if(P[j+1][i] == true && 1 +
                                 C[j] < C[i])
                        C[i] = 1 + C[j];
                }
            }
        }
        
        // Return the min cut value for complete
        // string. i.e., str[0..n-1]
        return C[n-1];
    }
      
    // Driver program to test above function
    public static void main(String args[])
    {
       String str = "ababbbabbababa";
       System.out.println("Min cuts needed for "+
                          "Palindrome Partitioning"+
                          " is "+ minPalPartion(str));
    }
}
// This code is contributed by Sumit Ghosh

C#

// C# Code for Palindrome Partitioning 


// Problem
using System;
  
class GFG
{
              
    // Returns the minimum number of cuts needed
    // to partition a string such that every part
    // is a palindrome
    static int minPalPartion(String str)
    {
        // Get the length of the string
        int n = str.Length;
          
        /* Create two arrays to build the solution
        in bottom up manner
        C[i] = Minimum number of cuts needed for
        palindrome partitioning of substring
        str[0..i]

205
Chapter 17. DP-17 | Palindrome Partitioning

        P[i][j] = true if substring str[i..j] is 


        palindrome, else false
        Note that C[i] is 0 if P[0][i] is true */
        int[] C = new int[n];
        bool[,] P = new bool[n,n];
          
        int i, j, L; // different looping variables
          
        // Every substring of length 1 is a palindrome
        for (i = 0; i < n; i++)
        {
            P[i,i] = true;
        }
          
        /* L is substring length. Build the solution 
        in bottom up manner by considering all substrings 
        of length starting from 2 to n. */
        for (L = 2; L <= n; L++)
        {
            // For substring of length L, set different 
            // possible starting indexes
            for (i = 0; i < n - L + 1; i++)
            {
                j = i + L - 1; // Set ending index
          
                // If L is 2, then we just need to 
                // compare two characters. Else need to 
                // check two corner characters and value
                // of P[i+1][j-1]
                if (L == 2)
                    P[i,j] = (str[i] == str[j]);
                else
                    P[i,j] = (str[i] == str[j]) && P[i+1,j-1];
            }
        }
      
        for (i = 0; i < n; i++)
        {
            if (P[0,i] == true)
                C[i] = 0;
            else
            {
                C[i] = int.MaxValue;
                for(j = 0; j < i; j++)
                {
                    if(P[j+1,i] == true && 1 + C[j] < C[i])
                        C[i] = 1 + C[j];
                }

206
Chapter 17. DP-17 | Palindrome Partitioning

            }
        }
          
        // Return the min cut value for complete
        // string. i.e., str[0..n-1]
        return C[n-1];
    }
      
    // Driver program 
    public static void Main()
    {
    String str = "ababbbabbababa";
    Console.Write("Min cuts needed for "+
                        "Palindrome Partitioning"+
                        " is "+ minPalPartion(str));
    }
}
  
// This code is contributed by Sam007

Output:

Min cuts needed for Palindrome Partitioning is 3

Time Complexity: O(n2 )

Source

https://www.geeksforgeeks.org/palindrome-partitioning-dp-17/

207
Chapter 18

DP-18 | Partition problem

Partition problem | DP-18 - GeeksforGeeks


Partition problem is to determine whether a given set can be partitioned into two subsets
such that the sum of elements in both subsets is same.
Examples

arr[] = {1, 5, 11, 5}


Output: true
The array can be partitioned as {1, 5, 5} and {11}

arr[] = {1, 5, 3}
Output: false
The array cannot be partitioned into equal sum sets.

Following are the two main steps to solve this problem:


1) Calculate sum of the array. If sum is odd, there can not be two subsets with equal sum,
so return false.
2) If sum of array elements is even, calculate sum/2 and find a subset of array with sum
equal to sum/2.
The first step is simple. The second step is crucial, it can be solved either using recursion
or Dynamic Programming.
Recursive Solution
Following is the recursive property of the second step mentioned above.

Let isSubsetSum(arr, n, sum/2) be the function that returns true if


there is a subset of arr[0..n-1] with sum equal to sum/2

The isSubsetSum problem can be divided into two subproblems

208
Chapter 18. DP-18 | Partition problem

a) isSubsetSum() without considering last element


(reducing n to n-1)
b) isSubsetSum considering the last element
(reducing sum/2 by arr[n-1] and n to n-1)
If any of the above the above subproblems return true, then return true.
isSubsetSum (arr, n, sum/2) = isSubsetSum (arr, n-1, sum/2) ||
isSubsetSum (arr, n-1, sum/2 - arr[n-1])

C/C++

// A  recursive C program for partition problem


#include <stdio.h>
  
// A utility function that returns true if there is 
// a subset of arr[] with sun equal to given sum
bool isSubsetSum (int arr[], int n, int sum)
{
   // Base Cases
   if (sum == 0)
     return true;
   if (n == 0 && sum != 0)
     return false;
  
   // If last element is greater than sum, then 
   // ignore it
   if (arr[n-1] > sum)
     return isSubsetSum (arr, n-1, sum);
  
   /* else, check if sum can be obtained by any of 
      the following
      (a) including the last element
      (b) excluding the last element
   */
   return isSubsetSum (arr, n-1, sum) || 
          isSubsetSum (arr, n-1, sum-arr[n-1]);
}
  
// Returns true if arr[] can be partitioned in two
//  subsets of equal sum, otherwise false
bool findPartiion (int arr[], int n)
{
    // Calculate sum of the elements in array
    int sum = 0;
    for (int i = 0; i < n; i++)
       sum += arr[i];
  
    // If sum is odd, there cannot be two subsets 
    // with equal sum

209
Chapter 18. DP-18 | Partition problem

    if (sum%2 != 0)
       return false;
  
    // Find if there is subset with sum equal to
    // half of total sum
    return isSubsetSum (arr, n, sum/2);
}
  
// Driver program to test above function
int main()
{
  int arr[] = {3, 1, 5, 9, 12};
  int n = sizeof(arr)/sizeof(arr[0]);
  if (findPartiion(arr, n) == true)
     printf("Can be divided into two subsets "
            "of equal sum");
  else
     printf("Can not be divided into two subsets"
            " of equal sum");
  return 0;
}

Java

// A recursive Java solution for partition problem


import java.io.*;
  
class Partition
{
    // A utility function that returns true if there is a
    // subset of arr[] with sun equal to given sum
    static boolean isSubsetSum (int arr[], int n, int sum)
    {
        // Base Cases
        if (sum == 0)
            return true;
        if (n == 0 && sum != 0)
            return false;
  
        // If last element is greater than sum, then ignore it
        if (arr[n-1] > sum)
            return isSubsetSum (arr, n-1, sum);
  
        /* else, check if sum can be obtained by any of
           the following
        (a) including the last element
        (b) excluding the last element
        */

210
Chapter 18. DP-18 | Partition problem

        return isSubsetSum (arr, n-1, sum) ||


               isSubsetSum (arr, n-1, sum-arr[n-1]);
    }
  
    // Returns true if arr[] can be partitioned in two
    // subsets of equal sum, otherwise false
    static boolean findPartition (int arr[], int n)
    {
        // Calculate sum of the elements in array
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
  
        // If sum is odd, there cannot be two subsets
        // with equal sum
        if (sum%2 != 0)
            return false;
  
        // Find if there is subset with sum equal to half
        // of total sum
        return isSubsetSum (arr, n, sum/2);
    }
  
    /*Driver function to check for above function*/
    public static void main (String[] args)
    {
  
        int arr[] = {3, 1, 5, 9, 12};
        int n = arr.length;
        if (findPartition(arr, n) == true)
            System.out.println("Can be divided into two "+
                                "subsets of equal sum");
        else
            System.out.println("Can not be divided into " +
                                "two subsets of equal sum");
    }
}
/* This code is contributed by Devesh Agrawal */

Python3

# A recursive Python3 program for 


# partition problem
  
# A utility function that returns 
# true if there is a subset of
# arr[] with sun equal to given sum
def isSubsetSum (arr, n, sum):

211
Chapter 18. DP-18 | Partition problem

    # Base Cases


    if sum == 0:
        return True
    if n == 0 and sum != 0:
        return False
  
    # If last element is greater than sum, then 
    # ignore it
    if arr[n-1] > sum:
        return isSubsetSum (arr, n-1, sum)
  
    ''' else, check if sum can be obtained by any of 
    the following
    (a) including the last element
    (b) excluding the last element'''
      
    return isSubsetSum (arr, n-1, sum) or isSubsetSum (arr, n-1, sum-arr[n-1])
  
# Returns true if arr[] can be partitioned in two
# subsets of equal sum, otherwise false
def findPartion (arr, n):
    # Calculate sum of the elements in array
    sum = 0
    for i in range(0, n):
        sum += arr[i]
    # If sum is odd, there cannot be two subsets 
    # with equal sum
    if sum % 2 != 0:
        return false
  
    # Find if there is subset with sum equal to
    # half of total sum
    return isSubsetSum (arr, n, sum // 2)
  
# Driver program to test above function
arr = [3, 1, 5, 9, 12]
n = len(arr)
if findPartion(arr, n) == True:
    print ("Can be divided into two subsets of equal sum")
else:
    print ("Can not be divided into two subsets of equal sum")
      
# This code is contributed by shreyanshi_arun.     

C#

// A recursive C# solution for partition problem


using System;

212
Chapter 18. DP-18 | Partition problem

  
class GFG
{
    // A utility function that returns true if there is a
    // subset of arr[] with sun equal to given sum
    static bool isSubsetSum (int []arr, int n, int sum)
    {
        // Base Cases
        if (sum == 0)
            return true;
        if (n == 0 && sum != 0)
            return false;
  
        // If last element is greater than sum, then ignore it
        if (arr[n-1] > sum)
            return isSubsetSum (arr, n-1, sum);
  
        /* else, check if sum can be obtained by any of
        the following
        (a) including the last element
        (b) excluding the last element
        */
        return isSubsetSum (arr, n-1, sum) ||
               isSubsetSum (arr, n-1, sum-arr[n-1]);
    }
  
    // Returns true if arr[] can be partitioned in two
    // subsets of equal sum, otherwise false
    static bool findPartition (int []arr, int n)
    {
        // Calculate sum of the elements in array
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
  
        // If sum is odd, there cannot be two subsets
        // with equal sum
        if (sum%2 != 0)
            return false;
  
        // Find if there is subset with sum equal to half
        // of total sum
        return isSubsetSum (arr, n, sum/2);
    }
  
    // Driver function 
    public static void Main ()
    {

213
Chapter 18. DP-18 | Partition problem

  
        int []arr = {3, 1, 5, 9, 12};
        int n = arr.Length;
        if (findPartition(arr, n) == true)
            Console.Write("Can be divided into two "+
                          "subsets of equal sum");
        else
            Console.Write("Can not be divided into " +
                          "two subsets of equal sum");
    }
}
  
// This code is contributed by Sam007

Output:

Can be divided into two subsets of equal sum

Time Complexity: O(2^n) In worst case, this solution tries two possibilities (whether to
include or exclude) for every element.
Dynamic Programming Solution
The problem can be solved using dynamic programming when the sum of the elements is
not too big. We can create a 2D array part[][] of size (sum/2)*(n+1). And we can construct
the solution in bottom up manner such that every filled entry has following property

part[i][j] = true if a subset of {arr[0], arr[1], ..arr[j-1]} has sum


equal to i, otherwise false

C/C++

// A Dynamic Programming based C program to partition problem


#include <stdio.h>
  
// Returns true if arr[] can be partitioned in two subsets of
// equal sum, otherwise false
bool findPartiion (int arr[], int n)
{
    int sum = 0;
    int i, j;
    
    // Caculcate sun of all elements
    for (i = 0; i < n; i++)
      sum += arr[i];

214
Chapter 18. DP-18 | Partition problem

      
    if (sum%2 != 0)  
       return false;
    
    bool part[sum/2+1][n+1];
      
    // initialize top row as true
    for (i = 0; i <= n; i++)
      part[0][i] = true;
        
    // initialize leftmost column, except part[0][0], as 0
    for (i = 1; i <= sum/2; i++)
      part[i][0] = false;     
       
     // Fill the partition table in botton up manner 
     for (i = 1; i <= sum/2; i++)  
     {
       for (j = 1; j <= n; j++)  
       {
         part[i][j] = part[i][j-1];
         if (i >= arr[j-1])
           part[i][j] = part[i][j] || part[i - arr[j-1]][j-1];
       }        
     }    
       
    /* // uncomment this part to print table 
     for (i = 0; i <= sum/2; i++)  
     {
       for (j = 0; j <= n; j++)  
          printf ("%4d", part[i][j]);
       printf("\n");
     } */ 
       
     return part[sum/2][n];
}     
  
// Driver program to test above funtion
int main()
{
  int arr[] = {3, 1, 1, 2, 2, 1};
  int n = sizeof(arr)/sizeof(arr[0]);
  if (findPartiion(arr, n) == true)
     printf("Can be divided into two subsets of equal sum");
  else
     printf("Can not be divided into two subsets of equal sum");
  getchar();
  return 0;
}

215
Chapter 18. DP-18 | Partition problem

Java

// A dynamic programming based Java program for partition problem


import java.io.*;
  
class Partition {
  
    // Returns true if arr[] can be partitioned in two subsets of
    // equal sum, otherwise false
    static boolean findPartition (int arr[], int n)
    {
        int sum = 0;
        int i, j;
  
        // Caculcate sun of all elements
        for (i = 0; i < n; i++)
            sum += arr[i];
  
        if (sum%2 != 0)
            return false;
  
        boolean part[][]=new boolean[sum/2+1][n+1];
  
        // initialize top row as true
        for (i = 0; i <= n; i++)
            part[0][i] = true;
  
        // initialize leftmost column, except part[0][0], as 0
        for (i = 1; i <= sum/2; i++)
            part[i][0] = false;
  
        // Fill the partition table in botton up manner
        for (i = 1; i <= sum/2; i++)
        {
            for (j = 1; j <= n; j++)
            {
                part[i][j] = part[i][j-1];
                if (i >= arr[j-1])
                    part[i][j] = part[i][j] ||
                                 part[i - arr[j-1]][j-1];
            }
        }
  
        /* // uncomment this part to print table
        for (i = 0; i <= sum/2; i++)
        {
            for (j = 0; j <= n; j++)
                printf ("%4d", part[i][j]);

216
Chapter 18. DP-18 | Partition problem

            printf("\n");
        } */
  
        return part[sum/2][n];
    }
  
    /*Driver function to check for above function*/
    public static void main (String[] args)
    {
        int arr[] = {3, 1, 1, 2, 2,1};
        int n = arr.length;
        if (findPartition(arr, n) == true)
            System.out.println("Can be divided into two "
                               "subsets of equal sum");
        else
            System.out.println("Can not be divided into"
                            " two subsets of equal sum");
  
    }
}
/* This code is contributed by Devesh Agrawal */

C#

// A dynamic programming based C# program 


// for partition problem
using System;
  
class GFG {
      
    // Returns true if arr[] can be partitioned 
    // in two subsets of equal sum, otherwise 
    // false
    static bool findPartition (int []arr, int n)
    {
          
        int sum = 0;
        int i, j;
  
        // Caculcate sun of all elements
        for (i = 0; i < n; i++)
            sum += arr[i];
  
        if (sum % 2 != 0)
            return false;
  
        bool [, ]part=new bool[sum / 2 + 1, n + 1];
  

217
Chapter 18. DP-18 | Partition problem

        // initialize top row as true


        for (i = 0; i <= n; i++)
            part[0, i] = true;
  
        // initialize leftmost column, except 
        // part[0][0], as 0
        for (i = 1; i <= sum/2; i++)
            part[i, 0] = false;
  
        // Fill the partition table in botton 
        // up manner
        for (i = 1; i <= sum/2; i++)
        {
            for (j = 1; j <= n; j++)
            {
                part[i, j] = part[i, j - 1];
                if (i >= arr[j - 1])
                    part[i, j] = part[i, j] ||
                    part[i - arr[j - 1],j - 1];
            }
        }
  
        /* // uncomment this part to print table
        for (i = 0; i <= sum/2; i++)
        {
            for (j = 0; j <= n; j++)
                printf ("%4d", part[i][j]);
            printf("\n");
        } */
  
        return part[sum / 2, n];
    }
  
    // Driver program to test above funtion
    public static void Main ()
    {
        int []arr = {3, 1, 1, 2, 2,1};
        int n = arr.Length;
          
        if (findPartition(arr, n) == true)
            Console.Write("Can be divided" 
                  + " into two subsets of"
                          + " equal sum");
        else
            Console.Write("Can not be " 
               + "divided into two subsets"
                      + " of equal sum");
  

218
Chapter 18. DP-18 | Partition problem

    }
}
  
// This code is contributed by Sam007.

Output:

Can be divided into two subsets of equal sum

Following diagram shows the values in partition table.

Time Complexity: O(sum*n)


Auxiliary Space: O(sum*n)
Please note that this solution will not be feasible for arrays with big sum.
References:
http://en.wikipedia.org/wiki/Partition_problem
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.

Source

https://www.geeksforgeeks.org/partition-problem-dp-18/

219
Chapter 19

DP-19 | Word Wrap Problem

Word Wrap Problem | DP-19 - GeeksforGeeks


Given a sequence of words, and a limit on the number of characters that can be put in one
line (line width). Put line breaks in the given sequence such that the lines are printed neatly.
Assume that the length of each word is smaller than the line width.
The word processors like MS Word do task of placing line breaks. The idea is to have
balanced lines. In other words, not have few lines with lots of extra spaces and some lines
with small amount of extra spaces.

The extra spaces includes spaces put at the end of every line except the last one.
The problem is to minimize the following total cost.
Cost of a line = (Number of extra spaces in the line)^3
Total Cost = Sum of costs for all lines

For example, consider the following string and line width M = 15


"Geeks for Geeks presents word wrap problem"

Following is the optimized arrangement of words in 3 lines


Geeks for Geeks
presents word
wrap problem

The total extra spaces in line 1, line 2 and line 3 are 0, 2 and 3 respectively.
So optimal value of total cost is 0 + 2*2 + 3*3 = 13

Please note that the total cost function is not sum of extra spaces, but sum of cubes (or
square is also used) of extra spaces. The idea behind this cost function is to balance the
spaces among lines. For example, consider the following two arrangement of same set of
words:

220
Chapter 19. DP-19 | Word Wrap Problem

1) There are 3 lines. One line has 3 extra spaces and all other lines have 0 extra spaces.
Total extra spaces = 3 + 0 + 0 = 3. Total cost = 3*3*3 + 0*0*0 + 0*0*0 = 27.
2) There are 3 lines. Each of the 3 lines has one extra space. Total extra spaces = 1 + 1 +
1 = 3. Total cost = 1*1*1 + 1*1*1 + 1*1*1 = 3.
Total extra spaces are 3 in both scenarios, but second arrangement should be preferred
because extra spaces are balanced in all three lines. The cost function with cubic sum
serves the purpose because the value of total cost in second scenario is less.
Method 1 (Greedy Solution)
The greedy solution is to place as many words as possible in the first line. Then do the
same thing for the second line and so on until all words are placed. This solution gives
optimal solution for many cases, but doesn’t give optimal solution in all cases. For example,
consider the following string “aaa bb cc ddddd” and line width as 6. Greedy method will
produce following output.

aaa bb
cc
ddddd

Extra spaces in the above 3 lines are 0, 4 and 1 respectively. So total cost is 0 + 64 + 1 =
65.
But the above solution is not the best solution. Following arrangement has more balanced
spaces. Therefore less value of total cost function.

aaa
bb cc
ddddd

Extra spaces in the above 3 lines are 3, 1 and 1 respectively. So total cost is 27 + 1 + 1 =
29.
Despite being sub-optimal in some cases, the greedy approach is used by many word pro-
cessors like MS Word and OpenOffice.org Writer.
Method 2 (Dynamic Programming)
The following Dynamic approach strictly follows the algorithm given in solution of Cormen
book. First we compute costs of all possible lines in a 2D table lc[][]. The value lc[i][j]
indicates the cost to put words from i to j in a single line where i and j are indexes of words
in the input sequences. If a sequence of words from i to j cannot fit in a single line, then
lc[i][j] is considered infinite (to avoid it from being a part of the solution). Once we have
the lc[][] table constructed, we can calculate total cost using following recursive formula. In
the following formula, C[j] is the optimized total cost for arranging words from 1 to j.

221
Chapter 19. DP-19 | Word Wrap Problem

The above recursion has overlapping subproblem property. For example, the solution of
subproblem c(2) is used by c(3), C(4) and so on. So Dynamic Programming is used to store
the results of subproblems. The array c[] can be computed from left to right, since each
value depends only on earlier values.
To print the output, we keep track of what words go on what lines, we can keep a parallel
p array that points to where each c value came from. The last line starts at word p[n] and
goes through word n. The previous line starts at word p[p[n]] and goes through word p[n?]
– 1, etc. The function printSolution() uses p[] to print the solution.
In the below program, input is an array l[] that represents lengths of words in a sequence.
The value l[i] indicates length of the ith word (i starts from 1) in theinput sequence.

C/C++

// A Dynamic programming solution for Word Wrap Problem


#include <limits.h>
#include <stdio.h>
#define INF INT_MAX
  
// A utility function to print the solution
int printSolution (int p[], int n);
  
// l[] represents lengths of different words in input sequence. For example, 
// l[] = {3, 2, 2, 5} is for a sentence like "aaa bb cc ddddd".  n is size of 
// l[] and M is line width (maximum no. of characters that can fit in a line)
void solveWordWrap (int l[], int n, int M)
{
    // For simplicity, 1 extra space is used in all below arrays 
  
    // extras[i][j] will have number of extra spaces if words from i 
    // to j are put in a single line
    int extras[n+1][n+1];  
  
    // lc[i][j] will have cost of a line which has words from 
    // i to j
    int lc[n+1][n+1];
   
    // c[i] will have total cost of optimal arrangement of words 
    // from 1 to i
    int c[n+1];
  

222
Chapter 19. DP-19 | Word Wrap Problem

    // p[] is used to print the solution.  


    int p[n+1];
  
    int i, j;
  
    // calculate extra spaces in a single line.  The value extra[i][j]
    // indicates extra spaces if words from word number i to j are
    // placed in a single line
    for (i = 1; i <= n; i++)
    {
        extras[i][i] = M - l[i-1];
        for (j = i+1; j <= n; j++)
            extras[i][j] = extras[i][j-1] - l[j-1] - 1;
    }
  
    // Calculate line cost corresponding to the above calculated extra
    // spaces. The value lc[i][j] indicates cost of putting words from
    // word number i to j in a single line
    for (i = 1; i <= n; i++)
    {
        for (j = i; j <= n; j++)
        {
            if (extras[i][j] < 0)
                lc[i][j] = INF;
            else if (j == n && extras[i][j] >= 0)
                lc[i][j] = 0;
            else
                lc[i][j] = extras[i][j]*extras[i][j];
        }
    }
  
    // Calculate minimum cost and find minimum cost arrangement.
    //  The value c[j] indicates optimized cost to arrange words
    // from word number 1 to j.
    c[0] = 0;
    for (j = 1; j <= n; j++)
    {
        c[j] = INF;
        for (i = 1; i <= j; i++)
        {
            if (c[i-1] != INF && lc[i][j] != INF && (c[i-1] + lc[i][j] < c[j]))
            {
                c[j] = c[i-1] + lc[i][j];
                p[j] = i;
            }
        }
    }
  

223
Chapter 19. DP-19 | Word Wrap Problem

    printSolution(p, n);
}
  
int printSolution (int p[], int n)
{
    int k;
    if (p[n] == 1)
        k = 1;
    else
        k = printSolution (p, p[n]-1) + 1;
    printf ("Line number %d: From word no. %d to %d \n", k, p[n], n);
    return k;
}
  
// Driver program to test above functions
int main()
{
    int l[] = {3, 2, 2, 5};
    int n = sizeof(l)/sizeof(l[0]);
    int M = 6;
    solveWordWrap (l, n, M);
    return 0;
}

Java

// A Dynamic programming solution for


// Word Wrap Problem in Java
public class WordWrap
{
  
    final int MAX = Integer.MAX_VALUE;
      
    // A utility function to print the solution
    int printSolution (int p[], int n)
    {
        int k;
        if (p[n] == 1)
        k = 1;
        else
        k = printSolution (p, p[n]-1) + 1;
        System.out.println("Line number" + " " + k + ": " + 
                    "From word no." +" "+ p[n] + " " + "to" + " " + n);
        return k;
    }
  
    // l[] represents lengths of different words in input sequence. For example,
    // l[] = {3, 2, 2, 5} is for a sentence like "aaa bb cc ddddd". n is size of

224
Chapter 19. DP-19 | Word Wrap Problem

    // l[] and M is line width (maximum no. of characters that can fit in a line)
    void solveWordWrap (int l[], int n, int M)
    {
        // For simplicity, 1 extra space is used in all below arrays
      
        // extras[i][j] will have number of extra spaces if words from i
        // to j are put in a single line
        int extras[][] = new int[n+1][n+1];
      
        // lc[i][j] will have cost of a line which has words from
        // i to j
        int lc[][]= new int[n+1][n+1];
      
        // c[i] will have total cost of optimal arrangement of words
        // from 1 to i
        int c[] = new int[n+1];
      
        // p[] is used to print the solution.
        int p[] =new int[n+1];
      
        // calculate extra spaces in a single line. The value extra[i][j]
        // indicates extra spaces if words from word number i to j are
        // placed in a single line
        for (int i = 1; i <= n; i++)
        {
            extras[i][i] = M - l[i-1];
            for (int j = i+1; j <= n; j++)
            extras[i][j] = extras[i][j-1] - l[j-1] - 1;
        }
          
        // Calculate line cost corresponding to the above calculated extra
        // spaces. The value lc[i][j] indicates cost of putting words from
        // word number i to j in a single line
        for (int i = 1; i <= n; i++)
        {
            for (int j = i; j <= n; j++)
            {
                if (extras[i][j] < 0)
                    lc[i][j] = MAX;
                else if (j == n && extras[i][j] >= 0)
                    lc[i][j] = 0;
                else
                    lc[i][j] = extras[i][j]*extras[i][j];
            }
        }
          
        // Calculate minimum cost and find minimum cost arrangement.
        // The value c[j] indicates optimized cost to arrange words

225
Chapter 19. DP-19 | Word Wrap Problem

        // from word number 1 to j.


        c[0] = 0;
        for (int j = 1; j <= n; j++)
        {
            c[j] = MAX;
            for (int i = 1; i <= j; i++)
            {
                if (c[i-1] != MAX && lc[i][j] != MAX && (c[i-1] + lc[i][j] < c[j]))
                {
                    c[j] = c[i-1] + lc[i][j];
                    p[j] = i;
                }
            }
        }
      
        printSolution(p, n);
    }
  
    public static void main(String args[])
    {
        WordWrap w = new WordWrap();
        int l[] = {3, 2, 2, 5};
        int n = l.length;
        int M = 6;
        w.solveWordWrap (l, n, M);
    }
}
  
// This code is contributed by Saket Kumar

C#

// A Dynamic programming solution for Word Wrap


// Problem in Java
using System;
  
public class GFG {
  
    static int MAX = int.MaxValue;
      
    // A utility function to print the solution
    static int printSolution (int []p, int n)
    {
        int k;
          
        if (p[n] == 1)
            k = 1;
        else

226
Chapter 19. DP-19 | Word Wrap Problem

            k = printSolution (p, p[n]-1) + 1;


              
        Console.WriteLine("Line number" + " "
                + k + ": From word no." + " "
                + p[n] + " " + "to" + " " + n);
        return k;
    }
  
    // l[] represents lengths of different 
    // words in input sequence. For example,
    // l[] = {3, 2, 2, 5} is for a sentence
    // like "aaa bb cc ddddd". n is size of
    // l[] and M is line width (maximum no. 
    // of characters that can fit in a line)
    static void solveWordWrap (int []l, int n, 
                                        int M)
    {
          
        // For simplicity, 1 extra space
        // is used in all below arrays
      
        // extras[i][j] will have number of
        // extra spaces if words from i
        // to j are put in a single line
        int [,]extras = new int[n+1,n+1];
      
        // lc[i][j] will have cost of a line 
        // which has words from i to j
        int [,]lc = new int[n+1,n+1];
      
        // c[i] will have total cost of
        // optimal arrangement of words 
        // from 1 to i
        int []c = new int[n+1];
      
        // p[] is used to print the solution.
        int []p = new int[n+1];
      
        // calculate extra spaces in a single 
        // line. The value extra[i][j] indicates
        // extra spaces if words from word number
        // i to j are placed in a single line
        for (int i = 1; i <= n; i++)
        {
            extras[i,i] = M - l[i-1];
              
            for (int j = i+1; j <= n; j++)
                extras[i,j] = extras[i,j-1]

227
Chapter 19. DP-19 | Word Wrap Problem

                                 - l[j-1] - 1;
        }
          
        // Calculate line cost corresponding to 
        // the above calculated extra spaces. The
        // value lc[i][j] indicates cost of 
        // putting words from word number i to 
        // j in a single line
        for (int i = 1; i <= n; i++)
        {
            for (int j = i; j <= n; j++)
            {
                if (extras[i,j] < 0)
                    lc[i,j] = MAX;
                else if (j == n && 
                              extras[i,j] >= 0)
                    lc[i,j] = 0;
                else
                    lc[i,j] = extras[i,j]
                                 * extras[i,j];
            }
        }
          
        // Calculate minimum cost and find 
        // minimum cost arrangement. The value
        // c[j] indicates optimized cost to
        // arrange words from word number
        // 1 to j.
        c[0] = 0;
        for (int j = 1; j <= n; j++)
        {
            c[j] = MAX;
            for (int i = 1; i <= j; i++)
            {
                if (c[i-1] != MAX && lc[i,j] 
                    != MAX && (c[i-1] + lc[i,j] 
                                       < c[j]))
                {
                    c[j] = c[i-1] + lc[i,j];
                    p[j] = i;
                }
            }
        }
      
        printSolution(p, n);
    }
  
    // Driver code

228
Chapter 19. DP-19 | Word Wrap Problem

    public static void Main()


    {
        int []l = {3, 2, 2, 5};
        int n = l.Length;
        int M = 6;
        solveWordWrap (l, n, M);
    }
}
  
// This code is contributed by nitin mittal.

Output:

Line number 1: From word no. 1 to 1


Line number 2: From word no. 2 to 3
Line number 3: From word no. 4 to 4

Time Complexity: O(n^2)


Auxiliary Space: O(n^2) The auxiliary space used in the above program cane be optimized
to O(n) (See the reference 2 for details)
Word Wrap problem ( Space optimized solution )
References:
http://en.wikipedia.org/wiki/Word_wrap
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/word-wrap-problem-dp-19/

229
Chapter 20

DP-20 | Maximum Length


Chain of Pairs

Maximum Length Chain of Pairs | DP-20 - GeeksforGeeks


You are given n pairs of numbers. In every pair, the first number is always smaller than the
second number. A pair (c, d) can follow another pair (a, b) if b < c. Chain of pairs can
be formed in this fashion. Find the longest chain which can be formed from a given set of
pairs.
Source: Amazon Interview | Set 2
For example, if the given pairs are {{5, 24}, {39, 60}, {15, 28}, {27, 40}, {50, 90} }, then
the longest chain that can be formed is of length 3, and the chain is {{5, 24}, {27, 40}, {50,
90}}
This problem is a variation of standard Longest Increasing Subsequence problem. Following
is a simple two step process.
1) Sort given pairs in increasing order of first (or smaller) element.
2) Now run a modified LIS process where we compare the second element of already finalized
LIS with the first element of new LIS being constructed.
The following code is a slight modification of method 2 of this post.

#include<stdio.h>
#include<stdlib.h>
  
// Structure for a pair
struct pair
{
  int a;
  int b;
};

230
Chapter 20. DP-20 | Maximum Length Chain of Pairs

  
// This function assumes that arr[] is sorted in increasing order
// according the first (or smaller) values in pairs.
int maxChainLength( struct pair arr[], int n)
{
   int i, j, max = 0;
   int *mcl = (int*) malloc ( sizeof( int ) * n );
  
   /* Initialize MCL (max chain length) values for all indexes */
   for ( i = 0; i < n; i++ )
      mcl[i] = 1;
  
   /* Compute optimized chain length values in bottom up manner */
   for ( i = 1; i < n; i++ )
      for ( j = 0; j < i; j++ )
         if ( arr[i].a > arr[j].b && mcl[i] < mcl[j] + 1)
            mcl[i] = mcl[j] + 1;
  
   // mcl[i] now stores the maximum chain length ending with pair i
  
   /* Pick maximum of all MCL values */
   for ( i = 0; i < n; i++ )
      if ( max < mcl[i] )
         max = mcl[i];
  
   /* Free memory to avoid memory leak */
   free( mcl );
  
   return max;
}
  
  
/* Driver program to test above function */
int main()
{
    struct pair arr[] = { {5, 24}, {15, 25},
                          {27, 40}, {50, 60} };
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Length of maximum size chain is %d\n",
           maxChainLength( arr, n ));
    return 0;
}

Java

class Pair{
    int a;
    int b;

231
Chapter 20. DP-20 | Maximum Length Chain of Pairs

      
    public Pair(int a, int b) {
        this.a = a;
        this.b = b;
    }
      
    // This function assumes that arr[] is sorted in increasing order
    // according the first (or smaller) values in pairs.
    static int maxChainLength(Pair arr[], int n)
    {
       int i, j, max = 0;
       int mcl[] = new int[n];
       
       /* Initialize MCL (max chain length) values for all indexes */
       for ( i = 0; i < n; i++ )
          mcl[i] = 1;
       
       /* Compute optimized chain length values in bottom up manner */
       for ( i = 1; i < n; i++ )
          for ( j = 0; j < i; j++ )
             if ( arr[i].a > arr[j].b && mcl[i] < mcl[j] + 1)
                mcl[i] = mcl[j] + 1;
       
       // mcl[i] now stores the maximum chain length ending with pair i
       
       /* Pick maximum of all MCL values */
       for ( i = 0; i < n; i++ )
          if ( max < mcl[i] )
             max = mcl[i];
       
       return max;
    }
  
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        Pair arr[] = new Pair[] {new Pair(5,24), new Pair(15, 25),
                                  new Pair (27, 40), new Pair(50, 60)};
        System.out.println("Length of maximum size chain is " + 
                                  maxChainLength(arr, arr.length));
    }
}

Python3

class Pair(object):
    def __init__(self, a, b):
        self.a = a

232
Chapter 20. DP-20 | Maximum Length Chain of Pairs

        self.b = b
  
# This function assumes that arr[] is sorted in increasing
# order according the first (or smaller) values in pairs.
def maxChainLength(arr, n):
      
    max = 0
  
    # Initialize MCL(max chain length) values for all indices
    mcl = [1 for i in range(n)]
  
    # Compute optimized chain length values in bottom up manner
    for i in range(1, n):
        for j in range(0, i):
            if (arr[i].a > arr[j].b and mcl[i] < mcl[j] + 1):
                mcl[i] = mcl[j] + 1
  
    # mcl[i] now stores the maximum
    # chain length ending with pair i
  
    # Pick maximum of all MCL values
    for i in range(n):
        if (max < mcl[i]):
            max = mcl[i]
  
    return max
  
# Driver program to test above function
arr = [Pair(5, 24), Pair(15, 25), Pair(27, 40), Pair(50, 60)]
  
print('Length of maximum size chain is',
      maxChainLength(arr, len(arr)))
  
# This code is contributed by Soumen Ghosh

C#

// Dynamic C# program to find 


// Maximum Length Chain of Pairs
using System;
  
class Pair {
    int a;
    int b;
      
    public Pair(int a, int b) 
    {
        this.a = a;

233
Chapter 20. DP-20 | Maximum Length Chain of Pairs

        this.b = b;
    }
      
    // This function assumes that arr[] 
    // is sorted in increasing order
    // according the first (or smaller) 
    // values in pairs.
    static int maxChainLength(Pair []arr, int n)
    {
        int i, j, max = 0;
        int []mcl = new int[n];
          
        // Initialize MCL (max chain length)
        // values for all indexes 
        for(i = 0; i < n; i++ )
            mcl[i] = 1;
          
        // Compute optimized chain length 
        // values in bottom up manner 
        for(i = 1; i < n; i++)
            for (j = 0; j < i; j++)
                if(arr[i].a > arr[j].b &&
                   mcl[i] < mcl[j] + 1)
                     
           // mcl[i] now stores the maximum 
          // chain length ending with pair i
          mcl[i] = mcl[j] + 1;
  
        // Pick maximum of all MCL values
        for ( i = 0; i < n; i++ )
            if (max < mcl[i] )
                max = mcl[i];
          
        return max;
    }
  
    // Driver Code
    public static void Main() 
    {
        Pair []arr = new Pair[] {new Pair(5,24), new Pair(15, 25),
                                 new Pair (27, 40), new Pair(50, 60)};
        Console.Write("Length of maximum size chain is " + 
                       maxChainLength(arr, arr.Length));
    }
}
  
// This code is contributed by nitin mittal.

234
Chapter 20. DP-20 | Maximum Length Chain of Pairs

Output:

Length of maximum size chain is 3

Time Complexity: O(n^2) where n is the number of pairs.


The given problem is also a variation of Activity Selection problemand can be solved in
(nLogn) time. To solve it as a activity selection problem, consider the first element of a
pair as start time in activity selection problem, and the second element of pair as end time.
Thanks to Palash for suggesting this approach.
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/maximum-length-chain-of-pairs-dp-20/

235
Chapter 21

DP-21 | Variations of LIS

Variations of LIS | DP-21 - GeeksforGeeks


We have discussed Dynamic Programming solution for Longest Increasing Subsequence prob-
lem in thispost and a O(nLogn) solution in thispost. Following are commonly asked varia-
tions of the standardLIS problem.
1. Building Bridges: Consider a 2-D map with a horizontal river passing through its
center. There are n cities on the southern bank with x-coordinates a(1) … a(n) and n
cities on the northern bank with x-coordinates b(1) … b(n). You want to connect as many
north-south pairs of cities as possible with bridges such that no two bridges cross. When
connecting cities, you can only connect city i on the northern bank to city i on the southern
bank.

8 1 4 3 5 2 6 7

--------------------------------------------

--------------------------------------------
1 2 3 4 5 6 7 8

Source:Dynamic Programming Practice Problems. The link also has well explained solution
for the problem.
2. Maximum Sum Increasing Subsequence: Given an array of n positive integers.
Write a program to find the maximum sum subsequence of the given array such that the
intgers in the subsequence are sorted in increasing order. For example, if input is {1, 101, 2,
3, 100, 4, 5}, then output should be {1, 2, 3, 100}. The solution to this problem has been
published here.
3. The Longest Chain You are given pairs of numbers. In a pair, the first number is
smaller with respect to the second number. Suppose you have two sets (a, b) and (c, d),

236
Chapter 21. DP-21 | Variations of LIS

the second set can follow the first set if b < c. So you can form a long chain in the similar
fashion. Find the longest chain which can be formed. The solution to this problem has been
published here.
4. Box Stacking You are given a set of n types of rectangular 3-D boxes, where the i^th
box has height h(i), width w(i) and depth d(i) (all real numbers). You want to create a
stack of boxes which is as tall as possible, but you can only stack a box on top of another
box if the dimensions of the 2-D base of the lower box are each strictly larger than those of
the 2-D base of the higher box. Of course, you can rotate a box so that any side functions
as its base. It is also allowable to use multiple instances of the same type of box.
Source:Dynamic Programming Practice Problems. The link also has well explained solution
for the problem.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.

Source

https://www.geeksforgeeks.org/variations-of-lis-dp-21/

237
Chapter 22

DP-22 | Box Stacking Problem

Box Stacking Problem | DP-22 - GeeksforGeeks


You are given a set of n types of rectangular 3-D boxes, where the i^th box has height h(i),
width w(i) and depth d(i) (all real numbers). You want to create a stack of boxes which
is as tall as possible, but you can only stack a box on top of another box if the dimensions
of the 2-D base of the lower box are each strictly larger than those of the 2-D base of the
higher box. Of course, you can rotate a box so that any side functions as its base. It is also
allowable to use multiple instances of the same type of box.
Source: http://people.csail.mit.edu/bdean/6.046/dp/. The link also has video for expla-
nation of solution.

238
Chapter 22. DP-22 | Box Stacking Problem

The Box Stacking problem is a variation of LIS problem. We need to build a maximum
height stack.
Following are the key points to note in the problem statement:
1) A box can be placed on top of another box only if both width and depth of the upper
placed box are smaller than width and depth of the lower box respectively.
2) We can rotate boxes such that width is smaller than depth. For example, if there is a box
with dimensions {1x2x3} where 1 is height, 2×3 is base, then there can be three possibilities,
{1x2x3}, {2x1x3} and {3x1x2}
3) We can use multiple instances of boxes. What it means is, we can have two different
rotations of a box as part of our maximum height stack.

239
Chapter 22. DP-22 | Box Stacking Problem

Following is the solution based on DP solution of LIS problem.


1) Generate all 3 rotations of all boxes. The size of rotation array becomes 3 times the size
of original array. For simplicity, we consider depth as always smaller than or equal to width.
2) Sort the above generated 3n boxes in decreasing order of base area.
3) After sorting the boxes, the problem is same as LIS with following optimal substructure
property.
MSH(i) = Maximum possible Stack Height with box i at top of stack
MSH(i) = { Max ( MSH(j) ) + height(i) } where j < i and width(j) > width(i) and depth(j)
> depth(i).
If there is no such j then MSH(i) = height(i)
4) To get overall maximum height, we return max(MSH(i)) where 0 < i < n
Following is the implementation of the above solution.

C++

/* Dynamic Programming implementation of Box Stacking problem */


#include<stdio.h>
#include<stdlib.h>
  
/* Representation of a box */
struct Box
{
  // h --> height, w --> width, d --> depth
  int h, w, d;  // for simplicity of solution, always keep w <= d
};
  
// A utility function to get minimum of two intgers
int min (int x, int y)
{ return (x < y)? x : y; }
  
// A utility function to get maximum of two intgers
int max (int x, int y)
{ return (x > y)? x : y; }
  
/* Following function is needed for library function qsort(). We
   use qsort() to sort boxes in decreasing order of base area. 
   Refer following link for help of qsort() and compare()
   http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/ */
int compare (const void *a, const void * b)
{
    return ( (*(Box *)b).d * (*(Box *)b).w ) -
           ( (*(Box *)a).d * (*(Box *)a).w );
}
  
/* Returns the height of the tallest stack that can be

240
Chapter 22. DP-22 | Box Stacking Problem

   formed with give type of boxes */


int maxStackHeight( Box arr[], int n )
{
   /* Create an array of all rotations of given boxes
      For example, for a box {1, 2, 3}, we consider three
      instances{{1, 2, 3}, {2, 1, 3}, {3, 1, 2}} */
   Box rot[3*n];
   int index = 0;
   for (int i = 0; i < n; i++)
   {
      // Copy the original box
      rot[index].h = arr[i].h;
      rot[index].d = max(arr[i].d, arr[i].w);
      rot[index].w = min(arr[i].d, arr[i].w);
      index++;
  
      // First rotation of box
      rot[index].h = arr[i].w;
      rot[index].d = max(arr[i].h, arr[i].d);
      rot[index].w = min(arr[i].h, arr[i].d);
      index++;
  
      // Second rotation of box
      rot[index].h = arr[i].d;
      rot[index].d = max(arr[i].h, arr[i].w);
      rot[index].w = min(arr[i].h, arr[i].w);
      index++;
   }
  
   // Now the number of boxes is 3n
   n = 3*n;
  
   /* Sort the array 'rot[]' in non-increasing order
      of base area */
   qsort (rot, n, sizeof(rot[0]), compare);
  
   // Uncomment following two lines to print all rotations
   // for (int i = 0; i < n; i++ )
   //    printf("%d x %d x %d\n", rot[i].h, rot[i].w, rot[i].d);
  
   /* Initialize msh values for all indexes 
      msh[i] --> Maximum possible Stack Height with box i on top */
   int msh[n];
   for (int i = 0; i < n; i++ )
      msh[i] = rot[i].h;
  
   /* Compute optimized msh values in bottom up manner */
   for (int i = 1; i < n; i++ )

241
Chapter 22. DP-22 | Box Stacking Problem

      for (int j = 0; j < i; j++ )


         if ( rot[i].w < rot[j].w &&
              rot[i].d < rot[j].d &&
              msh[i] < msh[j] + rot[i].h
            )
         {
              msh[i] = msh[j] + rot[i].h;
         }
  
  
   /* Pick maximum of all msh values */
   int max = -1;
   for ( int i = 0; i < n; i++ )
      if ( max < msh[i] )
         max = msh[i];
  
   return max;
}
  
/* Driver program to test above function */
int main()
{
  Box arr[] = { {4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32} };
  int n = sizeof(arr)/sizeof(arr[0]);
  
  printf("The maximum possible height of stack is %d\n",
         maxStackHeight (arr, n) );
  
  return 0;
}

Java

/* Dynamic Programming implementation 


of Box Stacking problem in Java*/
import java.util.*;
  
public class GFG {
      
    /* Representation of a box */
    static class Box implements Comparable<Box>{
      
        // h --> height, w --> width,
        // d --> depth
        int h, w, d, area;
          
        // for simplicity of solution,
        // always keep w <= d

242
Chapter 22. DP-22 | Box Stacking Problem

  
        /*Constructor to initialise object*/
        public Box(int h, int w, int d) {
            this.h = h;
            this.w = w;
            this.d = d;
        }
          
        /*To sort the box array on the basis
        of area in decreasing order of area */
        @Override
        public int compareTo(Box o) {
            return o.area-this.area;
        }
    }
  
    /* Returns the height of the tallest
    stack that can be formed with give 
    type of boxes */
    static int maxStackHeight( Box arr[], int n){
          
        Box[] rot = new Box[n*3];
          
        /* New Array of boxes is created - 
        considering all 3 possible rotations, 
        with width always greater than equal
        to width */
        for(int i = 0;i < n;i++){
            Box box = arr[i];
              
            /* Orignal Box*/
            rot[3*i] = new Box(box.h, Math.max(box.w,box.d), 
                                    Math.min(box.w,box.d));
              
            /* First rotation of box*/
            rot[3*i + 1] = new Box(box.w, Math.max(box.h,box.d), 
                                       Math.min(box.h,box.d));
              
            /* Second rotation of box*/
            rot[3*i + 2] = new Box(box.d, Math.max(box.w,box.h),
                                       Math.min(box.w,box.h));
        }
          
        /* Calculating base area of 
        each of the boxes.*/
        for(int i = 0; i < rot.length; i++)
            rot[i].area = rot[i].w * rot[i].d;
          

243
Chapter 22. DP-22 | Box Stacking Problem

        /* Sorting the Boxes on the bases 


        of Area in non Increasing order.*/
        Arrays.sort(rot);
          
        int count = 3 * n;
          
        /* Initialize msh values for all 
        indexes 
        msh[i] --> Maximum possible Stack Height
                   with box i on top */
        int[]msh = new int[count];
        for (int i = 0; i < count; i++ )
            msh[i] = rot[i].h;
          
        /* Computing optimized msh[] 
        values in bottom up manner */
        for(int i = 0; i < count; i++){
            msh[i] = 0;
            Box box = rot[i];
            int val = 0;
              
            for(int j = 0; j < i; j++){
                Box prevBox = rot[j];
                if(box.w < prevBox.w && box.d < prevBox.d){
                    val = Math.max(val, msh[j]);
                }
            }
            msh[i] = val + box.h;
        }
          
        int max = -1;
          
        /* Pick maximum of all msh values */
        for(int i = 0; i < count; i++){
            max = Math.max(max, msh[i]);
        }
          
        return max;
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) {
          
        Box[] arr = new Box[4];
        arr[0] = new Box(4, 6, 7);
        arr[1] = new Box(1, 2, 3);
        arr[2] = new Box(4, 5, 6);
        arr[3] = new Box(10, 12, 32);

244
Chapter 22. DP-22 | Box Stacking Problem

          
        System.out.println("The maximum possible "+
                           "height of stack is " + 
                           maxStackHeight(arr,4));
    }
}
  
// This code is contributed by Divyam 

Output:

The maximum possible height of stack is 60

In the above program, given input boxes are {4, 6, 7}, {1, 2, 3}, {4, 5, 6}, {10, 12, 32}.
Following are all rotations of the boxes in decreasing order of base area.

10 x 12 x 32
12 x 10 x 32
32 x 10 x 12
4 x 6 x 7
4 x 5 x 6
6 x 4 x 7
5 x 4 x 6
7 x 4 x 6
6 x 4 x 5
1 x 2 x 3
2 x 1 x 3
3 x 1 x 2

The height 60 is obtained by boxes { {3, 1, 2}, {1, 2, 3}, {6, 4, 5}, {4, 5, 6}, {4, 6, 7}, {32,
10, 12}, {10, 12, 32}}
Time Complexity: O(n^2)
Auxiliary Space: O(n)

Source

https://www.geeksforgeeks.org/box-stacking-problem-dp-22/

245
Chapter 23

DP-23 | Bellman–Ford
Algorithm

Bellman–Ford Algorithm | DP-23 - GeeksforGeeks


Given a graph and a source vertex src in graph, find shortest paths from src to all vertices
in the given graph. The graph may contain negative weight edges.
We have discussed Dijkstra’s algorithm for this problem. Dijksra’s algorithm is a Greedy
algorithm and time complexity is O(VLogV) (with the use of Fibonacci heap). Dijkstra
doesn’t work for Graphs with negative weight edges, Bellman-Ford works for such graphs.
Bellman-Ford is also simpler than Dijkstra and suites well for distributed systems. But time
complexity of Bellman-Ford is O(VE), which is more than Dijkstra.
Algorithm
Following are the detailed steps.
Input: Graph and a source vertex src
Output: Shortest distance to all vertices from src. If there is a negative weight cycle, then
shortest distances are not calculated, negative weight cycle is reported.
1) This step initializes distances from source to all vertices as infinite and distance to source
itself as 0. Create an array dist[] of size |V| with all values as infinite except dist[src] where
src is source vertex.
2) This step calculates shortest distances. Do following |V|-1 times where |V| is the number
of vertices in given graph.
…..a) Do following for each edge u-v
………………If dist[v] > dist[u] + weight of edge uv, then update dist[v]
………………….dist[v] = dist[u] + weight of edge uv
3) This step reports if there is a negative weight cycle in graph. Do following for each edge
u-v
……If dist[v] > dist[u] + weight of edge uv, then “Graph contains negative weight cycle”
The idea of step 3 is, step 2 guarantees shortest distances if graph doesn’t contain negative
weight cycle. If we iterate through all edges one more time and get a shorter path for any
vertex, then there is a negative weight cycle

246
Chapter 23. DP-23 | Bellman–Ford Algorithm

How does this work? Like other Dynamic Programming Problems, the algorithm calcu-
late shortest paths in bottom-up manner. It first calculates the shortest distances which
have at-most one edge in the path. Then, it calculates shortest paths with at-most 2 edges,
and so on. After the i-th iteration of outer loop, the shortest paths with at most i edges
are calculated. There can be maximum |V| – 1 edges in any simple path, that is why the
outer loop runs |v| – 1 times. The idea is, assuming that there is no negative weight cycle,
if we have calculated shortest paths with at most i edges, then an iteration over all edges
guarantees to give shortest path with at-most (i+1) edges (Proof is simple, you can refer
this or MIT Video Lecture)
Example
Let us understand the algorithm with following example graph. The images are taken from
thissource.
Let the given source vertex be 0. Initialize all distances as infinite, except the distance to
source itself. Total number of vertices in the graph is 5, so all edges must be processed 4
times.

Let all edges are processed in following order: (B,E), (D,B), (B,D), (A,B), (A,C), (D,C),
(B,C), (E,D). We get following distances when all edges are processed first time. The first
row in shows initial distances. The second row shows distances when edges (B,E), (D,B),
(B,D) and (A,B) are processed. The third row shows distances when (A,C) is processed.
The fourth row shows when (D,C), (B,C) and (E,D) are processed.

247
Chapter 23. DP-23 | Bellman–Ford Algorithm

The first iteration guarantees to give all shortest paths which are at most 1 edge long. We
get following distances when all edges are processed second time (The last row shows final
values).

The second iteration guarantees to give all shortest paths which are at most 2 edges long.
The algorithm processes all edges 2 more times. The distances are minimized after the
second iteration, so third and fourth iterations don’t update the distances.
Implementation:

C++

248
Chapter 23. DP-23 | Bellman–Ford Algorithm

// A C++ program for Bellman-Ford's single source 


// shortest path algorithm.
#include <bits/stdc++.h>
  
// a structure to represent a weighted edge in graph
struct Edge
{
    int src, dest, weight;
};
  
// a structure to represent a connected, directed and 
// weighted graph
struct Graph
{
    // V-> Number of vertices, E-> Number of edges
    int V, E;
  
    // graph is represented as an array of edges.
    struct Edge* edge;
};
  
// Creates a graph with V vertices and E edges
struct Graph* createGraph(int V, int E)
{
    struct Graph* graph = new Graph;
    graph->V = V;
    graph->E = E;
    graph->edge = new Edge[E];
    return graph;
}
  
// A utility function used to print the solution
void printArr(int dist[], int n)
{
    printf("Vertex   Distance from Source\n");
    for (int i = 0; i < n; ++i)
        printf("%d \t\t %d\n", i, dist[i]);
}
  
// The main function that finds shortest distances from src to
// all other vertices using Bellman-Ford algorithm.  The function
// also detects negative weight cycle
void BellmanFord(struct Graph* graph, int src)
{
    int V = graph->V;
    int E = graph->E;
    int dist[V];
  

249
Chapter 23. DP-23 | Bellman–Ford Algorithm

    // Step 1: Initialize distances from src to all other vertices


    // as INFINITE
    for (int i = 0; i < V; i++)
        dist[i]   = INT_MAX;
    dist[src] = 0;
  
    // Step 2: Relax all edges |V| - 1 times. A simple shortest 
    // path from src to any other vertex can have at-most |V| - 1 
    // edges
    for (int i = 1; i <= V-1; i++)
    {
        for (int j = 0; j < E; j++)
        {
            int u = graph->edge[j].src;
            int v = graph->edge[j].dest;
            int weight = graph->edge[j].weight;
            if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
                dist[v] = dist[u] + weight;
        }
    }
  
    // Step 3: check for negative-weight cycles.  The above step 
    // guarantees shortest distances if graph doesn't contain 
    // negative weight cycle.  If we get a shorter path, then there
    // is a cycle.
    for (int i = 0; i < E; i++)
    {
        int u = graph->edge[i].src;
        int v = graph->edge[i].dest;
        int weight = graph->edge[i].weight;
        if (dist[u] != INT_MAX && dist[u] + weight < dist[v])
            printf("Graph contains negative weight cycle");
    }
  
    printArr(dist, V);
  
    return;
}
  
// Driver program to test above functions
int main()
{
    /* Let us create the graph given in above example */
    int V = 5;  // Number of vertices in graph
    int E = 8;  // Number of edges in graph
    struct Graph* graph = createGraph(V, E);
  
    // add edge 0-1 (or A-B in above figure)

250
Chapter 23. DP-23 | Bellman–Ford Algorithm

    graph->edge[0].src = 0;
    graph->edge[0].dest = 1;
    graph->edge[0].weight = -1;
  
    // add edge 0-2 (or A-C in above figure)
    graph->edge[1].src = 0;
    graph->edge[1].dest = 2;
    graph->edge[1].weight = 4;
  
    // add edge 1-2 (or B-C in above figure)
    graph->edge[2].src = 1;
    graph->edge[2].dest = 2;
    graph->edge[2].weight = 3;
  
    // add edge 1-3 (or B-D in above figure)
    graph->edge[3].src = 1;
    graph->edge[3].dest = 3;
    graph->edge[3].weight = 2;
  
    // add edge 1-4 (or A-E in above figure)
    graph->edge[4].src = 1;
    graph->edge[4].dest = 4;
    graph->edge[4].weight = 2;
  
    // add edge 3-2 (or D-C in above figure)
    graph->edge[5].src = 3;
    graph->edge[5].dest = 2;
    graph->edge[5].weight = 5;
  
    // add edge 3-1 (or D-B in above figure)
    graph->edge[6].src = 3;
    graph->edge[6].dest = 1;
    graph->edge[6].weight = 1;
  
    // add edge 4-3 (or E-D in above figure)
    graph->edge[7].src = 4;
    graph->edge[7].dest = 3;
    graph->edge[7].weight = -3;
  
    BellmanFord(graph, 0);
  
    return 0;
}

Java

// A Java program for Bellman-Ford's single source shortest path


// algorithm.

251
Chapter 23. DP-23 | Bellman–Ford Algorithm

import java.util.*;
import java.lang.*;
import java.io.*;
  
// A class to represent a connected, directed and weighted graph
class Graph
{
    // A class to represent a weighted edge in graph
    class Edge {
        int src, dest, weight;
        Edge() {
            src = dest = weight = 0;
        }
    };
  
    int V, E;
    Edge edge[];
  
    // Creates a graph with V vertices and E edges
    Graph(int v, int e)
    {
        V = v;
        E = e;
        edge = new Edge[e];
        for (int i=0; i<e; ++i)
            edge[i] = new Edge();
    }
  
    // The main function that finds shortest distances from src
    // to all other vertices using Bellman-Ford algorithm.  The
    // function also detects negative weight cycle
    void BellmanFord(Graph graph,int src)
    {
        int V = graph.V, E = graph.E;
        int dist[] = new int[V];
  
        // Step 1: Initialize distances from src to all other
        // vertices as INFINITE
        for (int i=0; i<V; ++i)
            dist[i] = Integer.MAX_VALUE;
        dist[src] = 0;
  
        // Step 2: Relax all edges |V| - 1 times. A simple
        // shortest path from src to any other vertex can
        // have at-most |V| - 1 edges
        for (int i=1; i<V; ++i)
        {
            for (int j=0; j<E; ++j)

252
Chapter 23. DP-23 | Bellman–Ford Algorithm

            {
                int u = graph.edge[j].src;
                int v = graph.edge[j].dest;
                int weight = graph.edge[j].weight;
                if (dist[u]!=Integer.MAX_VALUE &&
                    dist[u]+weight<dist[v])
                    dist[v]=dist[u]+weight;
            }
        }
  
        // Step 3: check for negative-weight cycles.  The above
        // step guarantees shortest distances if graph doesn't
        // contain negative weight cycle. If we get a shorter
        //  path, then there is a cycle.
        for (int j=0; j<E; ++j)
        {
            int u = graph.edge[j].src;
            int v = graph.edge[j].dest;
            int weight = graph.edge[j].weight;
            if (dist[u] != Integer.MAX_VALUE &&
                dist[u]+weight < dist[v])
              System.out.println("Graph contains negative weight cycle");
        }
        printArr(dist, V);
    }
  
    // A utility function used to print the solution
    void printArr(int dist[], int V)
    {
        System.out.println("Vertex   Distance from Source");
        for (int i=0; i<V; ++i)
            System.out.println(i+"\t\t"+dist[i]);
    }
  
    // Driver method to test above function
    public static void main(String[] args)
    {
        int V = 5;  // Number of vertices in graph
        int E = 8;  // Number of edges in graph
  
        Graph graph = new Graph(V, E);
  
        // add edge 0-1 (or A-B in above figure)
        graph.edge[0].src = 0;
        graph.edge[0].dest = 1;
        graph.edge[0].weight = -1;
  
        // add edge 0-2 (or A-C in above figure)

253
Chapter 23. DP-23 | Bellman–Ford Algorithm

        graph.edge[1].src = 0;
        graph.edge[1].dest = 2;
        graph.edge[1].weight = 4;
  
        // add edge 1-2 (or B-C in above figure)
        graph.edge[2].src = 1;
        graph.edge[2].dest = 2;
        graph.edge[2].weight = 3;
  
        // add edge 1-3 (or B-D in above figure)
        graph.edge[3].src = 1;
        graph.edge[3].dest = 3;
        graph.edge[3].weight = 2;
  
        // add edge 1-4 (or A-E in above figure)
        graph.edge[4].src = 1;
        graph.edge[4].dest = 4;
        graph.edge[4].weight = 2;
  
        // add edge 3-2 (or D-C in above figure)
        graph.edge[5].src = 3;
        graph.edge[5].dest = 2;
        graph.edge[5].weight = 5;
  
        // add edge 3-1 (or D-B in above figure)
        graph.edge[6].src = 3;
        graph.edge[6].dest = 1;
        graph.edge[6].weight = 1;
  
        // add edge 4-3 (or E-D in above figure)
        graph.edge[7].src = 4;
        graph.edge[7].dest = 3;
        graph.edge[7].weight = -3;
  
        graph.BellmanFord(graph, 0);
    }
}
// Contributed by Aakash Hasija

Python

# Python program for Bellman-Ford's single source 


# shortest path algorithm.
  
from collections import defaultdict
  
#Class to represent a graph
class Graph:

254
Chapter 23. DP-23 | Bellman–Ford Algorithm

  
    def __init__(self,vertices):
        self.V= vertices #No. of vertices
        self.graph = [] # default dictionary to store graph
   
    # function to add an edge to graph
    def addEdge(self,u,v,w):
        self.graph.append([u, v, w])
          
    # utility function used to print the solution
    def printArr(self, dist):
        print("Vertex   Distance from Source")
        for i in range(self.V):
            print("%d \t\t %d" % (i, dist[i]))
      
    # The main function that finds shortest distances from src to
    # all other vertices using Bellman-Ford algorithm.  The function
    # also detects negative weight cycle
    def BellmanFord(self, src):
  
        # Step 1: Initialize distances from src to all other vertices
        # as INFINITE
        dist = [float("Inf")] * self.V
        dist[src] = 0 
  
  
        # Step 2: Relax all edges |V| - 1 times. A simple shortest 
        # path from src to any other vertex can have at-most |V| - 1 
        # edges
        for i in range(self.V - 1):
            # Update dist value and parent index of the adjacent vertices of
            # the picked vertex. Consider only those vertices which are still in
            # queue
            for u, v, w in self.graph:
                if dist[u] != float("Inf") and dist[u] + w < dist[v]:
                        dist[v] = dist[u] + w
  
        # Step 3: check for negative-weight cycles.  The above step 
        # guarantees shortest distances if graph doesn't contain 
        # negative weight cycle.  If we get a shorter path, then there
        # is a cycle.
  
        for u, v, w in self.graph:
                if dist[u] != float("Inf") and dist[u] + w < dist[v]:
                        print "Graph contains negative weight cycle"
                        return
                          
        # print all distance

255
Chapter 23. DP-23 | Bellman–Ford Algorithm

        self.printArr(dist)
  
g = Graph(5)
g.addEdge(0, 1, -1)
g.addEdge(0, 2, 4)
g.addEdge(1, 2, 3)
g.addEdge(1, 3, 2)
g.addEdge(1, 4, 2)
g.addEdge(3, 2, 5)
g.addEdge(3, 1, 1)
g.addEdge(4, 3, -3)
  
#Print the solution
g.BellmanFord(0)
  
#This code is contributed by Neelam Yadav

Output:

Vertex Distance from Source


0 0
1 -1
2 2
3 -2
4 1

Notes
1) Negative weights are found in various applications of graphs. For example, instead of
paying cost for a path, we may get some advantage if we follow the path.
2) Bellman-Ford works better (better than Dijksra’s) for distributed systems. Unlike Di-
jksra’s where we need to find minimum value of all vertices, in Bellman-Ford, edges are
considered one by one.
Exercise
1) The standard Bellman-Ford algorithm reports shortest path only if there is no negative
weight cycles. Modify it so that it reports minimum distances even if there is a negative
weight cycle.
2) Can we use Dijksra’s algorithm for shortest paths for graphs with negative weights – one
idea can be, calculate the minimum weight value, add a positive value (equal to absolute
value of minimum weight value) to all weights and run the Dijksra’s algorithm for the
modified graph. Will this algorithm work?
References:
http://www.youtube.com/watch?v=Ttezuzs39nk
http://en.wikipedia.org/wiki/Bellman%E2%80%93Ford_algorithm
http://www.cs.arizona.edu/classes/cs445/spring07/ShortestPath2.prn.pdf

256
Chapter 23. DP-23 | Bellman–Ford Algorithm

Source

https://www.geeksforgeeks.org/bellman-ford-algorithm-dp-23/

257
Chapter 24

DP-24 | Optimal Binary Search


Tree

Optimal Binary Search Tree | DP-24 - GeeksforGeeks


Given a sorted array keys[0.. n-1] of search keys and an array freq[0.. n-1] of frequency
counts, where freq[i] is the number of searches to keys[i]. Construct a binary search tree of
all keys such that the total cost of all the searches is as small as possible.
Let us first define the cost of a BST. The cost of a BST node is level of that node multiplied
by its frequency. Level of root is 1.

Example 1
Input: keys[] = {10, 12}, freq[] = {34, 50}
There can be following two possible BSTs
10 12
\ /
12 10
I II
Frequency of searches of 10 and 12 are 34 and 50 respectively.
The cost of tree I is 34*1 + 50*2 = 134
The cost of tree II is 50*1 + 34*2 = 118

Example 2
Input: keys[] = {10, 12, 20}, freq[] = {34, 8, 50}
There can be following possible BSTs
10 12 20 10 20
\ / \ / \ /
12 10 20 12 20 10
\ / / \
20 10 12 12
I II III IV V

258
Chapter 24. DP-24 | Optimal Binary Search Tree

Among all possible BSTs, cost of the fifth BST is minimum.


Cost of the fifth BST is 1*50 + 2*34 + 3*8 = 142

1) Optimal Substructure:
The optimal cost for freq[i..j] can be recursively calculated using following formula.

We need to calculate optCost(0, n-1) to find the result.


The idea of above formula is simple, we one by one try all nodes as root (r varies from i to
j in second term). When we make rth node as root, we recursively calculate optimal cost
from i to r-1 and r+1 to j.
We add sum of frequencies from i to j (see first term in the above formula), this is added
because every search will go through root and one comparison will be done for every search.
2) Overlapping Subproblems
Following is recursive implementation that simply follows the recursive structure mentioned
above.

C/C++

// A naive recursive implementation of optimal binary 


// search tree problem
#include <stdio.h>
#include <limits.h>
  
// A utility function to get sum of array elements 
// freq[i] to freq[j]
int sum(int freq[], int i, int j);
  
// A recursive function to calculate cost of optimal 
// binary search tree
int optCost(int freq[], int i, int j)
{
   // Base cases
   if (j < i)      // no elements in this subarray
     return 0;
   if (j == i)     // one element in this subarray
     return freq[i];
  
   // Get sum of freq[i], freq[i+1], ... freq[j]
   int fsum = sum(freq, i, j);
  
   // Initialize minimum value
   int min = INT_MAX;
  
   // One by one consider all elements as root and

259
Chapter 24. DP-24 | Optimal Binary Search Tree

   // recursively find cost of the BST, compare the


   // cost with min and update min if needed
   for (int r = i; r <= j; ++r)
   {
       int cost = optCost(freq, i, r-1) + 
                  optCost(freq, r+1, j);
       if (cost < min)
          min = cost;
   }
  
   // Return minimum value
   return min + fsum;
}
  
// The main function that calculates minimum cost of
// a Binary Search Tree. It mainly uses optCost() to 
// find the optimal cost.
int optimalSearchTree(int keys[], int freq[], int n)
{
     // Here array keys[] is assumed to be sorted in 
     // increasing order. If keys[] is not sorted, then 
     // add code to sort keys, and rearrange freq[] 
     // accordingly.
     return optCost(freq, 0, n-1);
}
  
// A utility function to get sum of array elements 
// freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
    int s = 0;
    for (int k = i; k <=j; k++)
       s += freq[k];
    return s;
}
  
// Driver program to test above functions
int main()
{
    int keys[] = {10, 12, 20};
    int freq[] = {34, 8, 50};
    int n = sizeof(keys)/sizeof(keys[0]);
    printf("Cost of Optimal BST is %d ", 
               optimalSearchTree(keys, freq, n));
    return 0;
}

Java

260
Chapter 24. DP-24 | Optimal Binary Search Tree

// A naive recursive implementation of optimal binary 


// search tree problem
public class GFG 
{
    // A recursive function to calculate cost of
        // optimal binary search tree
    static int optCost(int freq[], int i, int j)
    {
       // Base cases
       if (j < i)      // no elements in this subarray
         return 0;
       if (j == i)     // one element in this subarray
         return freq[i];
       
       // Get sum of freq[i], freq[i+1], ... freq[j]
       int fsum = sum(freq, i, j);
       
       // Initialize minimum value
       int min = Integer.MAX_VALUE;
       
       // One by one consider all elements as root and 
           // recursively find cost of the BST, compare the 
           // cost with min and update min if needed
       for (int r = i; r <= j; ++r)
       {
           int cost = optCost(freq, i, r-1) + 
                          optCost(freq, r+1, j);
           if (cost < min)
              min = cost;
       }
       
       // Return minimum value
       return min + fsum;
    }
      
    // The main function that calculates minimum cost of
        // a Binary Search Tree. It mainly uses optCost() to
        // find the optimal cost.
    static int optimalSearchTree(int keys[], int freq[], int n)
    {
         // Here array keys[] is assumed to be sorted in 
             // increasing order. If keys[] is not sorted, then
             // add code to sort keys, and rearrange freq[] 
             // accordingly.
         return optCost(freq, 0, n-1);
    }
      
    // A utility function to get sum of array elements 

261
Chapter 24. DP-24 | Optimal Binary Search Tree

        // freq[i] to freq[j]


    static int sum(int freq[], int i, int j)
    {
        int s = 0;
        for (int k = i; k <=j; k++)
           s += freq[k];
        return s;
    }
      
    // Driver code
    public static void main(String[] args) {
        int keys[] = {10, 12, 20};
        int freq[] = {34, 8, 50};
        int n = keys.length;
        System.out.println("Cost of Optimal BST is " +
                         optimalSearchTree(keys, freq, n));
    }
}
// This code is contributed by Sumit Ghosh

C#

// A naive recursive implementation of optimal binary 


// search tree problem
using System;
  
class GFG
{
    // A recursive function to calculate cost of
    // optimal binary search tree
    static int optCost(int []freq, int i, int j)
    {
          
    // Base cases
    // no elements in this subarray
    if (j < i)     
        return 0;
      
    // one element in this subarray    
    if (j == i)     
        return freq[i];
      
    // Get sum of freq[i], freq[i+1], ... freq[j]
    int fsum = sum(freq, i, j);
      
    // Initialize minimum value
    int min = int.MaxValue;
      

262
Chapter 24. DP-24 | Optimal Binary Search Tree

    // One by one consider all elements as root and 


    // recursively find cost of the BST, compare the 
    // cost with min and update min if needed
    for (int r = i; r <= j; ++r)
    {
        int cost = optCost(freq, i, r-1) + 
                        optCost(freq, r+1, j);
        if (cost < min)
            min = cost;
    }
      
    // Return minimum value
    return min + fsum;
    }
      
    // The main function that calculates minimum cost of
    // a Binary Search Tree. It mainly uses optCost() to
    // find the optimal cost.
    static int optimalSearchTree(int []keys, int []freq, int n)
    {
        // Here array keys[] is assumed to be sorted in 
        // increasing order. If keys[] is not sorted, then
        // add code to sort keys, and rearrange freq[] 
        // accordingly.
        return optCost(freq, 0, n-1);
    }
      
    // A utility function to get sum of array elements 
    // freq[i] to freq[j]
    static int sum(int []freq, int i, int j)
    {
        int s = 0;
        for (int k = i; k <=j; k++)
        s += freq[k];
        return s;
    }
      
    // Driver code
    public static void Main() 
    {
        int []keys = {10, 12, 20};
        int []freq = {34, 8, 50};
        int n = keys.Length;
        Console.Write("Cost of Optimal BST is " +
                        optimalSearchTree(keys, freq, n));
    }
}
  

263
Chapter 24. DP-24 | Optimal Binary Search Tree

// This code is contributed by Sam007

Output:

Cost of Optimal BST is 142

Time complexity of the above naive recursive approach is exponential. It should be noted
that the above function computes the same subproblems again and again. We can see many
subproblems being repeated in the following recursion tree for freq[1..4].

Since same suproblems are called again, this problem has Overlapping Subprolems property.
So optimal BST problem has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, recomputations of same
subproblems can be avoided by constructing a temporary array cost[][] in bottom up manner.
Dynamic Programming Solution
Following is C/C++ implementation for optimal BST problem using Dynamic Programming.
We use an auxiliary array cost[n][n] to store the solutions of subproblems. cost[0][n-1] will
hold the final result. The challenge in implementation is, all diagonal values must be filled
first, then the values which lie on the line just above the diagonal. In other words, we must
first fill all cost[i][i] values, then all cost[i][i+1] values, then all cost[i][i+2] values. So how to
fill the 2D array in such manner> The idea used in the implementation is same as Matrix
Chain Multiplication problem, we use a variable ‘L’ for chain length and increment ‘L’, one
by one. We calculate column number ‘j’ using the values of ‘i’ and ‘L’.
C/C++

// Dynamic Programming code for Optimal Binary Search 


// Tree Problem
#include <stdio.h>

264
Chapter 24. DP-24 | Optimal Binary Search Tree

#include <limits.h>
  
// A utility function to get sum of array elements 
// freq[i] to freq[j]
int sum(int freq[], int i, int j);
  
/* A Dynamic Programming based function that calculates
  minimum cost of a Binary Search Tree. */
int optimalSearchTree(int keys[], int freq[], int n)
{
    /* Create an auxiliary 2D matrix to store results 
      of subproblems */
    int cost[n][n];
  
    /* cost[i][j] = Optimal cost of binary search tree
       that can be  formed from keys[i] to keys[j].
       cost[0][n-1] will store the resultant cost */
  
    // For a single key, cost is equal to frequency of the key
    for (int i = 0; i < n; i++)
        cost[i][i] = freq[i];
  
    // Now we need to consider chains of length 2, 3, ... .
    // L is chain length.
    for (int L=2; L<=n; L++)
    {
        // i is row number in cost[][]
        for (int i=0; i<=n-L+1; i++)
        {
            // Get column number j from row number i and 
            // chain length L
            int j = i+L-1;
            cost[i][j] = INT_MAX;
  
            // Try making all keys in interval keys[i..j] as root
            for (int r=i; r<=j; r++)
            {
               // c = cost when keys[r] becomes root of this subtree
               int c = ((r > i)? cost[i][r-1]:0) + 
                       ((r < j)? cost[r+1][j]:0) + 
                       sum(freq, i, j);
               if (c < cost[i][j])
                  cost[i][j] = c;
            }
        }
    }
    return cost[0][n-1];
}

265
Chapter 24. DP-24 | Optimal Binary Search Tree

  
// A utility function to get sum of array elements 
// freq[i] to freq[j]
int sum(int freq[], int i, int j)
{
    int s = 0;
    for (int k = i; k <=j; k++)
       s += freq[k];
    return s;
}
  
// Driver program to test above functions
int main()
{
    int keys[] = {10, 12, 20};
    int freq[] = {34, 8, 50};
    int n = sizeof(keys)/sizeof(keys[0]);
    printf("Cost of Optimal BST is %d ", 
                 optimalSearchTree(keys, freq, n));
    return 0;
}

Java

// Dynamic Programming Java code for Optimal Binary Search


// Tree Problem
public class Optimal_BST2 {
      
    /* A Dynamic Programming based function that calculates
        minimum cost of a Binary Search Tree.  */
    static int optimalSearchTree(int keys[], int freq[], int n) {
  
        /* Create an auxiliary 2D matrix to store results of 
           subproblems */
        int cost[][] = new int[n + 1][n + 1];
  
        /* cost[i][j] = Optimal cost of binary search tree that 
           can be formed from keys[i] to keys[j]. cost[0][n-1] 
           will store the resultant cost */
  
        // For a single key, cost is equal to frequency of the key
        for (int i = 0; i < n; i++)
            cost[i][i] = freq[i];
  
        // Now we need to consider chains of length 2, 3, ... .
        // L is chain length.
        for (int L = 2; L <= n; L++) {
  

266
Chapter 24. DP-24 | Optimal Binary Search Tree

            // i is row number in cost[][]


            for (int i = 0; i <= n - L + 1; i++) {
  
                // Get column number j from row number i and 
                // chain length L
                int j = i + L - 1;
                cost[i][j] = Integer.MAX_VALUE;
  
                // Try making all keys in interval keys[i..j] as root
                for (int r = i; r <= j; r++) {
  
                    // c = cost when keys[r] becomes root of this subtree
                    int c = ((r > i) ? cost[i][r - 1] : 0)
                            + ((r < j) ? cost[r + 1][j] : 0) + sum(freq, i, j);
                    if (c < cost[i][j])
                        cost[i][j] = c;
                }
            }
        }
        return cost[0][n - 1];
    }
  
    // A utility function to get sum of array elements 
    // freq[i] to freq[j]
    static int sum(int freq[], int i, int j) {
        int s = 0;
        for (int k = i; k <= j; k++) {
            if (k >= freq.length)
                continue;
            s += freq[k];
        }
        return s;
    }
  
    public static void main(String[] args) {
          
        int keys[] = { 10, 12, 20 };
        int freq[] = { 34, 8, 50 };
        int n = keys.length;
        System.out.println("Cost of Optimal BST is "
                + optimalSearchTree(keys, freq, n));
    }
  
}
//This code is contributed by Sumit Ghosh

C#

267
Chapter 24. DP-24 | Optimal Binary Search Tree

// Dynamic Programming C# code for Optimal Binary Search


// Tree Problem
using System;
  
class GFG
{
    /* A Dynamic Programming based function that calculates
    minimum cost of a Binary Search Tree. */
    static int optimalSearchTree(int []keys, int []freq, int n) {
  
        /* Create an auxiliary 2D matrix to store results of 
        subproblems */
        int [,]cost = new int[n + 1,n + 1];
  
        /* cost[i][j] = Optimal cost of binary search tree that 
        can be formed from keys[i] to keys[j]. cost[0][n-1] 
        will store the resultant cost */
  
        // For a single key, cost is equal to frequency of the key
        for (int i = 0; i < n; i++)
            cost[i,i] = freq[i];
  
        // Now we need to consider chains of length 2, 3, ... .
        // L is chain length.
        for (int L = 2; L <= n; L++) {
  
            // i is row number in cost[][]
            for (int i = 0; i <= n - L + 1; i++) {
  
                // Get column number j from row number i and 
                // chain length L
                int j = i + L - 1;
                cost[i,j] = int.MaxValue;
  
                // Try making all keys in interval keys[i..j] as root
                for (int r = i; r <= j; r++) {
  
                    // c = cost when keys[r] becomes root of this subtree
                    int c = ((r > i) ? cost[i,r - 1] : 0)
                            + ((r < j) ? cost[r + 1,j] : 0) + sum(freq, i, j);
                    if (c < cost[i,j])
                        cost[i,j] = c;
                }
            }
        }
        return cost[0,n - 1];
    }
  

268
Chapter 24. DP-24 | Optimal Binary Search Tree

    // A utility function to get sum of array elements 


    // freq[i] to freq[j]
    static int sum(int []freq, int i, int j) {
        int s = 0;
        for (int k = i; k <= j; k++) {
            if (k >= freq.Length)
                continue;
            s += freq[k];
        }
        return s;
    }
  
    public static void Main() {
          
        int []keys = { 10, 12, 20 };
        int []freq = { 34, 8, 50 };
        int n = keys.Length;
        Console.Write("Cost of Optimal BST is "
                + optimalSearchTree(keys, freq, n));
    }
}
// This code is contributed by Sam007

Output:

Cost of Optimal BST is 142

Notes
1) The time complexity of the above solution is O(n^4). The time complexity can be easily
reduced to O(n^3) by pre-calculating sum of frequencies instead of calling sum() again and
again.
2) In the above solutions, we have computed optimal cost only. The solutions can be easily
modified to store the structure of BSTs also. We can create another auxiliary array of size
n to store the structure of tree. All we need to do is, store the chosen ‘r’ in the innermost
loop.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
Improved By : aradhya95

Source

https://www.geeksforgeeks.org/optimal-binary-search-tree-dp-24/

269
Chapter 25

DP-25 | Subset Sum Problem

Dynamic Programming - Subset Sum Problem


Given a set of non-negative integers, and a value sum, determine if there is a subset of the
given set with sum equal to given sum.
Example:

Input: set[] = {3, 34, 4, 12, 5, 2}, sum = 9


Output: True //There is a subset (4, 5) with sum 9.

Let isSubSetSum(int set[], int n, int sum) be the function to find whether there is a subset
of set[] with sum equal to sum. n is the number of elements in set[].
The isSubsetSum problem can be divided into two subproblems
…a) Include the last element, recur for n = n-1, sum = sum – set[n-1]
…b) Exclude the last element, recur for n = n-1.
If any of the above the above subproblems return true, then return true.
Following is the recursive formula for isSubsetSum() problem.

isSubsetSum(set, n, sum) = isSubsetSum(set, n-1, sum) ||


isSubsetSum(set, n-1, sum-set[n-1])
Base Cases:
isSubsetSum(set, n, sum) = false, if sum > 0 and n == 0
isSubsetSum(set, n, sum) = true, if sum == 0

270
Chapter 25. DP-25 | Subset Sum Problem

Following is naive recursive implementation that simply follows the recursive structure
mentioned above.

// A recursive solution for subset sum problem


#include <stdio.h>
  
// Returns true if there is a subset of set[] with sun equal to given sum
bool isSubsetSum(int set[], int n, int sum)
{
   // Base Cases
   if (sum == 0)
     return true;
   if (n == 0 && sum != 0)
     return false;
  
   // If last element is greater than sum, then ignore it
   if (set[n-1] > sum)
     return isSubsetSum(set, n-1, sum);
  
   /* else, check if sum can be obtained by any of the following
      (a) including the last element
      (b) excluding the last element   */
   return isSubsetSum(set, n-1, sum) || 
                        isSubsetSum(set, n-1, sum-set[n-1]);
}
  
// Driver program to test above function
int main()
{
  int set[] = {3, 34, 4, 12, 5, 2};
  int sum = 9;
  int n = sizeof(set)/sizeof(set[0]);

271
Chapter 25. DP-25 | Subset Sum Problem

  if (isSubsetSum(set, n, sum) == true)


     printf("Found a subset with given sum");
  else
     printf("No subset with given sum");
  return 0;
}

Java

// A recursive solution for subset sum


// problem
class GFG {
      
    // Returns true if there is a subset
    // of set[] with sum equal to given sum
    static boolean isSubsetSum(int set[],
                            int n, int sum)
    {
        // Base Cases
        if (sum == 0)
            return true;
        if (n == 0 && sum != 0)
            return false;
          
        // If last element is greater than 
        // sum, then ignore it
        if (set[n-1] > sum)
            return isSubsetSum(set, n-1, sum);
          
        /* else, check if sum can be obtained 
        by any of the following
            (a) including the last element
            (b) excluding the last element */
        return isSubsetSum(set, n-1, sum) || 
            isSubsetSum(set, n-1, sum-set[n-1]);
    }
      
    /* Driver program to test above function */
    public static void main (String args[])
    {
        int set[] = {3, 34, 4, 12, 5, 2};
        int sum = 9;
        int n = set.length;
        if (isSubsetSum(set, n, sum) == true)
            System.out.println("Found a subset"
                          + " with given sum");
        else
            System.out.println("No subset with"

272
Chapter 25. DP-25 | Subset Sum Problem

                               + " given sum");


    }
}
  
/* This code is contributed by Rajat Mishra */

Python3

# A recursive solution for subset sum


# problem
  
# Returns true if there is a subset 
# of set[] with sun equal to given sum
def isSubsetSum(set,n, sum) :
    
    # Base Cases
    if (sum == 0) :
        return True
    if (n == 0 and sum != 0) :
        return False
   
    # If last element is greater than
    # sum, then ignore it
    if (set[n - 1] > sum) :
        return isSubsetSum(set, n - 1, sum);
   
    # else, check if sum can be obtained
    # by any of the following
    # (a) including the last element
    # (b) excluding the last element   
    return isSubsetSum(set, n-1, sum) or isSubsetSum(set, n-1, sum-set[n-1])
      
      
# Driver program to test above function
set = [3, 34, 4, 12, 5, 2]
sum = 9
n = len(set)
if (isSubsetSum(set, n, sum) == True) :
    print("Found a subset with given sum")
else :
    print("No subset with given sum")
      
# This code is contributed by Nikita Tiwari.

C#

// A recursive solution for subset sum problem

273
Chapter 25. DP-25 | Subset Sum Problem

using System;
  
class GFG
{
    // Returns true if there is a subset of set[] with sum
    // equal to given sum
    static bool isSubsetSum(int []set, int n, int sum)
    {
        // Base Cases
        if (sum == 0)
            return true;
        if (n == 0 && sum != 0)
            return false;
          
        // If last element is greater than sum, 
        // then ignore it
        if (set[n-1] > sum)
            return isSubsetSum(set, n-1, sum);
          
        /* else, check if sum can be obtained 
        by any of the following
        (a) including the last element
        (b) excluding the last element */
        return isSubsetSum(set, n-1, sum) || 
                       isSubsetSum(set, n-1, sum-set[n-1]);
    }
      
    // Driver program 
    public static void Main ()
    {
        int []set = {3, 34, 4, 12, 5, 2};
        int sum = 9;
        int n = set.Length;
        if (isSubsetSum(set, n, sum) == true)
            Console.WriteLine("Found a subset with given sum");
        else
            Console.WriteLine("No subset with given sum");
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// A recursive solution for subset sum problem
  
// Returns true if there is a subset of set

274
Chapter 25. DP-25 | Subset Sum Problem

// with sun equal to given sum


function isSubsetSum($set, $n, $sum)
{
    // Base Cases
    if ($sum == 0)
        return true;
    if ($n == 0 && $sum != 0)
        return false;
      
    // If last element is greater
    // than sum, then ignore it
    if ($set[$n - 1] > $sum)
        return isSubsetSum($set, $n - 1, $sum);
      
    /* else, check if sum can be 
       obtained by any of the following
        (a) including the last element
        (b) excluding the last element */
    return isSubsetSum($set, $n - 1, $sum) || 
        isSubsetSum($set, $n - 1, 
                    $sum - $set[$n - 1]);
}
  
// Driver Code
$set = array(3, 34, 4, 12, 5, 2);
$sum = 9;
$n = 6;
  
if (isSubsetSum($set, $n, $sum) == true)
    echo"Found a subset with given sum";
else
    echo "No subset with given sum";
      
// This code is contributed by Anuj_67 
?>

Output:

Found a subset with given sum

The above solution may try all subsets of given set in worst case. Therefore time complexity
of the above solution is exponential. The problem is in-fact NP-Complete (There is no
known polynomial time solution for this problem).
We can solve the problem in Pseudo-polynomial time using Dynamic program-
ming. We create a boolean 2D table subset[][] and fill it in bottom up manner. The value
of subset[i][j] will be true if there is a subset of set[0..j-1] with sum equal to i., otherwise

275
Chapter 25. DP-25 | Subset Sum Problem

false. Finally, we return subset[sum][n]

// A Dynamic Programming solution for subset sum problem


#include <stdio.h>
   
// Returns true if there is a subset of set[] with sun equal to given sum
bool isSubsetSum(int set[], int n, int sum)
{
    // The value of subset[i][j] will be true if there is a 
    // subset of set[0..j-1] with sum equal to i
    bool subset[n+1][sum+1];
   
    // If sum is 0, then answer is true
    for (int i = 0; i <= n; i++)
      subset[i][0] = true;
   
    // If sum is not 0 and set is empty, then answer is false
    for (int i = 1; i <= sum; i++)
      subset[0][i] = false;
   
     // Fill the subset table in botton up manner
     for (int i = 1; i <= n; i++)
     {
       for (int j = 1; j <= sum; j++)
       {
         if(j<set[i-1])
         subset[i][j] = subset[i-1][j];
         if (j >= set[i-1])
           subset[i][j] = subset[i-1][j] || 
                                 subset[i - 1][j-set[i-1]];
       }
     }
   
     /*   // uncomment this code to print table
     for (int i = 0; i <= n; i++)
     {
       for (int j = 0; j <= sum; j++)
          printf ("%4d", subset[i][j]);
       printf("n");
     }*/
   
     return subset[n][sum];
}
   
// Driver program to test above function
int main()

276
Chapter 25. DP-25 | Subset Sum Problem

{
  int set[] = {3, 34, 4, 12, 5, 2};
  int sum = 9;
  int n = sizeof(set)/sizeof(set[0]);
  if (isSubsetSum(set, n, sum) == true)
     printf("Found a subset with given sum");
  else
     printf("No subset with given sum");
  return 0;
}
// This code is contributed by Arjun Tyagi.

Java

// A Dynamic Programming solution for subset


// sum problem
class GFG {
      
    // Returns true if there is a subset of 
    // set[] with sun equal to given sum
    static boolean isSubsetSum(int set[], 
                             int n, int sum)
    {
        // The value of subset[i][j] will be
        // true if there is a subset of 
        // set[0..j-1] with sum equal to i
        boolean subset[][] = 
                     new boolean[sum+1][n+1];
      
        // If sum is 0, then answer is true
        for (int i = 0; i <= n; i++)
            subset[0][i] = true;
      
        // If sum is not 0 and set is empty,
        // then answer is false
        for (int i = 1; i <= sum; i++)
            subset[i][0] = false;
      
        // Fill the subset table in botton
        // up manner
        for (int i = 1; i <= sum; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                subset[i][j] = subset[i][j-1];
                if (i >= set[j-1])
                subset[i][j] = subset[i][j] || 
                     subset[i - set[j-1]][j-1];

277
Chapter 25. DP-25 | Subset Sum Problem

            }
        }
      
        /* // uncomment this code to print table
        for (int i = 0; i <= sum; i++)
        {
        for (int j = 0; j <= n; j++)
            System.out.println (subset[i][j]);
        } */
      
        return subset[sum][n];
    }
  
    /* Driver program to test above function */
    public static void main (String args[])
    {
        int set[] = {3, 34, 4, 12, 5, 2};
        int sum = 9;
        int n = set.length;
        if (isSubsetSum(set, n, sum) == true)
            System.out.println("Found a subset"
                          + " with given sum");
        else
            System.out.println("No subset with"
                               + " given sum");
    }
}
  
/* This code is contributed by Rajat Mishra */

C#

// A Dynamic Programming solution for subset sum problem


using System;
  
class GFG
{
    // Returns true if there is a subset 
    // of set[] with sun equal to given sum
    static bool isSubsetSum(int []set, int n, int sum)
    {
        // The value of subset[i][j] will be true if there 
        // is a subset of set[0..j-1] with sum equal to i
        bool [,]subset = new bool[sum+1,n+1];
      
        // If sum is 0, then answer is true
        for (int i = 0; i <= n; i++)
        subset[0, i] = true;

278
Chapter 25. DP-25 | Subset Sum Problem

      
        // If sum is not 0 and set is empty, then answer is false
        for (int i = 1; i <= sum; i++)
        subset[i, 0] = false;
      
        // Fill the subset table in botton up manner
        for (int i = 1; i <= sum; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                subset[i, j] = subset[i, j - 1];
                if (i >= set[j - 1])
                subset[i, j] = subset[i, j] || 
                               subset[i - set[j - 1], j - 1];
                                              
            }
        }
      
        return subset[sum,n];
    }
      
    // Driver program 
    public static void Main ()
    {
        int []set = {3, 34, 4, 12, 5, 2};
        int sum = 9;
        int n = set.Length;
        if (isSubsetSum(set, n, sum) == true)
            Console.WriteLine("Found a subset with given sum");
        else
            Console.WriteLine("No subset with given sum");
    }
}
// This code is contributed by Sam007

PHP

<?php
// A Dynamic Programming solution for 
// subset sum problem
  
// Returns true if there is a subset of
// set[] with sun equal to given sum
function isSubsetSum( $set, $n, $sum)
{
    // The value of subset[i][j] will
    // be true if there is a subset of
    // set[0..j-1] with sum equal to i

279
Chapter 25. DP-25 | Subset Sum Problem

    $subset = array(array());
  
    // If sum is 0, then answer is true
    for ( $i = 0; $i <= $n; $i++)
        $subset[$i][0] = true;
  
    // If sum is not 0 and set is empty,
    // then answer is false
    for ( $i = 1; $i <= $sum; $i++)
        $subset[0][$i] = false;
  
    // Fill the subset table in botton
    // up manner
    for ($i = 1; $i <= $n; $i++)
    {
        for ($j = 1; $j <= $sum; $j++)
        {
            if($j < $set[$i-1])
                $subset[$i][$j] = 
                      $subset[$i-1][$j];
            if ($j >= $set[$i-1])
                $subset[$i][$j] = 
                       $subset[$i-1][$j] || 
                       $subset[$i - 1][$j - 
                               $set[$i-1]];
        }
    }
  
    /* // uncomment this code to print table
    for (int i = 0; i <= n; i++)
    {
    for (int j = 0; j <= sum; j++)
        printf ("%4d", subset[i][j]);
    printf("n");
    }*/
  
    return $subset[$n][$sum];
}
  
// Driver program to test above function
$set = array(3, 34, 4, 12, 5, 2);
$sum = 9;
$n = count($set);
  
if (isSubsetSum($set, $n, $sum) == true)
    echo "Found a subset with given sum";
else
    echo "No subset with given sum";

280
Chapter 25. DP-25 | Subset Sum Problem

  
// This code is contributed by anuj_67.
?>

Output:

Found a subset with given sum

Time complexity of the above solution is O(sum*n).Subset Sum Problem in O(sum) space
Perfect Sum Problem (Print all subsets with given sum)
Improved By : vt_m

Source

https://www.geeksforgeeks.org/subset-sum-problem-dp-25/

281
Chapter 26

DP-26 | Largest Independent


Set Problem

Largest Independent Set Problem | DP-26 - GeeksforGeeks


Given a Binary Tree, find size of the Largest Independent Set(LIS) in it. A subset of all
tree nodes is an independent set if there is no edge between any two nodes of the subset.
For example, consider the following binary tree. The largest independent set(LIS) is {10,
40, 60, 70, 80} and size of the LIS is 5.

A Dynamic Programming solution solves a given problem using solutions of subproblems in


bottom up manner. Can the given problem be solved using solutions to subproblems? If
yes, then what are the subproblems? Can we find largest independent set size (LISS) for
a node X if we know LISS for all descendants of X? If a node is considered as part of LIS,
then its children cannot be part of LIS, but its grandchildren can be. Following is optimal
substructure property.
1) Optimal Substructure:
Let LISS(X) indicates size of largest independent set of a tree with root X.

282
Chapter 26. DP-26 | Largest Independent Set Problem

LISS(X) = MAX { (1 + sum of LISS for all grandchildren of X),


(sum of LISS for all children of X) }

The idea is simple, there are two possibilities for every node X, either X is a member of
the set or not a member. If X is a member, then the value of LISS(X) is 1 plus LISS of all
grandchildren. If X is not a member, then the value is sum of LISS of all children.
2) Overlapping Subproblems
Following is recursive implementation that simply follows the recursive structure mentioned
above.

// A naive recursive implementation of Largest Independent Set problem


#include <stdio.h>
#include <stdlib.h>
  
// A utility function to find max of two integers
int max(int x, int y) { return (x > y)? x: y; }
  
/* A binary tree node has data, pointer to left child and a pointer to 
   right child */
struct node
{
    int data;
    struct node *left, *right;
};
  
// The function returns size of the largest independent set in a given 
// binary tree
int LISS(struct node *root)
{
    if (root == NULL)
       return 0;
  
    // Caculate size excluding the current node
    int size_excl = LISS(root->left) + LISS(root->right);
  
    // Calculate size including the current node
    int size_incl = 1;
    if (root->left)
       size_incl += LISS(root->left->left) + LISS(root->left->right);
    if (root->right)
       size_incl += LISS(root->right->left) + LISS(root->right->right);
  
    // Return the maximum of two sizes
    return max(size_incl, size_excl);
}
  

283
Chapter 26. DP-26 | Largest Independent Set Problem

  
// A utility function to create a node
struct node* newNode( int data )
{
    struct node* temp = (struct node *) malloc( sizeof(struct node) );
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
// Driver program to test above functions
int main()
{
    // Let us construct the tree given in the above diagram
    struct node *root         = newNode(20);
    root->left                = newNode(8);
    root->left->left          = newNode(4);
    root->left->right         = newNode(12);
    root->left->right->left   = newNode(10);
    root->left->right->right  = newNode(14);
    root->right               = newNode(22);
    root->right->right        = newNode(25);
  
    printf ("Size of the Largest Independent Set is %d ", LISS(root));
  
    return 0;
}

Output:

Size of the Largest Independent Set is 5

Time complexity of the above naive recursive approach is exponential. It should be noted
that the above function computes the same subproblems again and again. For example,
LISS of node with value 50 is evaluated for node with values 10 and 20 as 50 is grandchild
of 10 and child of 20.
Since same suproblems are called again, this problem has Overlapping Subprolems prop-
erty. So LISS problem has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, recomputations of same
subproblems can be avoided by storing the solutions to subproblems and solving problems
in bottom up manner.
Following is C implementation of Dynamic Programming based solution. In the following
solution, an additional field ‘liss’ is added to tree nodes. The initial value of ‘liss’ is set as
0 for all nodes. The recursive function LISS() calculates ‘liss’ for a node only if it is not
already set.
C

284
Chapter 26. DP-26 | Largest Independent Set Problem

/* Dynamic programming based program for Largest Independent Set problem */


#include <stdio.h>
#include <stdlib.h>
  
// A utility function to find max of two integers
int max(int x, int y) { return (x > y)? x: y; }
  
/* A binary tree node has data, pointer to left child and a pointer to 
   right child */
struct node
{
    int data;
    int liss;
    struct node *left, *right;
};
  
// A memoization function returns size of the largest independent set in
//  a given binary tree
int LISS(struct node *root)
{
    if (root == NULL)
        return 0;
  
    if (root->liss)
        return root->liss;
  
    if (root->left == NULL && root->right == NULL)
        return (root->liss = 1);
  
    // Calculate size excluding the current node
    int liss_excl = LISS(root->left) + LISS(root->right);
  
    // Calculate size including the current node
    int liss_incl = 1;
    if (root->left)
        liss_incl += LISS(root->left->left) + LISS(root->left->right);
    if (root->right)
        liss_incl += LISS(root->right->left) + LISS(root->right->right);
  
    // Maximum of two sizes is LISS, store it for future uses.
    root->liss = max(liss_incl, liss_excl);
  
    return root->liss;
}
  
// A utility function to create a node
struct node* newNode(int data)
{

285
Chapter 26. DP-26 | Largest Independent Set Problem

    struct node* temp = (struct node *) malloc( sizeof(struct node) );


    temp->data = data;
    temp->left = temp->right = NULL;
    temp->liss = 0;
    return temp;
}
  
// Driver program to test above functions
int main()
{
    // Let us construct the tree given in the above diagram
    struct node *root         = newNode(20);
    root->left                = newNode(8);
    root->left->left          = newNode(4);
    root->left->right         = newNode(12);
    root->left->right->left   = newNode(10);
    root->left->right->right  = newNode(14);
    root->right               = newNode(22);
    root->right->right        = newNode(25);
  
    printf ("Size of the Largest Independent Set is %d ", LISS(root));
  
    return 0;
}

Java

// Java program for calculating LISS 


// using dynamic programming
  
public class LisTree 
{
    /* A binary tree node has data, pointer 
       to left child and a pointer to right
       child */
    static class node 
    {
        int data, liss;
        node left, right;
  
        public node(int data) 
        {
            this.data = data;
            this.liss = 0;
        }
    }
  
    // A memoization function returns size 

286
Chapter 26. DP-26 | Largest Independent Set Problem

    // of the largest independent set in


    // a given binary tree
    static int liss(node root) 
    {
        if (root == null)
            return 0;
        if (root.liss != 0)
            return root.liss;
        if (root.left == null && root.right == null)
            return root.liss = 1;
          
        // Calculate size excluding the 
        // current node
        int liss_excl = liss(root.left) + liss(root.right);
          
        // Calculate size including the 
        // current node
        int liss_incl = 1;
        if (root.left != null) 
        {
            liss_incl += (liss(root.left.left) + liss(root.left.right));
        }
        if (root.right != null) 
        {
            liss_incl += (liss(root.right.left) + liss(root.right.right));
        }
          
        // Maximum of two sizes is LISS, 
        // store it for future uses.
        return root.liss = Math.max(liss_excl, liss_incl);
    }
  
    public static void main(String[] args) 
    {
        // Let us construct the tree given 
        // in the above diagram
          
        node root = new node(20);
        root.left = new node(8);
        root.left.left = new node(4);
        root.left.right = new node(12);
        root.left.right.left = new node(10);
        root.left.right.right = new node(14);
        root.right = new node(22);
        root.right.right = new node(25);
        System.out.println("Size of the Largest Independent Set is " + liss(root));
    }
}

287
Chapter 26. DP-26 | Largest Independent Set Problem

  
// This code is contributed by Rishabh Mahrsee

Output

Size of the Largest Independent Set is 5

Time Complexity: O(n) where n is the number of nodes in given Binary tree.
Following extensions to above solution can be tried as an exercise.
1) Extend the above solution for n-ary tree.
2) The above solution modifies the given tree structure by adding an additional field ‘liss’
to tree nodes. Extend the solution so that it doesn’t modify the tree structure.
3) The above solution only returns size of LIS, it doesn’t print elements of LIS. Extend the
solution to print all nodes that are part of LIS.

Source

https://www.geeksforgeeks.org/largest-independent-set-problem-dp-26/

288
Chapter 27

DP-27 | Maximum sum


rectangle in a 2D matrix

Maximum sum rectangle in a 2D matrix | DP-27 - GeeksforGeeks


Given a 2D array, find the maximum sum subarray in it. For example, in the following
2D array, the maximum sum subarray is highlighted with blue rectangle and sum of this
subarray is 29.

This problem is mainly an extension of Largest Sum Contiguous Subarray for 1D array.
The naive solution for this problem is to check every possible rectangle in given 2D array.
This solution requires 4 nested loops and time complexity of this solution would be O(n^4).
Kadane’s algorithm for 1D array can be used to reduce the time complexity to O(n^3).
The idea is to fix the left and right columns one by one and find the maximum sum
contiguous rows for every left and right column pair. We basically find top and bottom row
numbers (which have maximum sum) for every fixed left and right column pair. To find
the top and bottom row numbers, calculate sun of elements in every row from left to right
and store these sums in an array say temp[]. So temp[i] indicates sum of elements from left

289
Chapter 27. DP-27 | Maximum sum rectangle in a 2D matrix

to right in row i. If we apply Kadane’s 1D algorithm on temp[], and get the maximum sum
subarray of temp, this maximum sum would be the maximum possible sum with left and
right as boundary columns. To get the overall maximum sum, we compare this sum with
the maximum sum so far.

// Program to find maximum sum subarray in a given 2D array


#include <stdio.h>
#include <string.h>
#include <limits.h>
#define ROW 4
#define COL 5
  
// Implementation of Kadane's algorithm for 1D array. The function 
// returns the maximum sum and stores starting and ending indexes of the 
// maximum sum subarray at addresses pointed by start and finish pointers 
// respectively.
int kadane(int* arr, int* start, int* finish, int n)
{
    // initialize sum, maxSum and
    int sum = 0, maxSum = INT_MIN, i;
  
    // Just some initial value to check for all negative values case
    *finish = -1;
  
    // local variable
    int local_start = 0;
  
    for (i = 0; i < n; ++i)
    {
        sum += arr[i];
        if (sum < 0)
        {
            sum = 0;
            local_start = i+1;
        }
        else if (sum > maxSum)
        {
            maxSum = sum;
            *start = local_start;
            *finish = i;
        }
    }
  
     // There is at-least one non-negative number
    if (*finish != -1)
        return maxSum;

290
Chapter 27. DP-27 | Maximum sum rectangle in a 2D matrix

  
    // Special Case: When all numbers in arr[] are negative
    maxSum = arr[0];
    *start = *finish = 0;
  
    // Find the maximum element in array
    for (i = 1; i < n; i++)
    {
        if (arr[i] > maxSum)
        {
            maxSum = arr[i];
            *start = *finish = i;
        }
    }
    return maxSum;
}
  
// The main function that finds maximum sum rectangle in M[][]
void findMaxSum(int M[][COL])
{
    // Variables to store the final output
    int maxSum = INT_MIN, finalLeft, finalRight, finalTop, finalBottom;
  
    int left, right, i;
    int temp[ROW], sum, start, finish;
  
    // Set the left column
    for (left = 0; left < COL; ++left)
    {
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
  
        // Set the right column for the left column set by outer loop
        for (right = left; right < COL; ++right)
        {
           // Calculate sum between current left and right for every row 'i'
            for (i = 0; i < ROW; ++i)
                temp[i] += M[i][right];
  
            // Find the maximum sum subarray in temp[]. The kadane() 
            // function also sets values of start and finish.  So 'sum' is 
            // sum of rectangle between (start, left) and (finish, right) 
            //  which is the maximum sum with boundary columns strictly as
            //  left and right.
            sum = kadane(temp, &start, &finish, ROW);
  
            // Compare sum with maximum sum so far. If sum is more, then 
            // update maxSum and other output values

291
Chapter 27. DP-27 | Maximum sum rectangle in a 2D matrix

            if (sum > maxSum)


            {
                maxSum = sum;
                finalLeft = left;
                finalRight = right;
                finalTop = start;
                finalBottom = finish;
            }
        }
    }
  
    // Print final values
    printf("(Top, Left) (%d, %d)\n", finalTop, finalLeft);
    printf("(Bottom, Right) (%d, %d)\n", finalBottom, finalRight);
    printf("Max sum is: %d\n", maxSum);
}
  
// Driver program to test above functions
int main()
{
    int M[ROW][COL] = {{1, 2, -1, -4, -20},
                       {-8, -3, 4, 2, 1},
                       {3, 8, 10, 1, 3},
                       {-4, -1, 1, 7, -6}
                      };
  
    findMaxSum(M);
  
    return 0;
}

Java

import java.util.*;
import java.lang.*;
import java.io.*;
  
/**
 * Given a 2D array, find the maximum sum subarray in it
 */
class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        findMaxSubMatrix(new int[][] {
                            {1, 2, -1, -4, -20},
                            {-8, -3, 4, 2, 1},
                            {3, 8, 10, 1, 3},

292
Chapter 27. DP-27 | Maximum sum rectangle in a 2D matrix

                            {-4, -1, 1, 7, -6}


                            });
    }
      
    /**
     * To find maxSum in 1d array
     * 
     * return {maxSum, left, right}
     */ 
    public static int[] kadane(int[] a) {
        //result[0] == maxSum, result[1] == start, result[2] == end;
        int[] result = new int[]{Integer.MIN_VALUE, 0, -1};
        int currentSum = 0;
        int localStart = 0;
      
        for (int i = 0; i < a.length; i++) {
            currentSum += a[i];
            if (currentSum < 0) {
                  currentSum = 0;
                localStart = i + 1;
              } else if (currentSum > result[0]) {
                result[0] = currentSum;
                result[1] = localStart;
                result[2] = i;
              }
        }
          
        //all numbers in a are negative
        if (result[2] == -1) {
            result[0] = 0;
            for (int i = 0; i < a.length; i++) {
                if (a[i] > result[0]) {
                    result[0] = a[i];
                    result[1] = i;
                    result[2] = i;
                }
            }
        }
          
        return result;
      }
  
    /**
     * To find and print maxSum, (left, top),(right, bottom)
     */
    public static void findMaxSubMatrix(int[][] a) {
        int cols = a[0].length;
        int rows = a.length;

293
Chapter 27. DP-27 | Maximum sum rectangle in a 2D matrix

        int[] currentResult;
        int maxSum = Integer.MIN_VALUE;
        int left = 0;
        int top = 0;
        int right = 0;
        int bottom = 0;
          
        for (int leftCol = 0; leftCol < cols; leftCol++) {
            int[] tmp = new int[rows];
      
              for (int rightCol = leftCol; rightCol < cols; rightCol++) {
          
                for (int i = 0; i < rows; i++) {
                      tmp[i] += a[i][rightCol];
                }
                currentResult = kadane(tmp);
                if (currentResult[0] > maxSum) {
                    maxSum = currentResult[0];
                    left = leftCol;
                    top = currentResult[1];
                    right = rightCol;
                    bottom = currentResult[2];
                }
            }
        }
              System.out.println("MaxSum: " + maxSum + 
                                ", range: [(" + left + ", " + top + 
                                  ")(" + right + ", " + bottom + ")]");
    }
}
// Thanks to Ilia Savin for contributing this code.

Output:

(Top, Left) (1, 1)


(Bottom, Right) (3, 3)
Max sum is: 29

Time Complexity: O(n^3)


This article is compiled byAashish Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : Gaurav Kumar 33

294
Chapter 27. DP-27 | Maximum sum rectangle in a 2D matrix

Source

https://www.geeksforgeeks.org/maximum-sum-rectangle-in-a-2d-matrix-dp-27/

295
Chapter 28

DP-28 | Minimum insertions to


form a palindrome

Minimum insertions to form a palindrome | DP-28 - GeeksforGeeks


Given a string, find the minimum number of characters to be inserted to convert it to
palindrome.
Before we go further, let us understand with few examples:

• ab: Number of insertions required is 1 i.e. bab


• aa: Number of insertions required is 0 i.e. aa
• abcd: Number of insertions required is 3 i.e. dcbabcd
• abcda: Number of insertions required is 2 i.e. adcbcda which is same as number of
insertions in the substring bcd(Why?).
• abcde: Number of insertions required is 4 i.e. edcbabcde

Let the input string be str[l……h]. The problem can be broken down into three parts:
1. Find the minimum number of insertions in the substring str[l+1,…….h].
2. Find the minimum number of insertions in the substring str[l…….h-1].
3. Find the minimum number of insertions in the substring str[l+1……h-1].
Recursive Solution
The minimum number of insertions in the string str[l…..h] can be given as:

• minInsertions(str[l+1…..h-1]) if str[l] is equal to str[h]


• min(minInsertions(str[l…..h-1]), minInsertions(str[l+1…..h])) + 1 otherwise

// A Naive recursive program to find minimum 


// number insertions needed to make a string

296
Chapter 28. DP-28 | Minimum insertions to form a palindrome

// palindrome
#include <stdio.h>
#include <limits.h>
#include <string.h>
  
// A utility function to find minimum of two numbers
int min(int a, int b)
{  return a < b ? a : b; }
  
// Recursive function to find minimum number of 
// insertions
int findMinInsertions(char str[], int l, int h)
{
    // Base Cases
    if (l > h) return INT_MAX;
    if (l == h) return 0;
    if (l == h - 1) return (str[l] == str[h])? 0 : 1;
  
    // Check if the first and last characters are
    // same. On the basis of the comparison result, 
    // decide which subrpoblem(s) to call
    return (str[l] == str[h])? 
                     findMinInsertions(str, l + 1, h - 1):
                     (min(findMinInsertions(str, l, h - 1),
                     findMinInsertions(str, l + 1, h)) + 1);
}
  
// Driver program to test above functions
int main()
{
    char str[] = "geeks";
    printf("%d", findMinInsertions(str, 0, strlen(str)-1));
    return 0;
}

Java

// A Naive recursive Java program to find minimum


// number insertions needed to make a string
// palindrome
class GFG {
  
    // Recursive function to find minimum number
    // of insertions
    static int findMinInsertions(char str[], int l,
                                             int h)
    {
        // Base Cases

297
Chapter 28. DP-28 | Minimum insertions to form a palindrome

        if (l > h) return Integer.MAX_VALUE;


        if (l == h) return 0;
        if (l == h - 1) return (str[l] == str[h])? 0 : 1;
  
        // Check if the first and last characters
        // are same. On the basis of the  comparison
        // result, decide which subrpoblem(s) to call
        return (str[l] == str[h])?
            findMinInsertions(str, l + 1, h - 1):
            (Integer.min(findMinInsertions(str, l, h - 1),
            findMinInsertions(str, l + 1, h)) + 1);
    }
  
    // Driver program to test above functions
    public static void main(String args[])
    {
        String str= "geeks";
        System.out.println(findMinInsertions(str.toCharArray(),
                                          0, str.length()-1));
    }
}
// This code is contributed by Sumit Ghosh

C#

// A Naive recursive C# program 


// to find minimum number 
// insertions needed to make 
// a string palindrom
using System;
  
class GFG
{
    // Recursive function to 
    // find minimum number of
    // insertions
    static int findMinInsertions(char []str, 
                                 int l, int h)
    {
        // Base Cases
        if (l > h) return int.MaxValue;
        if (l == h) return 0;
        if (l == h - 1) 
            return (str[l] == str[h])? 0 : 1;
  
        // Check if the first and 
        // last characters are same. 
        // On the basis of the 

298
Chapter 28. DP-28 | Minimum insertions to form a palindrome

        // comparison result, decide 


        // which subrpoblem(s) to call
        return (str[l] == str[h])?
                findMinInsertions(str, 
                                  l + 1, h - 1):
                (Math.Min(findMinInsertions(str, l, 
                                            h - 1),
                          findMinInsertions(str, l + 
                                        1, h)) + 1);
    } 
      
    // Driver Code
    public static void Main()
    {
        string str= "geeks";
        Console.WriteLine(findMinInsertions(str.ToCharArray(),
                                            0, str.Length - 1)); 
    }
}
  
// This code is contributed by Sam007

Output:

Dynamic Programming based Solution


If we observe the above approach carefully, we can find that it exhibits overlapping subprob-
lems.
Suppose we want to find the minimum number of insertions in string “abcde”:

abcde
/ | \
/ | \
bcde abcd bcd <- case 3 is discarded as str[l] != str[h]
/ | \ / | \
/ | \ / | \
cde bcd cd bcd abc bc
/ | \ / | \ /|\ / | \
de cd d cd bc c………………….

The substrings in bold show that the recursion to be terminated and the recursion tree cannot
originate from there. Substring in the same color indicates overlapping subproblems.
How to reuse solutions of subproblems?
We can create a table to store results of subproblems so that they can be used directly if
same subproblem is encountered again.
The below table represents the stored values for the string abcde.

299
Chapter 28. DP-28 | Minimum insertions to form a palindrome

a b c d e
----------
0 1 2 3 4
0 0 1 2 3
0 0 0 1 2
0 0 0 0 1
0 0 0 0 0

How to fill the table?


The table should be filled in diagonal fashion. For the string abcde, 0….4, the following
should be order in which the table is filled:

Gap = 1:
(0, 1) (1, 2) (2, 3) (3, 4)

Gap = 2:
(0, 2) (1, 3) (2, 4)

Gap = 3:
(0, 3) (1, 4)

Gap = 4:
(0, 4)

// A Dynamic Programming based program to find


// minimum number insertions needed to make a
// string palindrome
#include <stdio.h>
#include <string.h>
  
// A utility function to find minimum of two integers
int min(int a, int b)
{   return a < b ? a : b;  }
  
// A DP function to find minimum number of insertions
int findMinInsertionsDP(char str[], int n)
{
    // Create a table of size n*n. table[i][j]
    // will store minimum number of insertions 
    // needed to convert str[i..j] to a palindrome.
    int table[n][n], l, h, gap;
  
    // Initialize all table entries as 0
    memset(table, 0, sizeof(table));

300
Chapter 28. DP-28 | Minimum insertions to form a palindrome

  
    // Fill the table
    for (gap = 1; gap < n; ++gap)
        for (l = 0, h = gap; h < n; ++l, ++h)
            table[l][h] = (str[l] == str[h])?
                          table[l+1][h-1] :
                          (min(table[l][h-1], 
                           table[l+1][h]) + 1);
  
    // Return minimum number of insertions for
    // str[0..n-1]
    return table[0][n-1];
}
  
// Driver program to test above function.
int main()
{
    char str[] = "geeks";
    printf("%d", findMinInsertionsDP(str, strlen(str)));
    return 0;
}

Java

// A Java solution for Dynamic Programming


// based program to find minimum number
// insertions needed to make a string
// palindrome
import java.util.Arrays;
  
class GFG
{
    // A DP function to find minimum number
    // of insersions
    static int findMinInsertionsDP(char str[], int n)
    {
        // Create a table of size n*n. table[i][j]
        // will store minumum number of insertions
        // needed to convert str[i..j] to a palindrome.
        int table[][] = new int[n][n];
        int l, h, gap;
  
        // Fill the table
        for (gap = 1; gap < n; ++gap)
        for (l = 0, h = gap; h < n; ++l, ++h)
            table[l][h] = (str[l] == str[h])?
                           table[l+1][h-1] :
                          (Integer.min(table[l][h-1],

301
Chapter 28. DP-28 | Minimum insertions to form a palindrome

                                 table[l+1][h]) + 1);
  
        // Return minimum number of insertions
        // for str[0..n-1]
        return table[0][n-1];
    }
  
    // Driver program to test above function.
    public static void main(String args[])
    {
        String str = "geeks";
        System.out.println(
        findMinInsertionsDP(str.toCharArray(), str.length()));
    }
}
// This code is contributed by Sumit Ghosh

Output:

Time complexity: O(N^2)


Auxiliary Space: O(N^2)
Another Dynamic Programming Solution (Variation of Longest Common Sub-
sequence Problem)
The problem of finding minimum insertions can also be solved using Longest Common Sub-
sequence (LCS) Problem. If we find out LCS of string and its reverse, we know how many
maximum characters can form a palindrome. We need insert remaining characters. Follow-
ing are the steps.
1) Find the length of LCS of input string and its reverse. Let the length be ‘l’.
2) The minimum number insertions needed is length of input string minus ‘l’.
C

// An LCS based program to find minimum number


// insertions needed to make a string palindrome
#include<stdio.h>
#include <string.h>
  
/* Utility function to get max of 2 integers */
int max(int a, int b)
{   return (a > b)? a : b; }
  
/* Returns length of LCS for X[0..m-1], Y[0..n-1]. 
   See http://goo.gl/bHQVP for details of this 
   function */
int lcs( char *X, char *Y, int m, int n )

302
Chapter 28. DP-28 | Minimum insertions to form a palindrome

{
   int L[n+1][n+1];
   int i, j;
  
   /* Following steps build L[m+1][n+1] in bottom 
      up fashion. Note that L[i][j] contains length
      of LCS of X[0..i-1] and Y[0..j-1] */
   for (i=0; i<=m; i++)
   {
     for (j=0; j<=n; j++)
     {
       if (i == 0 || j == 0)
         L[i][j] = 0;
  
       else if (X[i-1] == Y[j-1])
         L[i][j] = L[i-1][j-1] + 1;
  
       else
         L[i][j] = max(L[i-1][j], L[i][j-1]);
     }
   }
  
   /* L[m][n] contains length of LCS for X[0..n-1]
     and Y[0..m-1] */
   return L[m][n];
}
  
// LCS based function to find minimum number of 
// insertions
int findMinInsertionsLCS(char str[], int n)
{
   // Creata another string to store reverse of 'str'
   char rev[n+1];
   strcpy(rev, str);
   strrev(rev);
  
   // The output is length of string minus length of lcs of
   // str and it reverse
   return (n - lcs(str, rev, n, n));
}
  
// Driver program to test above functions
int main()
{
    char str[] = "geeks";
    printf("%d", findMinInsertionsLCS(str, strlen(str)));
    return 0;
}

303
Chapter 28. DP-28 | Minimum insertions to form a palindrome

Java

// An LCS based Java program to find minimum


// number insertions needed to make a string
// palindrome
class GFG
{
    /* Returns length of LCS for X[0..m-1],
       Y[0..n-1]. See http://goo.gl/bHQVP for
       details of this function */
    static int lcs( String X, String Y, int m, int n )
    {
        int L[][] = new int[n+1][n+1];
        int i, j;
  
        /* Following steps build L[m+1][n+1] in
           bottom up fashion. Note that L[i][j]
           contains length of LCS of X[0..i-1]
           and Y[0..j-1] */
        for (i=0; i<=m; i++)
        {
            for (j=0; j<=n; j++)
            {
                if (i == 0 || j == 0)
                    L[i][j] = 0;
  
                else if (X.charAt(i-1) == Y.charAt(j-1))
                    L[i][j] = L[i-1][j-1] + 1;
  
                else
                    L[i][j] = Integer.max(L[i-1][j], L[i][j-1]);
            }
        }
  
        /* L[m][n] contains length of LCS for
           X[0..n-1] and Y[0..m-1] */
        return L[m][n];
    }
  
    // LCS based function to find minimum number
    // of insersions
    static int findMinInsertionsLCS(String str, int n)
    {
        // Using StringBuffer to reverse a String
        StringBuffer sb = new StringBuffer(str);
        sb.reverse();
        String revString = sb.toString();
  

304
Chapter 28. DP-28 | Minimum insertions to form a palindrome

        // The output is length of string minus


        // length of lcs of str and it reverse
        return (n - lcs(str, revString , n, n));
    }
  
    // Driver program to test above functions
    public static void main(String args[])
    {
        String str = "geeks";
        System.out.println(
        findMinInsertionsLCS(str, str.length()));
    }
}
// This code is contributed by Sumit Ghosh

Output:

Time complexity of this method is also O(n^2) and this method also requires O(n^2) extra
space.
Related Article :
Minimum number of Appends needed to make a string palindrome
This article is compiled by Aashish Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : Sam007

Source

https://www.geeksforgeeks.org/minimum-insertions-to-form-a-palindrome-dp-28/

305
Chapter 29

DP-29 | Longest Common


Substring

Longest Common Substring | DP-29 - GeeksforGeeks


Given two strings ‘X’ and ‘Y’, find the length of the longest common substring.
Examples :

Input : X = "GeeksforGeeks", y = "GeeksQuiz"


Output : 5
The longest common substring is "Geeks" and is of
length 5.

Input : X = "abcdxyz", y = "xyzabcd"


Output : 4
The longest common substring is "abcd" and is of
length 4.

Input : X = "zxabcdezy", y = "yzabcdezx"


Output : 6
The longest common substring is "abcdez" and is of
length 6.

306
Chapter 29. DP-29 | Longest Common Substring

Let m and n be the lengths of first and second strings respectively.


A simple solution is to one by one consider all substrings of first string and for every
substring check if it is a substring in second string. Keep track of the maximum length
substring. There will be O(m^2) substrings and we can find whether a string is subsring on
another string in O(n) time (See this). So overall time complexity of this method would be
O(n * m2 )
Dynamic Programming can be used to find the longest common substring in O(m*n)
time. The idea is to find length of the longest common suffix for all substrings of both
strings and store these lengths in a table.

The longest common suffix has following optimal substructure property


LCSuff(X, Y, m, n) = LCSuff(X, Y, m-1, n-1) + 1 if X[m-1] = Y[n-1]
0 Otherwise (if X[m-1] != Y[n-1])

The maximum length Longest Common Suffix is the longest common substring.
LCSubStr(X, Y, m, n) = Max(LCSuff(X, Y, i, j)) where 1 <= i <= m
and 1 <= j <= n

Following is the implementation of the above solution.

C++

/* Dynamic Programming solution to find length of the 


   longest common substring */
#include<iostream>
#include<string.h>

307
Chapter 29. DP-29 | Longest Common Substring

using namespace std;


  
// A utility function to find maximum of two integers
int max(int a, int b)
{   return (a > b)? a : b; }
  
/* Returns length of longest common substring of X[0..m-1] 
   and Y[0..n-1] */
int LCSubStr(char *X, char *Y, int m, int n)
{
    // Create a table to store lengths of longest common suffixes of
    // substrings.   Notethat LCSuff[i][j] contains length of longest
    // common suffix of X[0..i-1] and Y[0..j-1]. The first row and
    // first column entries have no logical meaning, they are used only
    // for simplicity of program
    int LCSuff[m+1][n+1];
    int result = 0;  // To store length of the longest common substring
  
    /* Following steps build LCSuff[m+1][n+1] in bottom up fashion. */
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {
            if (i == 0 || j == 0)
                LCSuff[i][j] = 0;
  
            else if (X[i-1] == Y[j-1])
            {
                LCSuff[i][j] = LCSuff[i-1][j-1] + 1;
                result = max(result, LCSuff[i][j]);
            }
            else LCSuff[i][j] = 0;
        }
    }
    return result;
}
  
/* Driver program to test above function */
int main()
{
    char X[] = "OldSite:GeeksforGeeks.org";
    char Y[] = "NewSite:GeeksQuiz.com";
  
    int m = strlen(X);
    int n = strlen(Y);
  
    cout << "Length of Longest Common Substring is " 
         << LCSubStr(X, Y, m, n);

308
Chapter 29. DP-29 | Longest Common Substring

    return 0;
}

Java

//  Java implementation of finding length of longest 


// Common substring using Dynamic Programming
public class LongestCommonSubSequence 
{
    /* 
       Returns length of longest common substring  
       of X[0..m-1] and Y[0..n-1] 
    */
    static int LCSubStr(char X[], char Y[], int m, int n) 
    {
        // Create a table to store lengths of longest common suffixes of
        // substrings. Note that LCSuff[i][j] contains length of longest
        // common suffix of X[0..i-1] and Y[0..j-1]. The first row and
        // first column entries have no logical meaning, they are used only
        // for simplicity of program
        int LCStuff[][] = new int[m + 1][n + 1];
        int result = 0;  // To store length of the longest common substring
          
        // Following steps build LCSuff[m+1][n+1] in bottom up fashion
        for (int i = 0; i <= m; i++) 
        {
            for (int j = 0; j <= n; j++) 
            {
                if (i == 0 || j == 0)
                    LCStuff[i][j] = 0;
                else if (X[i - 1] == Y[j - 1])
                {
                    LCStuff[i][j] = LCStuff[i - 1][j - 1] + 1;
                    result = Integer.max(result, LCStuff[i][j]);
                } 
                else
                    LCStuff[i][j] = 0;
            }
        }
        return result;
    }
      
    // Driver Program to test above function
    public static void main(String[] args) 
    {
        String X = "OldSite:GeeksforGeeks.org";
        String Y = "NewSite:GeeksQuiz.com";
  

309
Chapter 29. DP-29 | Longest Common Substring

        int m = X.length();
        int n = Y.length();
  
        System.out.println("Length of Longest Common Substring is "
                + LCSubStr(X.toCharArray(), Y.toCharArray(), m, n));
    }
}
  
// This code is contributed by Sumit Ghosh

Python3

# Python3 implementation of Finding 


# Length of Longest Common Substring 
  
# Returns length of longest common 
# substring of X[0..m-1] and Y[0..n-1] 
def LCSubStr(X, Y, m, n):
      
    # Create a table to store lengths of
    # longest common suffixes of substrings. 
    # Note that LCSuff[i][j] contains the 
    # length of longest common suffix of 
    # X[0...i-1] and Y[0...j-1]. The first
    # row and first column entries have no
    # logical meaning, they are used only
    # for simplicity of the program.
      
    # LCSuff is the table with zero 
    # value initially in each cell
    LCSuff = [[0 for k in range(n+1)] for l in range(m+1)]
      
    # To store the length of 
    # longest common substring
    result = 0 
  
    # Following steps to build
    # LCSuff[m+1][n+1] in bottom up fashion
    for i in range(m + 1):
        for j in range(n + 1):
            if (i == 0 or j == 0):
                LCSuff[i][j] = 0
            elif (X[i-1] == Y[j-1]):
                LCSuff[i][j] = LCSuff[i-1][j-1] + 1
                result = max(result, LCSuff[i][j])
            else:
                LCSuff[i][j] = 0
    return result

310
Chapter 29. DP-29 | Longest Common Substring

  
# Driver Program to test above function
X = 'OldSite:GeeksforGeeks.org'
Y = 'NewSite:GeeksQuiz.com'
  
m = len(X)
n = len(Y)
  
print('Length of Longest Common Substring is',
                      LCSubStr(X, Y, m, n))
  
# This code is contributed by Soumen Ghosh

C#

// C# implementation of finding length of longest


// Common substring using Dynamic Programming
using System;
  
class GFG {
       
    // Returns length of longest common 
    // substring of X[0..m-1] and Y[0..n-1] 
    static int LCSubStr(string X, string Y,
                                 int m, int n)
    {
          
        // Create a table to store lengths of 
        // longest common suffixes of substrings.
        // Note that LCSuff[i][j] contains length
        // of longest common suffix of X[0..i-1] 
        // and Y[0..j-1]. The first row and first
        // column entries have no logical meaning,
        // they are used only for simplicity of 
        // program
        int[, ] LCStuff = new int[m + 1, n + 1];
          
        // To store length of the longest common
        // substring
        int result = 0; 
  
        // Following steps build LCSuff[m+1][n+1] 
        // in bottom up fashion
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                if (i == 0 || j == 0)
                    LCStuff[i, j] = 0;
                else if (X[i - 1] == Y[j - 1]) {

311
Chapter 29. DP-29 | Longest Common Substring

                    LCStuff[i, j] = 
                            LCStuff[i - 1, j - 1] + 1;
                              
                    result = Math.Max(result, 
                                      LCStuff[i, j]);
                }
                else
                    LCStuff[i, j] = 0;
            }
        }
          
        return result;
    }
  
    // Driver Program to test above function
    public static void Main()
    {
        String X = "OldSite:GeeksforGeeks.org";
        String Y = "NewSite:GeeksQuiz.com";
  
        int m = X.Length;
        int n = Y.Length;
  
        Console.Write("Length of Longest Common"
        + " Substring is " + LCSubStr(X, Y, m, n));
    }
  
}
  
// This code is contributed by Sam007.

Output:

Length of Longest Common Substring is 10

Time Complexity: O(m*n)


Auxiliary Space: O(m*n)
References: http://en.wikipedia.org/wiki/Longest_common_substring_problem
The longest substring can also be solved in O(n+m) time using Suffix Tree. We will be
covering Suffix Tree based solution in a separate post.
Exercise: The above solution prints only length of the longest common substring. Extend
the solution to print the substring also.

Source
https://www.geeksforgeeks.org/longest-common-substring-dp-29/

312
Chapter 30

DP-30 | Dice Throw

Dice Throw | DP-30 - GeeksforGeeks


Given n dice each with m faces, numbered from 1 to m, find the number of ways to get sum
X. X is the summation of values on each face when all the dice are thrown.
The Naive approach is to find all the possible combinations of values from n dice and keep
on counting the results that sum to X.
This problem can be efficiently solved using Dynamic Programming (DP).

Let the function to find X from n dice is: Sum(m, n, X)


The function can be represented as:
Sum(m, n, X) = Finding Sum (X - 1) from (n - 1) dice plus 1 from nth dice
+ Finding Sum (X - 2) from (n - 1) dice plus 2 from nth dice
+ Finding Sum (X - 3) from (n - 1) dice plus 3 from nth dice
...................................................
...................................................
...................................................
+ Finding Sum (X - m) from (n - 1) dice plus m from nth dice

So we can recursively write Sum(m, n, x) as following


Sum(m, n, X) = Sum(m, n - 1, X - 1) +
Sum(m, n - 1, X - 2) +
.................... +
Sum(m, n - 1, X - m)

Why DP approach?
The above problem exhibits overlapping subproblems. See the below diagram. Also, see
thisrecursive implementation. Let there be 3 dice, each with 6 faces and we need to find the
number of ways to get sum 8:

313
Chapter 30. DP-30 | Dice Throw

Sum(6, 3, 8) = Sum(6, 2, 7) + Sum(6, 2, 6) + Sum(6, 2, 5) +


Sum(6, 2, 4) + Sum(6, 2, 3) + Sum(6, 2, 2)

To evaluate Sum(6, 3, 8), we need to evaluate Sum(6, 2, 7) which can


recursively written as following:
Sum(6, 2, 7) = Sum(6, 1, 6) + Sum(6, 1, 5) + Sum(6, 1, 4) +
Sum(6, 1, 3) + Sum(6, 1, 2) + Sum(6, 1, 1)

We also need to evaluate Sum(6, 2, 6) which can recursively written


as following:
Sum(6, 2, 6) = Sum(6, 1, 5) + Sum(6, 1, 4) + Sum(6, 1, 3) +
Sum(6, 1, 2) + Sum(6, 1, 1)
..............................................
..............................................
Sum(6, 2, 2) = Sum(6, 1, 1)

Please take a closer look at the above recursion. The sub-problems in RED are solved
first time and sub-problems in BLUE are solved again (exhibit overlapping sub-problems).
Hence, storing the results of the solved sub-problems saves time.
Following is implementation of Dynamic Programming approach.

C++

// C++ program to find number of ways to get sum 'x' with 'n'
// dice where every dice has 'm' faces
#include <iostream>
#include <string.h>
using namespace std;
  
// The main function that returns number of ways to get sum 'x'
// with 'n' dice and 'm' with m faces.
int findWays(int m, int n, int x)
{

314
Chapter 30. DP-30 | Dice Throw

    // Create a table to store results of subproblems.  One extra 


    // row and column are used for simpilicity (Number of dice
    // is directly used as row index and sum is directly used
    // as column index).  The entries in 0th row and 0th column
    // are never used.
    int table[n + 1][x + 1];
    memset(table, 0, sizeof(table)); // Initialize all entries as 0
  
    // Table entries for only one dice
    for (int j = 1; j <= m && j <= x; j++)
        table[1][j] = 1;
  
    // Fill rest of the entries in table using recursive relation
    // i: number of dice, j: sum
    for (int i = 2; i <= n; i++)
        for (int j = 1; j <= x; j++)
            for (int k = 1; k <= m && k < j; k++)
                table[i][j] += table[i-1][j-k];
  
    /* Uncomment these lines to see content of table
    for (int i = 0; i <= n; i++)
    {
      for (int j = 0; j <= x; j++)
        cout << table[i][j] << " ";
      cout << endl;
    } */
    return table[n][x];
}
  
// Driver program to test above functions
int main()
{
    cout << findWays(4, 2, 1) << endl;
    cout << findWays(2, 2, 3) << endl;
    cout << findWays(6, 3, 8) << endl;
    cout << findWays(4, 2, 5) << endl;
    cout << findWays(4, 3, 5) << endl;
  
    return 0;
}

C#

// C# program to find number 


// of ways to get sum 'x' 
// with 'n' dice where every 
// dice has 'm' faces
using System;

315
Chapter 30. DP-30 | Dice Throw

  
class GFG
{
// The main function that returns 
// number of ways to get sum 'x'
// with 'n' dice and 'm' with m faces.
static int findWays(int m, 
                    int n, int x)
{
    // Create a table to store 
    // results of subproblems. 
    // row and column are used 
    // for simpilicity (Number 
    // of dice is directly used 
    // as row index and sum is 
    // directly used as column
    // index). The entries in 0th
    // row and 0th column are 
    // never used.
    int[,] table = new int[n + 1, 
                           x + 1];
                             
    // Initialize all 
    // entries as 0
    for (int i = 0; i <= n; i++)
    for (int j = 0; j <= x; j++)
    table[i, j] = 0;
      
    // Table entries for 
    // only one dice
    for (int j = 1; 
             j <= m && j <= x; j++)
        table[1, j] = 1;
  
    // Fill rest of the entries 
    // in table using recursive 
    // relation i: number of 
    // dice, j: sum
    for (int i = 2; i <= n; i++)
        for (int j = 1; j <= x; j++)
            for (int k = 1; 
                     k <= m && k < j; k++)
                table[i, j] += table[i - 1, 
                                     j - k];
  
    /* Uncomment these lines to
    see content of table
    for (int i = 0; i <= n; i++)

316
Chapter 30. DP-30 | Dice Throw

    {
    for (int j = 0; j <= x; j++)
        cout << table[i][j] << " ";
    cout << endl;
    } */
    return table[n, x];
}
  
// Driver Code
public static void Main()
{
    Console.WriteLine(findWays(4, 2, 1));
    Console.WriteLine(findWays(2, 2, 3));
    Console.WriteLine(findWays(6, 3, 8));
    Console.WriteLine(findWays(4, 2, 5));
    Console.WriteLine(findWays(4, 3, 5));
}
}
  
// This code is contributed by mits.

PHP

<?php
// PHP program to find number 
// of ways to get sum 'x' with
// 'n' dice where every dice
// has 'm' faces
  
// The main function that returns 
// number of ways to get sum 'x' 
// with 'n' dice and 'm' with m faces.
function findWays($m, $n, $x)
{
    // Create a table to store results  
    // of subproblems. One extra row 
    // and column are used for 
    // simpilicity (Number of dice is 
    // directly used as row index and 
    // sum is directly used as column 
    // index). The entries in 0th row 
    // and 0th column are never used.
    $table;
      
    // Initialize all entries as 0
        for ($i = 1; $i < $n + 1; $i++)
        for ($j = 1; $j < $x + 1; $j++)
        $table[$i][$j] = 0;

317
Chapter 30. DP-30 | Dice Throw

  
    // Table entries for
    // only one dice
    for ($j = 1; $j <= $m && 
                 $j <= $x; $j++)
        $table[1][$j] = 1;
  
    // Fill rest of the entries 
    // in table using recursive 
    // relation i: number of dice, 
    // j: sum
    for ($i = 2; $i <= $n; $i++)
        for ($j = 1; $j <= $x; $j++)
            for ($k = 1; $k <= $m && 
                         $k < $j; $k++)
                $table[$i][$j] += 
                        $table[$i - 1][$j - $k];
  
    return $table[$n][$x];
}
  
// Driver Code
echo findWays(4, 2, 1). "\n";
echo findWays(2, 2, 3). "\n";
echo findWays(6, 3, 8). "\n";
echo findWays(4, 2, 5). "\n";
echo findWays(4, 3, 5). "\n";
  
// This code is contributed by mits.
?>

Output :

0
2
21
4
6

Time Complexity: O(m * n * x) where m is number of faces, n is number of dice and x


is given sum.
We can add following two conditions at the beginning of findWays() to improve performance
of program for extreme cases (x is too high or x is too low)

// When x is so high that sum can not go beyond x even when we 
// get maximum value in every dice throw. 

318
Chapter 30. DP-30 | Dice Throw

if (m*n <= x)
    return (m*n == x);
 
// When x is too low
if (n >= x)
    return (n == x);

With above conditions added, time complexity becomes O(1) when x >= m*n or when x
<= n.
Exercise:
Extend the above algorithm to find the probability to get Sum > X.
This article is compiled by Aashish Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : Mithun Kumar

Source

https://www.geeksforgeeks.org/dice-throw-dp-30/

319
Chapter 31

DP-31 | Optimal Strategy for a


Game

Optimal Strategy for a Game | DP-31 - GeeksforGeeks


Problem statement: Consider a row of n coins of values v1 . . . vn, where n is even. We
play a game against an opponent by alternating turns. In each turn, a player selects either
the first or last coin from the row, removes it from the row permanently, and receives the
value of the coin. Determine the maximum possible amount of money we can definitely win
if we move first.
Note: The opponent is as clever as the user.
Let us understand the problem with few examples:
1. 5, 3, 7, 10 : The user collects maximum value as 15(10 + 5)
2. 8, 15, 3, 7 : The user collects maximum value as 22(7 + 15)
Does choosing the best at each move give an optimal solution?
No. In the second example, this is how the game can finish:
1.
…….User chooses 8.
…….Opponent chooses 15.
…….User chooses 7.
…….Opponent chooses 3.
Total value collected by user is 15(8 + 7)
2.
…….User chooses 7.
…….Opponent chooses 8.
…….User chooses 15.
…….Opponent chooses 3.
Total value collected by user is 22(7 + 15)

320
Chapter 31. DP-31 | Optimal Strategy for a Game

So if the user follows the second game state, maximum value can be collected although the
first move is not the best.
There are two choices:
1. The user chooses the ith coin with value Vi: The opponent either chooses (i+1)th coin
or jth coin. The opponent intends to choose the coin which leaves the user with minimum
value.
i.e. The user can collect the value Vi + min(F(i+2, j), F(i+1, j-1) )

2. The user chooses the jth coin with value Vj: The opponent either chooses ith coin or
(j-1)th coin. The opponent intends to choose the coin which leaves the user with minimum
value.
i.e. The user can collect the value Vj + min(F(i+1, j-1), F(i, j-2) )

Following is recursive solution that is based on above two choices. We take the maximum
of two choices.

F(i, j) represents the maximum value the user can collect from
i'th coin to j'th coin.

F(i, j) = Max(Vi + min(F(i+2, j), F(i+1, j-1) ),


Vj + min(F(i+1, j-1), F(i, j-2) ))
Base Cases
F(i, j) = Vi If j == i
F(i, j) = max(Vi, Vj) If j == i+1

Why Dynamic Programming?


The above relation exhibits overlapping sub-problems. In the above relation, F(i+1, j-1) is

321
Chapter 31. DP-31 | Optimal Strategy for a Game

calculated twice.

C++

// C program to find out maximum value from a given sequence of coins


#include <limits.h>
#include <stdio.h>
  
// Utility functions to get maximum and minimum of two intgers
int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; }
  
// Returns optimal value possible that a player can collect from
// an array of coins of size n. Note than n must be even
int optimalStrategyOfGame(int* arr, int n)
{
    // Create a table to store solutions of subproblems
    int table[n][n], gap, i, j, x, y, z;
  
    // Fill table using above recursive formula. Note that the table
    // is filled in diagonal fashion (similar to http:// goo.gl/PQqoS),
    // from diagonal elements to table[0][n-1] which is the result.
    for (gap = 0; gap < n; ++gap) {
        for (i = 0, j = gap; j < n; ++i, ++j) {
            // Here x is value of F(i+2, j), y is F(i+1, j-1) and
            // z is F(i, j-2) in above recursive formula
            x = ((i + 2) <= j) ? table[i + 2][j] : 0;
            y = ((i + 1) <= (j - 1)) ? table[i + 1][j - 1] : 0;
            z = (i <= (j - 2)) ? table[i][j - 2] : 0;
  
            table[i][j] = max(arr[i] + min(x, y), arr[j] + min(y, z));
        }
    }
  
    return table[0][n - 1];
}
  
// Driver program to test above function
int main()
{
    int arr1[] = { 8, 15, 3, 7 };
    int n = sizeof(arr1) / sizeof(arr1[0]);
    printf("%dn", optimalStrategyOfGame(arr1, n));
  
    int arr2[] = { 2, 2, 2, 2 };
    n = sizeof(arr2) / sizeof(arr2[0]);
    printf("%dn", optimalStrategyOfGame(arr2, n));
  

322
Chapter 31. DP-31 | Optimal Strategy for a Game

    int arr3[] = { 20, 30, 2, 2, 2, 10 };


    n = sizeof(arr3) / sizeof(arr3[0]);
    printf("%dn", optimalStrategyOfGame(arr3, n));
  
    return 0;
}

Java

// Java program to find out maximum


// value from a given sequence of coins
import java.io.*;
  
class GFG {
    // Utility functions to get maximum
    // and minimum of two intgers
    int max(int a, int b) { return a > b ? a : b; }
    int min(int a, int b) { return a < b ? a : b; }
  
    // Returns optimal value possible that a player
    // can collect from an array of coins of size n.
    // Note than n must be even
    static int optimalStrategyOfGame(int arr[], int n)
    {
        // Create a table to store solutions of subproblems
        int table[][] = new int[n][n];
        int gap, i, j, x, y, z;
  
        // Fill table using above recursive formula.
        // Note that the tableis filled in diagonal
        // fashion (similar to http:// goo.gl/PQqoS),
        // from diagonal elements to table[0][n-1]
        // which is the result.
        for (gap = 0; gap < n; ++gap) {
            for (i = 0, j = gap; j < n; ++i, ++j) {
                // Here x is value of F(i+2, j),
                // y is F(i+1, j-1) and z is
                // F(i, j-2) in above recursive formula
                x = ((i + 2) <= j) ? table[i + 2][j] : 0;
                y = ((i + 1) <= (j - 1)) ? table[i + 1][j - 1] : 0;
                z = (i <= (j - 2)) ? table[i][j - 2] : 0;
  
                table[i][j] = Math.max(arr[i] + Math.min(x, y), arr[j] + Math.min(y, z));
            }
        }
  
        return table[0][n - 1];
    }

323
Chapter 31. DP-31 | Optimal Strategy for a Game

  
    // Driver program
    public static void main(String[] args)
    {
        int arr1[] = { 8, 15, 3, 7 };
        int n = arr1.length;
        System.out.println("" + optimalStrategyOfGame(arr1, n));
  
        int arr2[] = { 2, 2, 2, 2 };
        n = arr2.length;
        System.out.println("" + optimalStrategyOfGame(arr2, n));
  
        int arr3[] = { 20, 30, 2, 2, 2, 10 };
        n = arr3.length;
        System.out.println("" + optimalStrategyOfGame(arr3, n));
    }
}
  
// This code is contributed by vt_m

Output:

22
4
42

Exercise
Your thoughts on the strategy when the user wishes to only win instead of winning with the
maximum value. Like above problem, number of coins is even.
Can Greedy approach work quite well and give an optimal solution? Will your answer
change if number of coins is odd? Please see Coin game of two corners
This article is compiled by Aashish Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/optimal-strategy-for-a-game-dp-31/

324
Chapter 32

DP-32 | Word Break Problem

Word Break Problem | DP-32 - GeeksforGeeks


Given an input string and a dictionary of words, find out if the input string can be segmented
into a space-separated sequence of dictionary words. See following examples for more details.
This is a famous Google interview question, also being asked by many other companies now
a days.

Consider the following dictionary


{ i, like, sam, sung, samsung, mobile, ice,
cream, icecream, man, go, mango}

Input: ilike
Output: Yes
The string can be segmented as "i like".

Input: ilikesamsung
Output: Yes
The string can be segmented as "i like samsung"
or "i like sam sung".

Recursive implementation:
The idea is simple, we consider each prefix and search it in dictionary. If the prefix is present
in dictionary, we recur for rest of the string (or suffix). If the recursive call for suffix returns
true, we return true, otherwise we try next prefix. If we have tried all prefixes and none of
them resulted in a solution, we return false.
We strongly recommend to see substrfunction which is used extensively in following imple-
mentations.

// A recursive program to test whether a given 


// string can be segmented into space separated 

325
Chapter 32. DP-32 | Word Break Problem

// words in dictionary
#include <iostream>
using namespace std;
  
/* A utility function to check whether a word is 
  present in dictionary or not. An array of strings 
  is used for dictionary.  Using array of strings for
  dictionary is definitely not a good idea. We have 
  used for simplicity of the program*/
int dictionaryContains(string word)
{
    string dictionary[] = {"mobile","samsung","sam","sung",
                            "man","mango","icecream","and",
                             "go","i","like","ice","cream"};
    int size = sizeof(dictionary)/sizeof(dictionary[0]);
    for (int i = 0; i < size; i++)
        if (dictionary[i].compare(word) == 0)
           return true;
    return false;
}
  
// returns true if string can be segmented into space 
// separated words, otherwise returns false
bool wordBreak(string str)
{
    int size = str.size();
  
    // Base case
    if (size == 0)  return true;
  
    // Try all prefixes of lengths from 1 to size
    for (int i=1; i<=size; i++)
    {
        // The parameter for dictionaryContains is 
        // str.substr(0, i) which is prefix (of input 
        // string) of length 'i'. We first check whether 
        // current prefix is in  dictionary. Then we 
        // recursively check for remaining string
        // str.substr(i, size-i) which is suffix of  
        // length size-i
        if (dictionaryContains( str.substr(0, i) ) &&
            wordBreak( str.substr(i, size-i) ))
            return true;
    }
  
    // If we have tried all prefixes and 
    // none of them worked
    return false;

326
Chapter 32. DP-32 | Word Break Problem

}
  
// Driver program to test above functions
int main()
{
    wordBreak("ilikesamsung")? cout <<"Yes\n": cout << "No\n";
    wordBreak("iiiiiiii")? cout <<"Yes\n": cout << "No\n";
    wordBreak("")? cout <<"Yes\n": cout << "No\n";
    wordBreak("ilikelikeimangoiii")? cout <<"Yes\n": cout << "No\n";
    wordBreak("samsungandmango")? cout <<"Yes\n": cout << "No\n";
    wordBreak("samsungandmangok")? cout <<"Yes\n": cout << "No\n";
    return 0;
}

Output:

Yes
Yes
Yes
Yes
Yes
No

Dynamic Programming
Why Dynamic Programming? The above problem exhibits overlapping sub-problems. For
example, see the following partial recursion tree for string “abcde” in worst case.

// A Dynamic Programming based program to test whether a given string can


// be segmented into space separated words in dictionary

327
Chapter 32. DP-32 | Word Break Problem

#include <iostream>
#include <string.h>
using namespace std;
  
/* A utility function to check whether a word is present in dictionary or not.
  An array of strings is used for dictionary.  Using array of strings for
  dictionary is definitely not a good idea. We have used for simplicity of
  the program*/
int dictionaryContains(string word)
{
    string dictionary[] = {"mobile","samsung","sam","sung","man","mango",
                           "icecream","and","go","i","like","ice","cream"};
    int size = sizeof(dictionary)/sizeof(dictionary[0]);
    for (int i = 0; i < size; i++)
        if (dictionary[i].compare(word) == 0)
           return true;
    return false;
}
  
// Returns true if string can be segmented into space separated
// words, otherwise returns false
bool wordBreak(string str)
{
    int size = str.size();
    if (size == 0)   return true;
  
    // Create the DP table to store results of subroblems. The value wb[i]
    // will be true if str[0..i-1] can be segmented into dictionary words,
    // otherwise false.
    bool wb[size+1];
    memset(wb, 0, sizeof(wb)); // Initialize all values as false.
  
    for (int i=1; i<=size; i++)
    {
        // if wb[i] is false, then check if current prefix can make it true.
        // Current prefix is "str.substr(0, i)"
        if (wb[i] == false && dictionaryContains( str.substr(0, i) ))
            wb[i] = true;
  
        // wb[i] is true, then check for all substrings starting from
        // (i+1)th character and store their results.
        if (wb[i] == true)
        {
            // If we reached the last prefix
            if (i == size)
                return true;
  
            for (int j = i+1; j <= size; j++)

328
Chapter 32. DP-32 | Word Break Problem

            {
                // Update wb[j] if it is false and can be updated
                // Note the parameter passed to dictionaryContains() is
                // substring starting from index 'i' and length 'j-i'
                if (wb[j] == false && dictionaryContains( str.substr(i, j-i) ))
                    wb[j] = true;
  
                // If we reached the last character
                if (j == size && wb[j] == true)
                    return true;
            }
        }
    }
  
    /* Uncomment these lines to print DP table "wb[]"
     for (int i = 1; i <= size; i++)
        cout << " " << wb[i]; */
  
    // If we have tried all prefixes and none of them worked
    return false;
}
  
// Driver program to test above functions
int main()
{
    wordBreak("ilikesamsung")? cout <<"Yes\n": cout << "No\n";
    wordBreak("iiiiiiii")? cout <<"Yes\n": cout << "No\n";
    wordBreak("")? cout <<"Yes\n": cout << "No\n";
    wordBreak("ilikelikeimangoiii")? cout <<"Yes\n": cout << "No\n";
    wordBreak("samsungandmango")? cout <<"Yes\n": cout << "No\n";
    wordBreak("samsungandmangok")? cout <<"Yes\n": cout << "No\n";
    return 0;
}

Output:

Yes
Yes
Yes
Yes
Yes
No

Optimized Dynamic Programming:


In this approach, apart from the dp table, we also maintain all the indexes which have
matched earlier. Then we will check the substrings from those indexes to the current index.
If anyone of that matches then we can divide the string up to that index.

329
Chapter 32. DP-32 | Word Break Problem

In this program, we are using some extra space. However, its time complexity is O(n*s)
where s is the length of the largest string in the dictionary and n is the length of the given
string.

// A Dynamic Programming based program to test


// whether a given string can  be segmented into
// space separated words in dictionary
#include <bits/stdc++.h>
using namespace std;
  
/* A utility function to check whether a word
   is present in dictionary or not. An array of 
   strings is used for dictionary.  Using array
   of strings for dictionary is definitely not 
   a good idea. We have used for simplicity of
   the program*/
int dictionaryContains(string word)
{
    string dictionary[] = { "mobile", "samsung", "sam",
                            "sung", "man", "mango",
                            "icecream", "and", "go",
                            "i", "like", "ice", "cream" };
    int size = sizeof(dictionary) / sizeof(dictionary[0]);
    for (int i = 0; i < size; i++)
        if (dictionary[i].compare(word) == 0)
            return true;
    return false;
}
  
// Returns true if string can be segmented into space
// separated words, otherwise returns false
bool wordBreak(string s)
{
    int n = s.size();
    if (n == 0)
        return true;
  
    // Create the DP table to store results of subroblems.
    // The value dp[i] will be true if str[0..i] can be
    // segmented into dictionary words, otherwise false.
    vector<bool> dp(n + 1, 0); // Initialize all values
    // as false.
  
    // matched_index array represents the indexes for which
    // dp[i] is true. Initially only -1 element is present
    // in this array.
    vector<int> matched_index;
    matched_index.push_back(-1);

330
Chapter 32. DP-32 | Word Break Problem

  
    for (int i = 0; i < n; i++) {
        int msize = matched_index.size();
  
        // Flag value which tells that a substring matches
        // with given words or not.
        int f = 0;
  
        // Check all the substring from the indexes matched
        // earlier. If any of that substring matches than
        // make flag value = 1;
        for (int j = msize - 1; j >= 0; j--) {
  
            // sb is substring starting from matched_index[j]
            // + 1  and of length i - matched_index[j]
            string sb = s.substr(matched_index[j] + 1, i - matched_index[j]);
  
            if (dictionaryContains(sb)) {
                f = 1;
                break;
            }
        }
  
        // If substring matches than do dp[i] = 1 and
        // push that index in matched_index array.
        if (f == 1) {
            dp[i] = 1;
            matched_index.push_back(i);
        }
    }
    return dp[n - 1];
}
  
// Driver code
int main()
{
    wordBreak("ilikesamsung") ? cout << "Yes\n" : cout << "No\n";
    wordBreak("iiiiiiii") ? cout << "Yes\n" : cout << "No\n";
    wordBreak("") ? cout << "Yes\n" : cout << "No\n";
    wordBreak("ilikelikeimangoiii") ? cout << "Yes\n" : cout << "No\n";
    wordBreak("samsungandmango") ? cout << "Yes\n" : cout << "No\n";
    wordBreak("samsungandmangok") ? cout << "Yes\n" : cout << "No\n";
    return 0;
}

Output:

331
Chapter 32. DP-32 | Word Break Problem

Yes
Yes
Yes
Yes
Yes
No

Word Break Problem | (Trie solution)


Exercise:
The above solutions only finds out whether a given string can be segmented or not. Extend
the above Dynamic Programming solution to print all possible partitions of input string.
Examples:

Input: ilikeicecreamandmango
Output:
i like ice cream and man go
i like ice cream and mango
i like icecream and man go
i like icecream and mango

Input: ilikesamsungmobile
Output:
i like sam sung mobile
i like samsung mobile

Refer below post for solution of exercise.


Word Break Problem using Backtracking

Source

https://www.geeksforgeeks.org/word-break-problem-dp-32/

332
Chapter 33

DP-33 | Find if a string is


interleaved of two other strings

Find if a string is interleaved of two other strings | DP-33 - GeeksforGeeks


Given three strings A, B and C. Write a function that checks whether C is an interleaving
of A and B. C is said to be interleaving A and B, if it contains all characters of A and B
and order of all characters in individual strings is preserved.
We have discussed a simple solution of this problem here. The simple solution doesn’t work
if strings A and B have some common characters. For example A = “XXY”, string B
= “XXZ” and string C = “XXZXXXY”. To handle all cases, two possibilities need to be
considered.
a) If first character of C matches with first character of A, we move one character ahead in
A and C and recursively check.
b) If first character of C matches with first character of B, we move one character ahead in
B and C and recursively check.
If any of the above two cases is true, we return true, else false. Following is simple recursive
implementation of this approach (Thanks to Fredericfor suggesting this)

// A simple recursive function to check whether C is an interleaving of A and B


bool isInterleaved(char *A, char *B, char *C)
{
    // Base Case: If all strings are empty
    if (!(*A || *B || *C))
        return true;
  
    // If C is empty and any of the two strings is not empty
    if (*C == '\0')
        return false;
  
    // If any of the above mentioned two possibilities is true,

333
Chapter 33. DP-33 | Find if a string is interleaved of two other strings

    // then return true, otherwise false


    return ( (*C == *A) && isInterleaved(A+1, B, C+1))
           || ((*C == *B) && isInterleaved(A, B+1, C+1));
}

Dynamic Programming
The worst case time complexity of recursive solution is O(2n ). The above recursive solution
certainly has many overlapping subproblems. For example, if wee consider A = “XXX”, B
= “XXX” and C = “XXXXXX” and draw recursion tree, there will be many overlapping
subproblems.
Therefore, like other typical Dynamic Programming problems, we can solve it by creating a
table and store results of subproblems in bottom up manner. Thanks to Abhinav Ramana
for suggesting this method and implementation.

// A Dynamic Programming based program to check whether a string C is


// an interleaving of two other strings A and B.
#include <iostream>
#include <string.h>
using namespace std;
  
// The main function that returns true if C is
// an interleaving of A and B, otherwise false.
bool isInterleaved(char* A, char* B, char* C)
{
    // Find lengths of the two strings
    int M = strlen(A), N = strlen(B);
  
    // Let us create a 2D table to store solutions of
    // subproblems.  C[i][j] will be true if C[0..i+j-1]
    // is an interleaving of A[0..i-1] and B[0..j-1].
    bool IL[M+1][N+1];
  
    memset(IL, 0, sizeof(IL)); // Initialize all values as false.
  
    // C can be an interleaving of A and B only of sum
    // of lengths of A & B is equal to length of C.
    if ((M+N) != strlen(C))
       return false;
  
    // Process all characters of A and B
    for (int i=0; i<=M; ++i)
    {
        for (int j=0; j<=N; ++j)
        {
            // two empty strings have an empty string
            // as interleaving
            if (i==0 && j==0)
                IL[i][j] = true;

334
Chapter 33. DP-33 | Find if a string is interleaved of two other strings

  
            // A is empty
            else if (i==0 && B[j-1]==C[j-1])
                IL[i][j] = IL[i][j-1];
  
            // B is empty
            else if (j==0 && A[i-1]==C[i-1])
                IL[i][j] = IL[i-1][j];
  
            // Current character of C matches with current character of A,
            // but doesn't match with current character of B
            else if(A[i-1]==C[i+j-1] && B[j-1]!=C[i+j-1])
                IL[i][j] = IL[i-1][j];
  
            // Current character of C matches with current character of B,
            // but doesn't match with current character of A
            else if (A[i-1]!=C[i+j-1] && B[j-1]==C[i+j-1])
                IL[i][j] = IL[i][j-1];
  
            // Current character of C matches with that of both A and B
            else if (A[i-1]==C[i+j-1] && B[j-1]==C[i+j-1])
                IL[i][j]=(IL[i-1][j] || IL[i][j-1]) ;
        }
    }
  
    return IL[M][N];
}
  
// A function to run test cases
void test(char *A, char *B, char *C)
{
    if (isInterleaved(A, B, C))
        cout << C <<" is interleaved of " << A <<" and " << B << endl;
    else
        cout << C <<" is not interleaved of " << A <<" and " << B << endl;
}
  
  
// Driver program to test above functions
int main()
{
    test("XXY", "XXZ", "XXZXXXY");
    test("XY" ,"WZ" ,"WZXY");
    test ("XY", "X", "XXY");
    test ("YX", "X", "XXY");
    test ("XXY", "XXZ", "XXXXZY");
    return 0;
}

335
Chapter 33. DP-33 | Find if a string is interleaved of two other strings

Output:

XXZXXXY is not interleaved of XXY and XXZ


WZXY is interleaved of XY and WZ
XXY is interleaved of XY and X
XXY is not interleaved of YX and X
XXXXZY is interleaved of XXY and XXZ

See thisfor more test cases.


Time Complexity: O(MN)
Auxiliary Space: O(MN)

Source

https://www.geeksforgeeks.org/find-if-a-string-is-interleaved-of-two-other-strings-dp-33/

336
Chapter 34

DP-34 | Assembly Line


Scheduling

Assembly Line Scheduling | DP-34 - GeeksforGeeks


A car factory has two assembly lines, each with n stations. A station is denoted by Si,j
where i is either 1 or 2 and indicates the assembly line the station is on, and j indicates
the number of the station. The time taken per station is denoted by ai,j . Each station is
dedicated to some sort of work like engine fitting, body fitting, painting and so on. So, a
car chassis must pass through each of the n stations in order before exiting the factory. The
parallel stations of the two assembly lines perform the same task. After it passes through
station Si,j , it will continue to station Si,j+1 unless it decides to transfer to the other line.
Continuing on the same line incurs no extra cost, but transferring from line i at station j –
1 to station j on the other line takes time ti,j . Each assembly line takes an entry time ei and
exit time xi which may be different for the two lines. Give an algorithm for computing the
minimum time it will take to build a car chassis.
The below figure presents the problem in a clear picture:

The following information can be extracted from the problem statement to make it simpler:

337
Chapter 34. DP-34 | Assembly Line Scheduling

• Two assembly lines, 1 and 2, each with stations from 1 to n.


• A car chassis must pass through all stations from 1 to n in order(in any of the two
assembly lines). i.e. it cannot jump from station i to station j if they are not at one
move distance.
• The car chassis can move one station forward in the same line, or one station diagonally
in the other line. It incurs an extra cost ti, j to move to station j from line i. No cost
is incurred for movement in same line.
• The time taken in station j on line i is ai, j .
• Si, j represents a station j on line i.

Breaking the problem into smaller sub-problems:


We can easily find the ith factorial if (i-1)th factorial is known. Can we apply the similar
funda here?
If the minimum time taken by the chassis to leave station Si, j-1 is known, the minimum
time taken to leave station Si, j can be calculated quickly by combining ai, j and ti, j .
T1(j) indicates the minimum time taken by the car chassis to leave station j on assembly
line 1.
T2(j) indicates the minimum time taken by the car chassis to leave station j on assembly
line 2.
Base cases:
The entry time ei comes into picture only when the car chassis enters the car factory.
Time taken to leave first station in line 1 is given by:
T1(1) = Entry time in Line 1 + Time spent in station S1,1
T1(1) = e1 + a1,1
Similarly, time taken to leave first station in line 2 is given by:
T2(1) = e2 + a2,1
Recursive Relations:
If we look at the problem statement, it quickly boils down to the below observations:
The car chassis at station S1,j can come either from station S1, j-1 or station S2, j-1 .
Case #1: Its previous station is S1, j-1
The minimum time to leave station S1,j is given by:
T1(j) = Minimum time taken to leave station S1, j-1 + Time spent in station S1, j
T1(j) = T1(j-1) + a1, j
Case #2: Its previous station is S2, j-1
The minimum time to leave station S1, j is given by:
T1(j) = Minimum time taken to leave station S2, j-1 + Extra cost incurred to change the
assembly line + Time spent in station S1, j
T1(j) = T2(j-1) + t2, j + a1, j
The minimum time T1(j) is given by the minimum of the two obtained in cases #1 and #2.
T1(j) = min((T1(j-1) + a1, j ), (T2(j-1) + t2, j + a1, j ))
Similarly the minimum time to reach station S2, j is given by:
T2(j) = min((T2(j-1) + a2, j ), (T1(j-1) + t1, j + a2, j ))

338
Chapter 34. DP-34 | Assembly Line Scheduling

The total minimum time taken by the car chassis to come out of the factory is given by:
Tmin = min(Time taken to leave station Si,n + Time taken to exit the car factory)
Tmin = min(T1(n) + x1 , T2(n) + x2 )
Why dynamic programming?
The above recursion exhibits overlapping sub-problems. There are two ways to reach station
S1, j :

1. From station S1, j-1


2. From station S2, j-1

So, to find the minimum time to leave station S1, j the minimum time to leave the previous
two stations must be calculated(as explained in above recursion).
Similarly, there are two ways to reach station S2, j :

1. From station S2, j-1


2. From station S1, j-1

Please note that the minimum times to leave stations S1, j-1 and S2, j-1 have already been
calculated.
So, we need two tables to store the partial results calculated for each station in an assembly
line. The table will be filled in bottom-up fashion.
Note:
In this post, the word “leave” has been used in place of “reach” to avoid the confusion. Since
the car chassis must spend a fixed time in each station, the word leave suits better.
Implementation:
C

// A C program to find minimum possible time by the car chassis to complete


#include <stdio.h>
#define NUM_LINE 2
#define NUM_STATION 4
  
// Utility function to find minimum of two numbers
int min(int a, int b) { return a < b ? a : b; }
  
int carAssembly(int a[][NUM_STATION], int t[][NUM_STATION], int *e, int *x)
{
    int T1[NUM_STATION], T2[NUM_STATION], i;
  
    T1[0] = e[0] + a[0][0]; // time taken to leave first station in line 1
    T2[0] = e[1] + a[1][0]; // time taken to leave first station in line 2
  
    // Fill tables T1[] and T2[] using the above given recursive relations
    for (i = 1; i < NUM_STATION; ++i)

339
Chapter 34. DP-34 | Assembly Line Scheduling

    {
        T1[i] = min(T1[i-1] + a[0][i], T2[i-1] + t[1][i] + a[0][i]);
        T2[i] = min(T2[i-1] + a[1][i], T1[i-1] + t[0][i] + a[1][i]);
    }
  
    // Consider exit times and retutn minimum
    return min(T1[NUM_STATION-1] + x[0], T2[NUM_STATION-1] + x[1]);
}
  
int main()
{
    int a[][NUM_STATION] = {{4, 5, 3, 2},
                {2, 10, 1, 4}};
    int t[][NUM_STATION] = {{0, 7, 4, 5},
                {0, 9, 2, 8}};
    int e[] = {10, 12}, x[] = {18, 7};
  
    printf("%d", carAssembly(a, t, e, x));
  
    return 0;
}

Output:

35

Java

// A java program to find minimum possible


// time by the car chassis to complete
import java.io.*;
  
class GFG 
{
    static int NUM_LINE = 2;
    static int NUM_STATION = 4;
      
    // Utility function to find minimum of two numbers
    static int min(int a, int b) 
    { 
        return a < b ? a : b; 
          
    }
      
    static int carAssembly(int a[][], int t[][], int e[], int x[])
    {
        int T1[]= new int [NUM_STATION];

340
Chapter 34. DP-34 | Assembly Line Scheduling

        int T2[] =new int[NUM_STATION] ;


        int i;
      
        // time taken to leave first station in line 1
        T1[0] = e[0] + a[0][0]; 
          
        // time taken to leave first station in line 2
        T2[0] = e[1] + a[1][0];
      
        // Fill tables T1[] and T2[] using 
        // the above given recursive relations
        for (i = 1; i < NUM_STATION; ++i)
        {
            T1[i] = min(T1[i - 1] + a[0][i], 
                    T2[i - 1] + t[1][i] + a[0][i]);
            T2[i] = min(T2[i - 1] + a[1][i], 
                    T1[i - 1] + t[0][i] + a[1][i]);
        }
      
        // Consider exit times and retutn minimum
        return min(T1[NUM_STATION-1] + x[0], 
                    T2[NUM_STATION-1] + x[1]);
    }
      
      
    // Driver code
    public static void main (String[] args) 
    {
        int a[][] = {{4, 5, 3, 2},
                    {2, 10, 1, 4}};
        int t[][] = {{0, 7, 4, 5},
                    {0, 9, 2, 8}};
        int e[] = {10, 12}, x[] = {18, 7};
      
        System.out.println(carAssembly(a, t, e, x));    
      
    }
}
// This code is contributed by vt_m

Python3

# Python program to find minimum possible 


# time by the car chassis to complete
  
def carAssembly (a, t, e, x):
      
    NUM_STATION = len(a[0])

341
Chapter 34. DP-34 | Assembly Line Scheduling

    T1 = [0 for i in range(NUM_STATION)]


    T2 = [0 for i in range(NUM_STATION)]
      
    T1[0] = e[0] + a[0][0] # time taken to leave
                           # first station in line 1
    T2[0] = e[1] + a[1][0] # time taken to leave
                           # first station in line 2
  
    # Fill tables T1[] and T2[] using
    # above given recursive relations
    for i in range(1, NUM_STATION):
        T1[i] = min(T1[i-1] + a[0][i],
                    T2[i-1] + t[1][i] + a[0][i])
        T2[i] = min(T2[i-1] + a[1][i],
                    T1[i-1] + t[0][i] + a[1][i] )
  
    # consider exit times and return minimum
    return min(T1[NUM_STATION - 1] + x[0],
               T2[NUM_STATION - 1] + x[1])
  
a = [[4, 5, 3, 2],
     [2, 10, 1, 4]]
t = [[0, 7, 4, 5],
     [0, 9, 2, 8]]
e = [10, 12]
x = [18, 7]
  
print(carAssembly(a, t, e, x))
  
# This code is contributed by Soumen Ghosh

C#

// A C# program to find minimum possible


// time by the car chassis to complete
using System;
  
class GFG {
      
    static int NUM_STATION = 4;
      
    // Utility function to find minimum 
    // of two numbers
    static int min(int a, int b) 
    { 
        return a < b ? a : b; 
          
    }

342
Chapter 34. DP-34 | Assembly Line Scheduling

      
    static int carAssembly(int [,]a, int [,]t,
                             int []e, int []x)
    {
        int []T1= new int [NUM_STATION];
        int []T2 =new int[NUM_STATION] ;
        int i;
      
        // time taken to leave first station
        // in line 1
        T1[0] = e[0] + a[0,0]; 
          
        // time taken to leave first station
        // in line 2
        T2[0] = e[1] + a[1,0];
      
        // Fill tables T1[] and T2[] using 
        // the above given recursive relations
        for (i = 1; i < NUM_STATION; ++i)
        {
            T1[i] = min(T1[i - 1] + a[0,i], 
                  T2[i - 1] + t[1,i] + a[0,i]);
            T2[i] = min(T2[i - 1] + a[1,i], 
                  T1[i - 1] + t[0,i] + a[1,i]);
        }
      
        // Consider exit times and retutn
        // minimum
        return min(T1[NUM_STATION-1] + x[0], 
                    T2[NUM_STATION-1] + x[1]);
    }
      
    // Driver code
    public static void Main () 
    {
        int [,]a = { {4, 5, 3, 2},
                     {2, 10, 1, 4} };
                       
        int [,]t = { {0, 7, 4, 5},
                     {0, 9, 2, 8} };
                       
        int []e = {10, 12};
        int []x = {18, 7};
      
        Console.Write(carAssembly(a, t, e, x)); 
      
    }
}

343
Chapter 34. DP-34 | Assembly Line Scheduling

  
// This code is contributed by nitin mittal.

PHP

<?php
// A PHP program to find minimum
// possible time by the car chassis
// to complete
  
$NUM_LINE = 2;
$NUM_STATION = 4;
  
// Utility function to find 
// minimum of two numbers
function carAssembly($a, $t, 
                     $e, $x)
{
    global $NUM_LINE,
           $NUM_STATION;
    $T1 = array(); 
    $T2 = array();
    $i;
  
    $T1[0] = $e[0] + $a[0][0]; // time taken to leave 
                               // first station in line 1
    $T2[0] = $e[1] + $a[1][0]; // time taken to leave 
                               // first station in line 2
  
    // Fill tables T1[] and T2[] 
    // using the above given
    // recursive relations
    for ($i = 1; 
         $i < $NUM_STATION; ++$i)
    {
        $T1[$i] = min($T1[$i - 1] + $a[0][$i], 
                      $T2[$i - 1] + $t[1][$i] + 
                                    $a[0][$i]);
        $T2[$i] = min($T2[$i - 1] + $a[1][$i], 
                      $T1[$i - 1] + $t[0][$i] + 
                                    $a[1][$i]);
    }
  
    // Consider exit times 
    // and return minimum
    return min($T1[$NUM_STATION - 1] + $x[0], 
               $T2[$NUM_STATION - 1] + $x[1]);
}

344
Chapter 34. DP-34 | Assembly Line Scheduling

  
// Driver Code
$a = array(array(4, 5, 3, 2),
           array(2, 10, 1, 4));
$t = array(array(0, 7, 4, 5),
           array(0, 9, 2, 8));
$e = array(10, 12);
$x = array(18, 7);
  
echo carAssembly($a, $t, $e, $x);
  
// This code is contributed
// by anuj_67.
?>

Output:

35

The bold line shows the path covered by the car chassis for given input values.
Exercise:
Extend the above algorithm to print the path covered by the car chassis in the factory.
References:
Introduction to Algorithms 3rd Edition by Clifford Stein, Thomas H. Cormen, Charles E.
Leiserson, Ronald L. Rivest
This article is compiled by Aashish Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal, vt_m

Source
https://www.geeksforgeeks.org/assembly-line-scheduling-dp-34/

345
Chapter 35

DP-35 | Longest Arithmetic


Progression

Longest Arithmetic Progression | DP-35 - GeeksforGeeks


Given a set of numbers, find the Length of the Longest Arithmetic Progression (LLAP) in
it.
Examples:

set[] = {1, 7, 10, 15, 27, 29}


output = 3
The longest arithmetic progression is {1, 15, 29}

set[] = {5, 10, 15, 20, 25, 30}


output = 6
The whole set is in AP

For simplicity, we have assumed that the given set is sorted. We can always add a pre-
processing step to first sort the set and then apply the below algorithms.
A simple solution is to one by one consider every pair as first two elements of AP and
check for the remaining elements in sorted set. To consider all pairs as first two elements,
we need to run a O(n^2) nested loop. Inside the nested loops, we need a third loop which
linearly looks for the more elements in Arithmetic Progression (AP). This process takes
O(n3 ) time.
We can solve this problem in O(n2 ) time using Dynamic Programming. To get idea of
the DP solution, let us first discuss solution of following simpler problem.
Given a sorted set, find if there exist three elements in Arithmetic Progression
or not
Please note that, the answer is true if there are 3 or more elements in AP, otherwise false.

346
Chapter 35. DP-35 | Longest Arithmetic Progression

To find the three elements, we first fix an element as middle element and search for other
two (one smaller and one greater). We start from the second element and fix every element
as middle element. For an element set[j] to be middle of AP, there must exist elements ‘set[i]’
and ‘set[k]’ such that set[i] + set[k] = 2*set[j] where 0 <= i < j and j < k <=n-1. How
to efficiently find i and k for a given j? We can find i and k in linear time using following
simple algorithm.

1. Initialize i as j-1 and k as j+1


2. • If set[i] + set[k] is equal to 2*set[j], then we are done.
• If set[i] + set[k] > 2*set[j], then decrement i (do i–).
• Else if set[i] + set[k] < 2*set[j], then increment k (do k++).

Following is C++ implementation of the above algorithm for the simpler problem.

// The function returns true if there exist three elements in AP


// Assumption: set[0..n-1] is sorted. 
// The code strictly implements the algorithm provided in the reference.
bool arithmeticThree(int set[], int n)
{
    // One by fix every element as middle element
    for (int j=1; j<n-1; j++)
    {
        // Initialize i and k for the current j
        int i = j-1, k = j+1;
  
        // Find if there exist i and k that form AP
        // with j as middle element
        while (i >= 0 && k <= n-1)
        {
            if (set[i] + set[k] == 2*set[j])
                return true;
            (set[i] + set[k] < 2*set[j])? k++ : i--;
        }
    }
  
    return false;
}

See thisfor a complete running program.


How to extend the above solution for the original problem?
The above function returns a boolean value. The required output of original problem is
Length of the Longest Arithmetic Progression (LLAP) which is an integer value. If the
given set has two or more elements, then the value of LLAP is at least 2 (Why?).
The idea is to create a 2D table L[n][n]. An entry L[i][j] in this table stores LLAP with set[i]
and set[j] as first two elements of AP and j > i. The last column of the table is always 2
(Why – see the meaning of L[i][j]). Rest of the table is filled from bottom right to top left.

347
Chapter 35. DP-35 | Longest Arithmetic Progression

To fill rest of the table, j (second element in AP) is first fixed. i and k are searched for a
fixed j. If i and k are found such that i, j, k form an AP, then the value of L[i][j] is set as
L[j][k] + 1. Note that the value of L[j][k] must have been filled before as the loop traverses
from right to left columns.
Following is the implementation of the Dynamic Programming algorithm.

C++

// C++ program to find Length of the Longest AP (llap) in a given sorted set.
// The code strictly implements the algorithm provided in the reference.
#include <iostream>
using namespace std;
  
// Returns length of the longest AP subset in a given set
int lenghtOfLongestAP(int set[], int n)
{
    if (n <= 2)  return n;
  
    // Create a table and initialize all values as 2. The value of
    // L[i][j] stores LLAP with set[i] and set[j] as first two
    // elements of AP. Only valid entries are the entries where j>i
    int L[n][n];
    int llap = 2;  // Initialize the result
  
    // Fill entries in last column as 2. There will always be
    // two elements in AP with last number of set as second
    // element in AP
    for (int i = 0; i < n; i++)
        L[i][n-1] = 2;
  
    // Consider every element as second element of AP
    for (int j=n-2; j>=1; j--)
    {
        // Search for i and k for j
        int i = j-1, k = j+1;
        while (i >= 0 && k <= n-1)
        {
           if (set[i] + set[k] < 2*set[j])
               k++;
  
           // Before changing i, set L[i][j] as 2
           else if (set[i] + set[k] > 2*set[j])
           {   L[i][j] = 2, i--;   }
  
           else
           {
               // Found i and k for j, LLAP with i and j as first two

348
Chapter 35. DP-35 | Longest Arithmetic Progression

               // elements is equal to LLAP with j and k as first two


               // elements plus 1. L[j][k] must have been filled
               // before as we run the loop from right side
               L[i][j] = L[j][k] + 1;
  
               // Update overall LLAP, if needed
               llap = max(llap, L[i][j]);
  
               // Change i and k to fill more L[i][j] values for
               // current j
               i--; k++;
           }
        }
  
        // If the loop was stopped due to k becoming more than
        // n-1, set the remaining entties in column j as 2
        while (i >= 0)
        {
            L[i][j] = 2;
            i--;
        }
    }
    return llap;
}
  
/* Drier program to test above function*/
int main()
{
    int set1[] = {1, 7, 10, 13, 14, 19};
    int n1 = sizeof(set1)/sizeof(set1[0]);
    cout <<   lenghtOfLongestAP(set1, n1) << endl;
  
    int set2[] = {1, 7, 10, 15, 27, 29};
    int n2 = sizeof(set2)/sizeof(set2[0]);
    cout <<   lenghtOfLongestAP(set2, n2) << endl;
  
    int set3[] = {2, 4, 6, 8, 10};
    int n3 = sizeof(set3)/sizeof(set3[0]);
    cout <<   lenghtOfLongestAP(set3, n3) << endl;
  
    return 0;
}

Java

// Java program to find Length of the


// Longest AP (llap) in a given sorted set.
// The code strictly implements the 

349
Chapter 35. DP-35 | Longest Arithmetic Progression

// algorithm provided in the reference.


import java.io.*;
  
class GFG 
{
    // Returns length of the longest 
    // AP subset in a given set
    static int lenghtOfLongestAP(int set[], int n)
    {
        if (n <= 2) return n;
      
        // Create a table and initialize all 
        // values as 2. The value ofL[i][j] stores 
        // LLAP with set[i] and set[j] as first two
        // elements of AP. Only valid entries are 
        // the entries where j>i
        int L[][] = new int[n][n];
          
         // Initialize the result
        int llap = 2;
      
        // Fill entries in last column as 2. 
        // There will always be two elements in 
        // AP with last number of set as second
        // element in AP
        for (int i = 0; i < n; i++)
            L[i][n - 1] = 2;
      
        // Consider every element as second element of AP
        for (int j = n - 2; j >= 1; j--)
        {
            // Search for i and k for j
            int i = j -1 , k = j + 1;
            while (i >= 0 && k <= n - 1)
            {
            if (set[i] + set[k] < 2 * set[j])
                k++;
      
            // Before changing i, set L[i][j] as 2
            else if (set[i] + set[k] > 2 * set[j])
            { 
                L[i][j] = 2; i--; 
                  
            }
      
            else
            {
                // Found i and k for j, LLAP with i and j as first two

350
Chapter 35. DP-35 | Longest Arithmetic Progression

                // elements is equal to LLAP with j and k as first two


                // elements plus 1. L[j][k] must have been filled
                // before as we run the loop from right side
                L[i][j] = L[j][k] + 1;
      
                // Update overall LLAP, if needed
                llap = Math.max(llap, L[i][j]);
      
                // Change i and k to fill 
                // more L[i][j] values for current j
                i--; k++;
            }
            }
      
            // If the loop was stopped due
            // to k becoming more than
            // n-1, set the remaining 
            // entties in column j as 2
            while (i >= 0)
            {
                L[i][j] = 2;
                i--;
            }
        }
        return llap;
    }
      
    // Driver program 
    public static void main (String[] args) 
    {
        int set1[] = {1, 7, 10, 13, 14, 19};
        int n1 = set1.length;
        System.out.println ( lenghtOfLongestAP(set1, n1));
      
        int set2[] = {1, 7, 10, 15, 27, 29};
        int n2 = set2.length;
        System.out.println(lenghtOfLongestAP(set2, n2));
      
        int set3[] = {2, 4, 6, 8, 10};
        int n3 = set3.length;
        System.out.println(lenghtOfLongestAP(set3, n3)) ;
      
      
    }
}
  
// This code is contributed by vt_m

351
Chapter 35. DP-35 | Longest Arithmetic Progression

Output:

4
3
5

Time Complexity: O(n2 )


Auxiliary Space: O(n2 )
References:
http://www.cs.uiuc.edu/~jeffe/pubs/pdf/arith.pdf

Source

https://www.geeksforgeeks.org/longest-arithmetic-progression-dp-35/

352
Chapter 36

DP-36 | Maximum Product


Cutting

Maximum Product Cutting | DP-36 - GeeksforGeeks


Given a rope of length n meters, cut the rope in different parts of integer lengths in a way
that maximizes product of lengths of all parts. You must make at least one cut. Assume
that the length of rope is more than 2 meters.
Examples:

Input: n = 2
Output: 1 (Maximum obtainable product is 1*1)

Input: n = 3
Output: 2 (Maximum obtainable product is 1*2)

Input: n = 4
Output: 4 (Maximum obtainable product is 2*2)

Input: n = 5
Output: 6 (Maximum obtainable product is 2*3)

Input: n = 10
Output: 36 (Maximum obtainable product is 3*3*4)

1) Optimal Substructure:
This problem is similar to Rod Cutting Problem. We can get the maximum product by
making a cut at different positions and comparing the values obtained after a cut. We can
recursively call the same function for a piece obtained after a cut.
Let maxProd(n) be the maximum product for a rope of length n. maxProd(n) can be
written as following.

353
Chapter 36. DP-36 | Maximum Product Cutting

maxProd(n) = max(i*(n-i), maxProdRec(n-i)*i) for all i in {1, 2, 3 .. n}


2) Overlapping Subproblems
Following is simple recursive implementation of the problem. The implementation simply
follows the recursive structure mentioned above.

C++

// A Naive Recursive method to find maxium product


#include <iostream>
using namespace std;
  
// Utility function to get the maximum of two and three integers
int max(int a, int b) { return (a > b)? a : b;}
int max(int a, int b, int c) { return max(a, max(b, c));}
  
// The main function that returns maximum product obtainable
// from a rope of length n
int maxProd(int n)
{
    // Base cases
    if (n == 0 || n == 1) return 0;
  
    // Make a cut at different places and take the maximum of all
    int max_val = 0;
    for (int i = 1; i < n; i++)
      max_val = max(max_val, i*(n-i), maxProd(n-i)*i);
  
    // Return the maximum of all values
    return max_val;
}
  
/* Driver program to test above functions */
int main()
{
    cout << "Maximum Product is " << maxProd(10);
    return 0;
}

Java

// Java program to find maxium product


import java.io.*;
  
class GFG {
  
    // The main function that returns 

354
Chapter 36. DP-36 | Maximum Product Cutting

    // maximum product obtainable from 


    // a rope of length n
    static int maxProd(int n)
    {
        // Base cases
        if (n == 0 || n == 1) return 0;
  
        // Make a cut at different places
        // and take the maximum of all
        int max_val = 0;
        for (int i = 1; i < n; i++)
        max_val = Math.max(max_val,
                  Math.max(i * (n - i),
                   maxProd(n - i) * i));
  
        // Return the maximum of all values
        return max_val;
    }   
  
    /* Driver program to test above functions */
    public static void main(String[] args)
    {
        System.out.println("Maximum Product is " 
                            + maxProd(10));
    }
}
// This code is contributed by Prerna Saini

Python3

# The main function that returns maximum


# product obtainable from a rope of length n
  
def maxProd(n):
      
    # Base cases
    if (n == 0 or n == 1):
        return 0
   
    # Make a cut at different places
    # and take the maximum of all
    max_val = 0
    for i in range(1, n - 1):
        max_val = max(max_val, max(i * (n - i), maxProd(n - i) * i))
   
    #Return the maximum of all values
    return max_val;
  

355
Chapter 36. DP-36 | Maximum Product Cutting

   
# Driver program to test above functions 
print("Maximum Product is ", maxProd(10));
      
# This cide is contributed
# by Sumit Sudhakar

C#

// C# program to find maxium product


using System;
  
class GFG {
      
    // The main function that returns  
    // the max possible product 
    static int maxProd(int n)
    {
  
        // n equals to 2 or 3 must 
        // be handled explicitly
        if (n == 2 || n == 3)
            return (n - 1);
  
        // Keep removing parts of size 
        // 3 while n is greater than 4
        int res = 1;
        while (n > 4) {
            n -= 3;
  
            // Keep multiplying 3 to res
            res *= 3;
        }
  
        // The last part multiplied 
        // by previous parts
        return (n * res);
    }
  
    // Driver code
    public static void Main()
    {
        Console.WriteLine("Maximum Product is "
                                + maxProd(10));
    }
}
  
// This code is contributed by Sam007

356
Chapter 36. DP-36 | Maximum Product Cutting

Output:

Maximum Product is 36

Considering the above implementation, following is recursion tree for a Rope of length 5.

In the above partial recursion tree, mP(3) is being solved twice. We can see that there
are many subproblems which are solved again and again. Since same suproblems are called
again, this problem has Overlapping Subprolems property. So the problem has both prop-
erties (see thisand this) of a dynamic programming problem. Like other typical Dynamic
Programming(DP) problems, recomputations of same subproblems can be avoided by con-
structing a temporary array val[] in bottom up manner.

// A Dynamic Programming solution for Max Product Problem


int maxProd(int n)
{
   int val[n+1];
   val[0] = val[1] = 0;
   
   // Build the table val[] in bottom up manner and return
   // the last entry from the table
   for (int i = 1; i <= n; i++)
   {
      int max_val = 0;
      for (int j = 1; j <= i/2; j++)
         max_val = max(max_val, (i-j)*j, j*val[i-j]);

357
Chapter 36. DP-36 | Maximum Product Cutting

      val[i] = max_val;
   }
   return val[n];
}

Time Complexity of the Dynamic Programming solution is O(n^2) and it requires O(n)
extra space.
A Tricky Solution:
If we see some examples of this problems, we can easily observe following pattern.
The maximum product can be obtained be repeatedly cutting parts of size 3 while size
is greater than 4, keeping the last part as size of 2 or 3 or 4. For example, n = 10, the
maximum product is obtained by 3, 3, 4. For n = 11, the maximum product is obtained
by 3, 3, 3, 2. Following is the implementation of this approach.

C++

#include <iostream>
using namespace std;
  
/* The main function that teturns the max possible product */
int maxProd(int n)
{
   // n equals to 2 or 3 must be handled explicitly
   if (n == 2 || n == 3) return (n-1);
  
   // Keep removing parts of size 3 while n is greater than 4
   int res = 1;
   while (n > 4)
   {
       n -= 3;
       res *= 3; // Keep multiplying 3 to res
   }
   return (n * res); // The last part multiplied by previous parts
}
  
/* Driver program to test above functions */
int main()
{
    cout << "Maximum Product is " << maxProd(10);
    return 0;
}

Java

// Java program to find maximum product


import java.io.*;

358
Chapter 36. DP-36 | Maximum Product Cutting

  
class GFG {
  
    /* The main function that returns the 
    max possible product */
    static int maxProd(int n)
    {
      
    // n equals to 2 or 3 must be handled
    // explicitly
    if (n == 2 || n == 3) return (n-1);
  
    // Keep removing parts of size 3 
    // while n is greater than 4
    int res = 1;
    while (n > 4)
    {
        n -= 3;
          
        // Keep multiplying 3 to res
        res *= 3; 
    }
      
    // The last part multiplied by 
    // previous parts
    return (n * res); 
    }
  
    /* Driver program to test above functions */
    public static void main(String[] args)
    {
        System.out.println("Maximum Product is "
                            + maxProd(10));
    }   
}
// This code is contributed by Prerna Saini

Python3

# The main function that returns the 


# max possible product
  
def maxProd(n):
      
    # n equals to 2 or 3 must
    # be handled explicitly
    if (n == 2 or n == 3):
        return (n - 1)

359
Chapter 36. DP-36 | Maximum Product Cutting

   
    # Keep removing parts of size 3 
    # while n is greater than 4
    res = 1
    while (n > 4):
        n -= 3;
           
        # Keep multiplying 3 to res
        res *= 3; 
      
    # The last part multiplied 
    # by previous parts
    return (n * res)
  
# Driver program to test above functions 
print("Maximum Product is ", maxProd(10));
      
# This code is contributed 
# by Sumit Sudhakar

C#

// C# program to find maxium product


using System;
  
class GFG {
  
    // The main function that returns
    // maximum product obtainable from
    // a rope of length n
    static int maxProd(int n)
    {
        // Base cases
        if (n == 0 || n == 1)
            return 0;
  
        // Make a cut at different places
        // and take the maximum of all
        int max_val = 0;
        for (int i = 1; i < n; i++)
            max_val = Math.Max(max_val,
                    Math.Max(i * (n - i),
                     maxProd(n - i) * i));
  
        // Return the maximum of all values
        return max_val;
    }
  

360
Chapter 36. DP-36 | Maximum Product Cutting

    // Driver code


    public static void Main()
     {
        Console.WriteLine("Maximum Product is "
                                + maxProd(10));
     }
}
  
// This code is contributed by Sam007

PHP

<?php
  
/* The main function that returns 
   the max possible product */
function maxProd($n)
{
      
// n equals to 2 or 3 must
// be handled explicitly
if ($n == 2 || $n == 3) 
    return ($n - 1);
  
// Keep removing parts of size 
// 3 while n is greater than 4
$res = 1;
while ($n > 4)
{
    $n = $n - 3;
      
    // Keep multiplying 3 to res
    $res = $res * 3; 
}
  
// The last part multiplied
// by previous parts
return ($n * $res); 
}
  
// Driver code
echo ("Maximum Product is ");
echo(maxProd(10));
  
// This code is contributed 
// by Shivi_Aggarwal 
?>

361
Chapter 36. DP-36 | Maximum Product Cutting

Output:

Maximum Product is 36

Improved By : Shivi_Aggarwal

Source

https://www.geeksforgeeks.org/maximum-product-cutting-dp-36/

362
Chapter 37

DP-37 | Boolean
Parenthesization Problem

Boolean Parenthesization Problem | DP-37 - GeeksforGeeks


Given a boolean expression with following symbols.

Symbols
'T' ---> true
'F' ---> false

And following operators filled between symbols

Operators
& ---> boolean AND
| ---> boolean OR
^ ---> boolean XOR

Count the number of ways we can parenthesize the expression so that the value of expression
evaluates to true.
Let the input be in form of two arrays one contains the symbols (T and F) in order and
other contains operators (&, | and ^}
Examples:

Input: symbol[] = {T, F, T}


operator[] = {^, &}
Output: 2

363
Chapter 37. DP-37 | Boolean Parenthesization Problem

The given expression is "T ^ F & T", it evaluates true


in two ways "((T ^ F) & T)" and "(T ^ (F & T))"

Input: symbol[] = {T, F, F}


operator[] = {^, |}
Output: 2
The given expression is "T ^ F | F", it evaluates true
in two ways "( (T ^ F) | F )" and "( T ^ (F | F) )".

Input: symbol[] = {T, T, F, T}


operator[] = {|, &, ^}
Output: 4
The given expression is "T | T & F ^ T", it evaluates true
in 4 ways ((T|T)&(F^T)), (T|(T&(F^T))), (((T|T)&F)^T)
and (T|((T&F)^T)).

Solution:
Let T(i, j) represents the number of ways to parenthesize the symbols between i and j
(both inclusive) such that the subexpression between i and j evaluates to true.

Let F(i, j) represents the number of ways to parenthesize the symbols between i and j (both
inclusive) such that the subexpression between i and j evaluates to false.

Base Cases:

T(i, i) = 1 if symbol[i] = 'T'


T(i, i) = 0 if symbol[i] = 'F'

F(i, i) = 1 if symbol[i] = 'F'


F(i, i) = 0 if symbol[i] = 'T'

364
Chapter 37. DP-37 | Boolean Parenthesization Problem

If we draw recursion tree of above recursive solution, we can observe that it many overlapping
subproblems. Like other dynamic programming problems, it can be solved by filling a table
in bottom up manner. Following is C++ implementation of dynamic programming solution.

#include<iostream>
#include<cstring>
using namespace std;
  
// Returns count of all possible parenthesizations that lead to
// result true for a boolean expression with symbols like true
// and false and operators like &, | and ^ filled between symbols
int countParenth(char symb[], char oper[], int n)
{
    int F[n][n], T[n][n];
  
    // Fill diaginal entries first
    // All diagonal entries in T[i][i] are 1 if symbol[i]
    // is T (true).  Similarly, all F[i][i] entries are 1 if
    // symbol[i] is F (False)
    for (int i = 0; i < n; i++)
    {
        F[i][i] = (symb[i] == 'F')? 1: 0;
        T[i][i] = (symb[i] == 'T')? 1: 0;
    }
  
    // Now fill T[i][i+1], T[i][i+2], T[i][i+3]... in order
    // And F[i][i+1], F[i][i+2], F[i][i+3]... in order
    for (int gap=1; gap<n; ++gap)
    {
        for (int i=0, j=gap; j<n; ++i, ++j)
        {
            T[i][j] = F[i][j] = 0;
            for (int g=0; g<gap; g++)
            {
                // Find place of parenthesization using current value
                // of gap
                int k = i + g;
  
                // Store Total[i][k] and Total[k+1][j]
                int tik = T[i][k] + F[i][k];
                int tkj = T[k+1][j] + F[k+1][j];
  
                // Follow the recursive formulas according to the current
                // operator
                if (oper[k] == '&')
                {
                    T[i][j] += T[i][k]*T[k+1][j];
                    F[i][j] += (tik*tkj - T[i][k]*T[k+1][j]);

365
Chapter 37. DP-37 | Boolean Parenthesization Problem

                }
                if (oper[k] == '|')
                {
                    F[i][j] += F[i][k]*F[k+1][j];
                    T[i][j] += (tik*tkj - F[i][k]*F[k+1][j]);
                }
                if (oper[k] == '^')
                {
                    T[i][j] += F[i][k]*T[k+1][j] + T[i][k]*F[k+1][j];
                    F[i][j] += T[i][k]*T[k+1][j] + F[i][k]*F[k+1][j];
                }
            }
        }
    }
    return T[0][n-1];
}
  
// Driver program to test above function
int main()
{
    char symbols[] = "TTFT";
    char operators[] = "|&^";
    int n = strlen(symbols);
  
    // There are 4 ways
    // ((T|T)&(F^T)), (T|(T&(F^T))), (((T|T)&F)^T) and (T|((T&F)^T))
    cout << countParenth(symbols, operators, n);
    return 0;
}

Output:

Time Complexity: O(n3 )


Auxiliary Space: O(n2 )
References:
http://people.cs.clemson.edu/~bcdean/dp_practice/dp_9.swf

Source

https://www.geeksforgeeks.org/boolean-parenthesization-problem-dp-37/

366
Chapter 38

A Space Optimized DP solution


for 0-1 Knapsack Problem

A Space Optimized DP solution for 0-1 Knapsack Problem - GeeksforGeeks


Given weights and values of n items, put these items in a knapsack of capacity W to get the
maximum total value in the knapsack. In other words, given two integer arrays val[0..n-1]
and wt[0..n-1] which represent values and weights associated with n items respectively. Also
given an integer W which represents knapsack capacity, find out the maximum value subset
of val[] such that sum of the weights of this subset is smaller than or equal to W. We cannot
break an item, either pick the complete item, or don’t pick it (0-1 property).
Here W <= 2000000 and n <= 500
Examples:

Input : W = 10, n = 3
val[] = {7, 8, 4}
wt[] = {3, 8, 6}
Output: 11
We get maximum value by picking items of 3 KG and 6 KG.

We have discussed a Dynamic Programming based solution here. In the previous solution, we
used a n * W matrix. We can reduce the used extra space. The idea behind the optimization
is, to compute mat[i][j], we only need solution of previous row. In 0-1 Knapsack Problem if
we are currently on mat[i][j] and we include ith element then we move j-wt[i] steps back in
previous row and if we exclude the current element we move on jth column in previous row.
So here we can observe that at a time we are working only with 2 consecutive rows.
In below solution, we create a matrix of size 2*W. If n is odd, then final answer will be at
mat[0][W] and if n is even then final answer will be at mat[1][W] because index starts from
0.

367
Chapter 38. A Space Optimized DP solution for 0-1 Knapsack Problem

// C++ program of a space optimized DP solution for


// 0-1 knapsack problem.
#include<bits/stdc++.h>
using namespace std;
  
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// mat[2][W+1] to store final result
int KnapSack(int val[], int wt[], int n, int W)
{
    // matrix to store final result
    int mat[2][W+1];
    memset(mat, 0, sizeof(mat));
  
    // iterate through all items
    int i = 0;
    while (i < n) // one by one traverse each element
    {
        int j = 0; // traverse all wieghts j <= W
  
        // if i is odd that mean till now we have odd
        // number of elements so we store result in 1th
        // indexed row
        if (i%2!=0)
        {
            while (++j <= W) // check for each value
            {
                if (wt[i] <= j) // include element
                    mat[1][j] = max(val[i] + mat[0][j-wt[i]],
                                    mat[0][j] );
                else           // exclude element
                    mat[1][j] = mat[0][j];
            }
  
        }
  
        // if i is even that mean till now we have even number
        // of elements so we store result in 0th indexed row
        else
        {
            while(++j <= W)
            {
                if (wt[i] <= j)
                    mat[0][j] = max(val[i] + mat[1][j-wt[i]],
                                     mat[1][j]);
                else

368
Chapter 38. A Space Optimized DP solution for 0-1 Knapsack Problem

                    mat[0][j] = mat[1][j];
            }
        }
        i++;
    }
  
    // Return mat[0][W] if n is odd, else mat[1][W]
    return (n%2 != 0)? mat[0][W] : mat[1][W];
}
  
// Driver program to test the cases
int main()
{
    int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
    cout << KnapSack(val, wt, n, W) << endl;
    return 0;
}

Output:

11

Time Complexity : O(n * W)


Auxiliary Space : O(W)
Here is an optimized code contributed by Gaurav Mamgain

// C++ program of a space optimized DP solution for


// 0-1 knapsack problem.
#include<bits/stdc++.h>
using namespace std;
  
// val[] is for storing maximum profit for each weight
// wt[] is for storing weights
// n number of item
// W maximum capacity of bag
// dp[W+1] to store final result
int KnapSack(int val[], int wt[], int n, int W)
{
    // array to store final result
    //dp[i] stores the profit with KnapSack capacity "i"
    int dp[W+1];
      
    //initially profit with 0 to W KnapSack capacity is 0
    memset(dp, 0, sizeof(dp));
  
    // iterate through all items

369
Chapter 38. A Space Optimized DP solution for 0-1 Knapsack Problem

    for(int i=0; i < n; i++) 


        //traverse dp array from right to left
        for(int j=W; j>=wt[i]; j--)
            dp[j] = max(dp[j] , val[i] + dp[j-wt[i]]);
    /*above line finds out maximum of  dp[j](excluding ith element value)
      and val[i] + dp[j-wt[i]] (including ith element value and the
      profit with "KnapSack capacity - ith element weight") */  
    return dp[W];
}
  
// Driver program to test the cases
int main()
{
    int val[] = {7, 8, 4}, wt[] = {3, 8, 6}, W = 10, n = 3;
    cout << KnapSack(val, wt, n, W) << endl;
    return 0;
}
  
// This code is contributed by Gaurav Mamgain

Output:

11

This article is contributed by Shashank Mishra ( Gullu ). This article is reviwed by


team geeksforgeeks.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.

Source

https://www.geeksforgeeks.org/space-optimized-dp-solution-0-1-knapsack-problem/

370
Chapter 39

A Space Optimized Solution of


LCS

A Space Optimized Solution of LCS - GeeksforGeeks


Given two strings, find the length of longest subsequence present in both of them.
Examples:
LCS for input Sequences “ABCDGH” and “AEDFHR” is “ADH” of length 3.
LCS for input Sequences “AGGTAB” and “GXTXAYB” is “GTAB” of length 4.
We have discussed typical dynamic programming based solution for LCS. We can optimize
space used by lcs problem. We know recurrence relation of LCS problem is

/* Returns length of LCS for X[0..m-1], Y[0..n-1] */


int lcs(string &X, string &Y)
{
    int m = X.length(), n = Y.length();
    int L[m+1][n+1];
  
    /* Following steps build L[m+1][n+1] in bottom up
       fashion. Note that L[i][j] contains length of
       LCS of X[0..i-1] and Y[0..j-1] */
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
  
            else if (X[i-1] == Y[j-1])
                L[i][j] = L[i-1][j-1] + 1;
  
            else

371
Chapter 39. A Space Optimized Solution of LCS

                L[i][j] = max(L[i-1][j], L[i][j-1]);


        }
    }
  
    /* L[m][n] contains length of LCS for X[0..n-1] and
       Y[0..m-1] */
    return L[m][n];
}

How to find length of LCS in O(n) auxiliary space?

We strongly recommend that you click here and practice it, before moving on
to the solution.
One important observation in above simple implementation is, in each iteration of outer
loop we only, need values from all columns of previous row. So there is no need of
storing all rows in our DP matrix, we can just store two rows at a time and use them, in that
way used space will reduce from L[m+1][n+1] to L[2][n+1]. Below is the implementation
of above idea.

C++

// Space optimized C++ implementation


// of LCS problem 
#include<bits/stdc++.h>
using namespace std;
  
// Returns length of LCS 
// for X[0..m-1], Y[0..n-1] 
int lcs(string &X, string &Y)
{
      
    // Find lengths of two strings
    int m = X.length(), n = Y.length();
  
    int L[2][n + 1];
  
    // Binary index, used to
    // index current row and
    // previous row.
    bool bi;
  
    for (int i = 0; i <= m; i++)
    {
          
        // Compute current 
        // binary index

372
Chapter 39. A Space Optimized Solution of LCS

        bi = i & 1;
  
        for (int j = 0; j <= n; j++)
        {
            if (i == 0 || j == 0)
                L[bi][j] = 0;
  
            else if (X[i-1] == Y[j-1])
                 L[bi][j] = L[1 - bi][j - 1] + 1;
  
            else
                L[bi][j] = max(L[1 - bi][j], 
                               L[bi][j - 1]);
        }
    }
  
    // Last filled entry contains
    // length of LCS
    // for X[0..n-1] and Y[0..m-1] 
    return L[bi][n];
}
  
// Driver code
int main()
{
    string X = "AGGTAB";
    string Y = "GXTXAYB";
  
    printf("Length of LCS is %d\n", lcs(X, Y));
  
    return 0;
}

Java

// Java Code for A Space Optimized 


// Solution of LCS
  
class GFG {
      
    // Returns length of LCS 
    // for X[0..m - 1],
    // Y[0..n - 1] 
    public static int lcs(String X, 
                          String Y)
    {
          
        // Find lengths of two strings

373
Chapter 39. A Space Optimized Solution of LCS

        int m = X.length(), n = Y.length();


      
        int L[][] = new int[2][n+1];
      
        // Binary index, used to index 
        // current row and previous row.
        int bi=0;
      
        for (int i = 0; i <= m; i++)
        {
              
            // Compute current binary index
            bi = i & 1;
      
            for (int j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    L[bi][j] = 0;
      
                else if (X.charAt(i - 1) == 
                         Y.charAt(j - 1))
                    L[bi][j] = L[1 - bi][j - 1] + 1;
      
                else
                    L[bi][j] = Math.max(L[1 - bi][j], 
                                        L[bi][j - 1]);
            }
        }
      
        // Last filled entry contains length of 
        // LCS for X[0..n-1] and Y[0..m-1] 
        return L[bi][n];
    }
      
      
    // Driver Code 
    public static void main(String[] args) 
    {
        String X = "AGGTAB";
        String Y = "GXTXAYB";
      
        System.out.println("Length of LCS is " +
                                    lcs(X, Y));
    }
}
  
// This code is contributed by Arnav Kr. Mandal.

374
Chapter 39. A Space Optimized Solution of LCS

Python3

# Space optimized Python


# implementation of LCS problem
  
# Returns length of LCS for 
# X[0..m-1], Y[0..n-1]
def lcs(X, Y):
      
    # Find lengths of two strings
    m = len(X)
    n = len(Y)
  
    L = [[0 for i in range(n+1)] for j in range(2)]
  
    # Binary index, used to index current row and
    # previous row.
    bi = bool
      
    for i in range(m):
        # Compute current binary index
        bi = i&1
  
        for j in range(n+1):
            if (i == 0 or j == 0):
                L[bi][j] = 0
  
            elif (X[i] == Y[j - 1]):
                L[bi][j] = L[1 - bi][j - 1] + 1
  
            else:
                L[bi][j] = max(L[1 - bi][j], 
                               L[bi][j - 1])
  
    # Last filled entry contains length of LCS
    # for X[0..n-1] and Y[0..m-1]
    return L[bi][n]
  
# Driver Code
X = "AGGTAB"
Y = "GXTXAYB"
  
print("Length of LCS is", lcs(X, Y))
  
# This code is contributed by Soumen Ghosh.

C#

375
Chapter 39. A Space Optimized Solution of LCS

// C# Code for A Space 


// Optimized Solution of LCS
using System;
  
class GFG
{
      
    // Returns length of LCS 
    // for X[0..m - 1],
    // Y[0..n - 1] 
    public static int lcs(string X,
                          string Y)
    {
          
        // Find lengths of
        // two strings
        int m = X.Length, n = Y.Length;
      
        int [,]L = new int[2, n + 1];
      
        // Binary index, used to 
        // index current row and 
        // previous row.
        int bi = 0;
      
        for (int i = 0; i <= m; i++)
        {
              
            // Compute current
            // binary index
            bi = i & 1;
      
            for (int j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    L[bi, j] = 0;
       
                else if (X[i - 1] == Y[j - 1])
                    L[bi, j] = L[1 - bi, 
                                 j - 1] + 1;
      
                else
                    L[bi, j] = Math.Max(L[1 - bi, j], 
                                        L[bi, j - 1]);
            }
        }
      
        // Last filled entry contains

376
Chapter 39. A Space Optimized Solution of LCS

        // length of LCS for X[0..n-1]


        // and Y[0..m-1] 
        return L[bi, n];
    }
      
    // Driver Code 
    public static void Main() 
    {
        string X = "AGGTAB";
        string Y = "GXTXAYB";
      
        Console.Write("Length of LCS is " +
                                lcs(X, Y));
    }
}
  
// This code is contributed 
// by shiv_bhakt.

Output:

Length of LCS is 4

Time Complexity : O(m*n)


Auxiliary Space : O(n)
This article is contributed Shivam Mittal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : shiv_bhakt

Source

https://www.geeksforgeeks.org/space-optimized-solution-lcs/

377
Chapter 40

All ways to add parenthesis for


evaluation

All ways to add parenthesis for evaluation - GeeksforGeeks


Given a string that represents an expression constituting numbers and binary operator +,
– and * only. We need to parenthesize the expression in all possible way and return all
evaluated values.

Input : expr = “3-2-1”


Output : {0, 2}
((3-2)-1) = 0
(3-(2-1)) = 2

Input : expr = "5*4-3*2"


Output : {-10, 10, 14, 10, 34}
(5*(4-(3*2))) = -10
(5*((4-3)*2)) = 10
((5*4)-(3*2)) = 14
((5*(4-3))*2) = 10
(((5*4)-3)*2) = 34

We can solve this problem by parenthesizing all possible valid substring of the expression
and then evaluating them, but as we can see that it will involve solving lots of repeating
subproblem, to save ourselves we can follow a dynamic programming approach.
We store the result for each substring in a map and if string in recursion is already solved,
we return result from map instead of solving that again.
Below code runs a loop in the string and if at any instant, character is operator then we
divide the input from there, recursively solve each part and then combine the result in all
possible ways.
See the use of c_str() function, this function converts the C++ string into C char array,

378
Chapter 40. All ways to add parenthesis for evaluation

this function is used in below code because atoi() function expects a character array as an
argument not the string. It converts character array to number.

//  C++ program to output all possible values of


// an expression by parenthesizing it.
#include <bits/stdc++.h>
using namespace std;
  
//  method checks, character is operator or not
bool isOperator(char op)
{
    return (op == '+' || op == '-' || op == '*');
}
  
//  Utility recursive method to get all possible
// result of input string
vector<int> possibleResultUtil(string input,
            map< string, vector<int> > memo)
{
    //  If already calculated, then return from memo
    if (memo.find(input) != memo.end())
        return memo[input];
  
    vector<int> res;
    for (int i = 0; i < input.size(); i++)
    {
        if (isOperator(input[i]))
        {
            // If character is operator then split and
            // calculate recursively
            vector<int> resPre =
              possibleResultUtil(input.substr(0, i), memo);
            vector<int> resSuf =
              possibleResultUtil(input.substr(i + 1), memo);
  
            //  Combine all possible combination
            for (int j = 0; j < resPre.size(); j++)
            {
                for (int k = 0; k < resSuf.size(); k++)
                {
                    if (input[i] == '+')
                        res.push_back(resPre[j] + resSuf[k]);
                    else if (input[i] == '-')
                        res.push_back(resPre[j] - resSuf[k]);
                    else if (input[i] == '*')
                        res.push_back(resPre[j] * resSuf[k]);
                }
            }

379
Chapter 40. All ways to add parenthesis for evaluation

        }
    }
  
    // if input contains only number then save that 
    // into res vector
    if (res.size() == 0)
        res.push_back(atoi(input.c_str()));
  
    // Store in memo so that input string is not 
    // processed repeatedly
    memo[input] = res;
    return res;
}
  
//  method to return all possible output 
// from input expression
vector<int> possibleResult(string input)
{
    map< string, vector<int> > memo;
    return possibleResultUtil(input, memo);
}
  
//  Driver code to test above methods
int main()
{
    string input = "5*4-3*2";
    vector<int> res = possibleResult(input);
  
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << " ";
    return 0;
}

Output:

-10 10 14 10 34

Source

https://www.geeksforgeeks.org/all-ways-to-add-parenthesis-for-evaluation/

380
Chapter 41

Alternate Fibonacci Numbers

Alternate Fibonacci Numbers - GeeksforGeeks


Give a number N, print alternate fibonacci numbers till n-th Fibonacci.
Examples:

Input : N = 7
Output : 0 1 3 8

Input : N = 15
Output : 0 1 3 8 21 55 144 377

Read method 2 in the following article : fibonacci number


Approach:Using dynamic programming approach. Keep storing the previously calcu-
lated fibonacci numbers and using the previous two to store the next fibonacci number.

Source

https://www.geeksforgeeks.org/alternate-fibonacci-numbers/
C++

// Alternate Fibonacci Series using Dynamic Programming


#include <bits/stdc++.h>
using namespace std;
  
void alternateFib(int n)
{
    if (n < 0)
      return;

381
Chapter 41. Alternate Fibonacci Numbers

  
    /* 0th and 1st number of the series are 0 and 1*/
    int f1 = 0;
    int f2 = 1;
  
    cout << f1 << " ";
    for (int i = 2; i <= n; i++) {
         int f3 = f2 + f1;
            
         if (i % 2 == 0)
            cout << f3 << " ";
  
         f1 = f2;
         f2 = f3;
    }
}
  
int main()
{
    int N = 15;
    alternateFib(N);
    return 0;
}

Java

// Alternate Fibonacci Series 


// using Dynamic Programming
import java.io.*;
  
class GFG 
{
static void alternateFib(int n)
{
    if (n < 0)
    return;
  
    /* 0th and 1st number of the
       series are 0 and 1*/
    int f1 = 0;
    int f2 = 1;
  
    System.out.print(f1 + " ");
    for (int i = 2; i <= n; i++) 
    {
        int f3 = f2 + f1;
          
        if (i % 2 == 0)

382
Chapter 41. Alternate Fibonacci Numbers

            System.out.print(f3 + " ");


  
        f1 = f2;
        f2 = f3;
    }
}
  
// Driver Code
public static void main (String[] args) 
{
    int N = 15;
    alternateFib(N);
}
}
  
// This code is contributed
// by chandan_jnu.

C#
// Alternate Fibonacci Series
// using Dynamic Programming
using System;
class GFG
{
static void alternateFib(int n)
{
if (n < 0) return; /* 0th and 1st number of the series are 0 and 1*/ int f1 = 0; int f2 = 1;
Console.Write(f1 + ” ”); for (int i = 2; i <= n; i++) { int f3 = f2 + f1; if (i % 2 == 0)
Console.Write(f3 + ” ”); f1 = f2; f2 = f3; } } // Driver Code public static void Main () { int
N = 15; alternateFib(N); } } // This code is contributed // by chandan_jnu. [tabbyending]
Output:

0 1 3 8 21 55 144 377

Time Complexity : O(n)


Auxiliary Space : O(1)
Improved By : Chandan_Kumar

383
Chapter 42

Balanced expressions such that


given positions have opening
brackets

Balanced expressions such that given positions have opening brackets - GeeksforGeeks
Given an integer n and an array of positions ‘position[]’ (1 <= position[i] <= 2n), find the
number of ways of proper bracket expressions that can be formed of length 2n such that
given positions have opening bracket. Examples :

Input : n = 3, position[] = [2}


Output : 3
Explanation :
The proper bracket sequences of length 6 and
opening bracket at position 2 are:
[ [ ] ] [ ]
[ [ [ ] ] ]
[ [ ] [ ] ]

Input : n = 2, position[] = {1, 3}


Output : 1
Explanation: The only possibility is:
[ ] [ ]

Approach : This problem can be solved by Dynamic programming..


Let DPi, j be the number of valid ways of filling the first i positions such that there are
j more brackets of type ‘[‘ than of type ‘]’. Valid ways would mean that it is the prefix
of a matched bracket expression and that the locations at which enforced ‘[‘ brackets are
enforced, have been satisfied. It is easy to see that DP2N, 0 is the final answer.

384
Chapter 42. Balanced expressions such that given positions have opening brackets

The base case of the DP is, DP0, 0 =1. We need to fill the first position with a ‘[‘ bracket,
and there is only way to do this.
If the position has a opening bracket sequence which can be marked by a hash array,
then the recurrence occurs as :

if(j != 0) dpi, j = dpi-1, j-1


else dpi, j = 0;

If the position has no opening bracket sequence, then recurrence happens as :

if(j != 0) dpi, j = dpi - 1, j - 1 + dpi - 1, j + 1


else dpi, j = dpi - 1, j + 1

The answer will be DP2n, 0

Given below is the CPP implementation of the above approach :


C++

// CPP code to find number of ways of


// arranging bracket with proper expressions
#include <bits/stdc++.h>
using namespace std;
  
#define N 1000
  
// function to calculate the number
// of proper bracket sequence
long long arrangeBraces(int n, int pos[], int k)
{
  
    // hash array to mark the
    // positions of opening brackets
    bool h[N];
  
    // dp 2d array
    int dp[N][N];
  
    memset(h, 0, sizeof h);
    memset(dp, 0, sizeof dp);
  
    // mark positions in hash array
    for (int i = 0; i < k; i++)
        h[pos[i]] = 1;
  
    // first position marked as 1
    dp[0][0] = 1;

385
Chapter 42. Balanced expressions such that given positions have opening brackets

  
    // iterate and formulate the recurrences
    for (int i = 1; i <= 2 * n; i++) {
        for (int j = 0; j <= 2 * n; j++) {
  
            // if position has a opening bracket
            if (h[i]) {
                if (j != 0)
                    dp[i][j] = dp[i - 1][j - 1];
                else
                    dp[i][j] = 0;
            }
            else {
                if (j != 0)
                    dp[i][j] = dp[i - 1][j - 1] +
                               dp[i - 1][j + 1];
                else
                    dp[i][j] = dp[i - 1][j + 1];
            }
        }
    }
  
    // return answer
    return dp[2 * n][0];
}
  
// driver code
int main()
{
    int n = 3;
  
    // positions where opening braces
    // will be placed
    int pos[] = { 2 };
    int k = sizeof(pos)/sizeof(pos[0]);
  
    cout << arrangeBraces(n, pos, k);
    return 0;
}

Output :

Time Complexity: O(n^2)


Auxiliary Space: O(n^2)

386
Chapter 42. Balanced expressions such that given positions have opening brackets

Source

https://www.geeksforgeeks.org/balanced-expressions-such-that-given-positions-have-opening-brackets/

387
Chapter 43

Balanced expressions such that


given positions have opening
brackets | Set 2

Balanced expressions such that given positions have opening brackets | Set 2 - GeeksforGeeks
Given an integer n and an array of positions ‘position[]’ (1 <= length(position[]) <= 2n),
find the number of ways of proper bracket expressions that can be formed of length 2n such
that given positions have the opening bracket.

Note: position[] array is given in the form of (1-based indexing) [0, 1, 1, 0]. Here 1
denotes the positions at which open bracket should be placed. At positions with value 0,
either of opening and closing bracket can be placed.
Examples:

Input: n = 3, position[] = [0, 1, 0, 0, 0, 0]


Output: 3
The proper bracket sequences of length 6 and
opening bracket at position 2 are:
[[]][]
[[[]]]
[[][]]
Input: n = 2, position[] = [1, 0, 1, 0]
Output: 1
The only possibility is:
[][]

Dynamic Programming approach of this problem has been already discussed here. In this
post, recursive and recursion using memoization approach will be discussed.
Algorithm–

388
Chapter 43. Balanced expressions such that given positions have opening brackets | Set 2

1. Mark all the positions with open brackets in the given array adj as 1.
2. Run a recursive loop, such that –
• If count of total brackets(opening brackets subracted from closing brackets is less
than zero), return 0.
• If the index reaches till n and if the total brackets=0, then a solution is obtained
and return 1, otherwise return 0.
• If the index has 1 pre-assigned to it, return the function recursively with index+1
and increment the total brackets.
• Otherwise Return the function recursively by inserting open brackets at that
index and incrementing total brackets by 1 + inserting closed brackets at that
index and decrementing total brackets by 1 and move on to the next index till n.

Below is the Recursive solution for above algorithm:

// C++ implementation of above 


// approach using Recursion
#include <bits/stdc++.h>
using namespace std;
  
// Function to find Number of
// proper bracket expressions
int find(int index, int openbrk, int n, int adj[])
{
    // If open-closed brackets < 0
    if (openbrk < 0)
        return 0;
  
    // If index reaches the end of expression
    if (index == n) {
  
        // IF brackets are balanced
        if (openbrk == 0)
            return 1;
        else
            return 0;
    }
  
    // If the current index has assigned open bracket
    if (adj[index] == 1) {
  
        // Move forward increasing the
        // length of open brackets
        return find(index + 1, openbrk + 1, n, adj);
    }
  
    else {
  

389
Chapter 43. Balanced expressions such that given positions have opening brackets | Set 2

        // Move forward by inserting open as well


        // as closed brackets on that index
        return find(index + 1, openbrk + 1, n, adj)
               + find(index + 1, openbrk - 1, n, adj);
    }
}
// Driver Code
int main()
{
  
    int n = 2;
  
    // Open brackets at postion 1
    int adj[4] = { 1, 0, 0, 0 };
  
    // Calling the find function to calculate the answer
    cout << find(0, 0, 2 * n, adj) << endl;
  
  return 0;
}

Output:

Memoized Approach: Time complexity of the above algorithm can be optimized by using
Memorization. The only thing to be done is to use an array to store the results of previous
iterations so that there is no need to recursively call the same function more than once, if
the value is already calculated.
Below is the required implementation:

// C++ implemntation of above 


// approach using memoizaion
#include <bits/stdc++.h>
using namespace std;
  
#define N 1000
  
// Function to find Number
// of proper bracket expressions
int find(int index, int openbrk, int n,
         int dp[N][N], int adj[])
{
    // If open-closed brackets<0
    if (openbrk < 0)
        return 0;

390
Chapter 43. Balanced expressions such that given positions have opening brackets | Set 2

  
    // If index reaches the end of expression
    if (index == n) {
  
        // If brackets are balanced
        if (openbrk == 0)
            return 1;
  
        else
            return 0;
    }
  
    // If already stored in dp
    if (dp[index][openbrk] != -1)
        return dp[index][openbrk];
  
    // If the current index has assigned open bracket
    if (adj[index] == 1) {
  
        // Move forward increasing the
        // length of open brackets
        dp[index][openbrk] = find(index + 1,
                                  openbrk + 1, n, dp, adj);
    }
    else {
        // Move forward by inserting open as
        // well as closed brackets on that index
        dp[index][openbrk] = find(index + 1, openbrk + 1, n, dp, adj)
                             + find(index + 1, openbrk - 1, n, dp, adj);
    }
    // return the answer
    return dp[index][openbrk];
}
  
// Driver Code
int main()
{
    // DP array to precompute the answer
    int dp[N][N];
    int n = 2;
  
    memset(dp, -1, sizeof(dp));
  
    // Open brackets at postion 1
    int adj[4] = { 1, 0, 0, 0 };
  
    // Calling the find function to calculate the answer
    cout << find(0, 0, 2 * n, dp, adj) << endl;

391
Chapter 43. Balanced expressions such that given positions have opening brackets | Set 2

  
  return 0;
}

Output:

Time complexity: O(N2 )

Source

https://www.geeksforgeeks.org/balanced-expressions-such-that-given-positions-have-opening-brackets-set-2/

392
Chapter 44

Bell Numbers (Number of ways


to Partition a Set)

Bell Numbers (Number of ways to Partition a Set) - GeeksforGeeks


Given a set of n elements, find number of ways of partitioning it.
Examples:

Input: n = 2
Output: Number of ways = 2
Explanation: Let the set be {1, 2}
{ {1}, {2} }
{ {1, 2} }

Input: n = 3
Output: Number of ways = 5
Explanation: Let the set be {1, 2, 3}
{ {1}, {2}, {3} }
{ {1}, {2, 3} }
{ {2}, {1, 3} }
{ {3}, {1, 2} }
{ {1, 2, 3} }.

Solution to above questions is Bell Number.


What is a Bell Number?
Let S(n, k) be total number of partitions of n elements into k sets. The value of n’th Bell
Number is sum of S(n, k) for k = 1 to n.

Value of S(n, k) can be defined recursively as, S(n+1, k) = k*S(n, k) + S(n, k-1)

393
Chapter 44. Bell Numbers (Number of ways to Partition a Set)

How does above recursive formula work?


When we add a (n+1)’th element to k partitions, there are two possibilities.
1) It is added as a single element set to existing partitions, i.e, S(n, k-1)
2) It is added to all sets of every partition, i.e., k*S(n, k)
S(n, k) is called Stirling numbers of the second kind
First few Bell numbers are 1, 1, 2, 5, 15, 52, 203, ….
A Simple Method to compute n’th Bell Number is to one by one compute S(n, k) for k
= 1 to n and return sum of all computed values. Refer this for computation of S(n, k).
A Better Method is to use Bell Triangle. Below is a sample Bell Triangle for first few Bell
Numbers.

1
1 2
2 3 5
5 7 10 15
15 20 27 37 52

The triangle is constructed using below formula.

// If this is first column of current row 'i'


If j == 0
// Then copy last entry of previous row
// Note that i'th row has i entries
Bell(i, j) = Bell(i-1, i-1)

// If this is not first column of current row


Else
// Then this element is sum of previous element
// in current row and the element just above the
// previous element
Bell(i, j) = Bell(i-1, j-1) + Bell(i, j-1)

Interpretation
Then Bell(n, k) counts the number of partitions of the set {1, 2, …, n + 1} in which the
element k + 1 is the largest element that can be alone in its set.
For example, Bell(3, 2) is 3, it is count of number of partitions of {1, 2, 3, 4} in which 3 is
the largest singleton element. There are three such partitions:

{1}, {2, 4}, {3}


{1, 4}, {2}, {3}
{1, 2, 4}, {3}.

394
Chapter 44. Bell Numbers (Number of ways to Partition a Set)

Below is Dynamic Programming based implementation of above recursive formula.

C++

// A C++ program to find n'th Bell number


#include<iostream>
using namespace std;
  
int bellNumber(int n)
{
   int bell[n+1][n+1];
   bell[0][0] = 1;
   for (int i=1; i<=n; i++)
   {
      // Explicitly fill for j = 0
      bell[i][0] = bell[i-1][i-1];
  
      // Fill for remaining values of j
      for (int j=1; j<=i; j++)
         bell[i][j] = bell[i-1][j-1] + bell[i][j-1];
   }
   return bell[n][0];
}
  
// Driver program
int main()
{
   for (int n=0; n<=5; n++)
      cout << "Bell Number " << n << " is " 
           << bellNumber(n) << endl;
   return 0;
}

Java

// Java program to find n'th Bell number


import java.io.*;
  
class GFG 
{
    // Function to find n'th Bell Number
    static int bellNumber(int n)
    {
        int[][] bell = new int[n+1][n+1];
        bell[0][0] = 1;
          
        for (int i=1; i<=n; i++)

395
Chapter 44. Bell Numbers (Number of ways to Partition a Set)

        {
            // Explicitly fill for j = 0
            bell[i][0] = bell[i-1][i-1];
   
            // Fill for remaining values of j
            for (int j=1; j<=i; j++)
                bell[i][j] = bell[i-1][j-1] + bell[i][j-1];
        }
          
        return bell[n][0];
    }
      
    // Driver program
    public static void main (String[] args) 
    {
        for (int n=0; n<=5; n++)
            System.out.println("Bell Number "+ n +
                            " is "+bellNumber(n));
    }
}
  
// This code is contributed by Pramod Kumar

Python3

# A Python program to find n'th Bell number


  
def bellNumber(n):
  
    bell = [[0 for i in range(n+1)] for j in range(n+1)]
    bell[0][0] = 1
    for i in range(1, n+1):
  
        # Explicitly fill for j = 0
        bell[i][0] = bell[i-1][i-1]
  
        # Fill for remaining values of j
        for j in range(1, i+1):
            bell[i][j] = bell[i-1][j-1] + bell[i][j-1]
  
    return bell[n][0]
  
# Driver program
for n in range(6):
    print('Bell Number', n, 'is', bellNumber(n))
  
# This code is contributed by Soumen Ghosh

396
Chapter 44. Bell Numbers (Number of ways to Partition a Set)

C#

// C# program to find n'th Bell number


using System;
  
class GFG {
      
    // Function to find n'th 
    // Bell Number
    static int bellNumber(int n)
    {
        int[,] bell = new int[n + 1, 
                              n + 1];
        bell[0, 0] = 1;
          
        for (int i = 1; i <= n; i++)
        {
              
            // Explicitly fill for j = 0
            bell[i, 0] = bell[i - 1, i - 1];
  
            // Fill for remaining values of j
            for (int j = 1; j <= i; j++)
                bell[i, j] = bell[i - 1, j - 1] + 
                             bell[i, j - 1];
        }
          
        return bell[n, 0];
    }
      
    // Driver Code
    public static void Main () 
    {
        for (int n = 0; n <= 5; n++)
            Console.WriteLine("Bell Number "+ n +
                              " is "+bellNumber(n));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// A PHP program to find
// n'th Bell number
  

397
Chapter 44. Bell Numbers (Number of ways to Partition a Set)

// function that returns 


// n'th bell number
function bellNumber($n)
{
  
    $bell[0][0] = 1;
    for ($i = 1; $i <= $n; $i++)
    {
          
        // Explicitly fill for j = 0
        $bell[$i][0] = $bell[$i - 1]
                            [$i - 1];
      
        // Fill for remaining 
        // values of j
        for ($j = 1; $j <= $i; $j++)
            $bell[$i][$j] = $bell[$i - 1][$j - 1] + 
                                $bell[$i][$j - 1];
    }
    return $bell[$n][0];
}
  
// Driver Code
for ($n = 0; $n <= 5; $n++)
echo("Bell Number " . $n . " is "
      . bellNumber($n) . "\n");
  
// This code is contributed by Ajit.
?>

Output:

Bell Number 0 is 1
Bell Number 1 is 1
Bell Number 2 is 2
Bell Number 3 is 5
Bell Number 4 is 15
Bell Number 5 is 52

Time Complexity of above solution is O(n2 ). We will soon be discussing other more efficient
methods of computing Bell Numbers.
Another problem that can be solved by Bell Numbers.
A number is squarefree if it is not divisible by a perfect square other than 1. For example,
6 is a square free number but 12 is not as it is divisible by 4.
Given a squarefree number x, find the number of different multiplicative partitions of x. The
number of multiplicative partitions is Bell(n) where n is number of prime factors of x. For

398
Chapter 44. Bell Numbers (Number of ways to Partition a Set)

example x = 30, there are 3 prime factors of 2, 3 and 5. So the answer is Bell(3) which is 5.
The 5 partitions are 1 x 30, 2 x15, 3 x 10, 5 x 6 and 2 x 3 x 5.
Exercise:
The above implementation causes arithmetic overflow for slightly larger values of n. Ex-
tend the above program so that results are computed under modulo 1000000007 to avoid
overflows.
Reference:
https://en.wikipedia.org/wiki/Bell_number
https://en.wikipedia.org/wiki/Bell_triangle
This article is contributed by Rajeev Agrawal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : nitin mittal, jit_t

Source

https://www.geeksforgeeks.org/bell-numbers-number-of-ways-to-partition-a-set/

399
Chapter 45

Bitmasking and Dynamic


Programming | Set 1 (Count
ways to assign unique cap to
every person)

Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique cap to every
person) - GeeksforGeeks
Consider the below problems statement.
There are 100 different types of caps each having a unique id from 1 to 100. Also, there
are ‘n’ persons each having a collection of a variable number of caps. One day all of these
persons decide to go in a party wearing a cap but to look unique they decided that none of
them will wear the same type of cap. So, count the total number of arrangements or ways
such that none of them is wearing the same type of cap.
Constraints: 1 <= n <= 10 Example:

The first line contains the value of n, next n lines contain collections
of all the n persons.
Input:
3
5 100 1 // Collection of the first person.
2 // Collection of the second person.
5 100 // Collection of the third person.

Output:
4
Explanation: All valid possible ways are (5, 2, 100), (100, 2, 5),
(1, 2, 5) and (1, 2, 100)

400
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

Since, number of ways could be large, so output modulo 1000000007


We strongly recommend you to minimize your browser and try this yourself
first.
A Simple Solution is to try all possible combinations. Start by picking the first element
from the first set, marking it as visited and recur for remaining sets. It is basically a
Backtracking based solution.
A better solution is to use Bitmasking and DP. Let us first introduce Bitmasking.
What is Bitmasking?
Suppose we have a collection of elements which are numbered from 1 to N. If we want to
represent a subset of this set then it can be encoded by a sequence of N bits (we usually call
this sequence a “mask”). In our chosen subset the i-th element belongs to it if and only if
the i-th bit of the mask is set i.e., it equals to 1. For example, the mask 10000101 means
that the subset of the set [1… 8] consists of elements 1, 3 and 8. We know that for a set
of N elements there are total 2N subsets thus 2N masks are possible, one representing each
subset. Each mask is, in fact, an integer number written in binary notation.
Our main methodology is to assign a value to each mask (and, therefore, to each subset)
and thus calculate the values for new masks using values of the already computed masks.
Usually our main target is to calculate value/solution for the complete set i.e., for mask
11111111. Normally, to find the value for a subset X we remove an element in every possible
way and use values for obtained subsets X’1 , X’2 … ,X’k to compute the value/solution for X.
This means that the values for X’i must have been computed already, so we need to establish
an ordering in which masks will be considered. It’s easy to see that the natural ordering will
do: go over masks in increasing order of corresponding numbers. Also, We sometimes, start
with the empty subset X and we add elements in every possible way and use the values of
obtained subsets X’1 , X’2 … ,X’k to compute the value/solution for X.
We mostly use the following notations/operations on masks:
bit(i, mask) – the i-th bit of mask
count(mask) – the number of non-zero bits in the mask
first(mask) – the number of the lowest non-zero bit in the mask
set(i, mask) – set the ith bit in the mask
check(i, mask) – check the ith bit in the mask
How is this problem solved using Bitmasking + DP?
The idea is to use the fact that there are upto 10 persons. So we can use an integer variable
as a bitmask to store which person is wearing a cap and which is not.

Let i be the current cap number (caps from 1 to i-1 are already
processed). Let integer variable mask indicates that the persons w
earing and not wearing caps. If i'th bit is set in mask, then
i'th person is wearing a cap, else not.

// consider the case when ith cap is not included


// in the arrangement
countWays(mask, i) = countWays(mask, i+1) +

401
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

// when ith cap is included in the arrangement


// so, assign this cap to all possible persons
// one by one and recur for remaining persons.
&Sum; countWays(mask | (1 << j), i+1)
for every person j that can wear cap i

Note that the expression "mask | (1 << j)" sets j'th bit in mask.
And a person can wear cap i if it is there in the person's cap list
provided as input.

If we draw the complete recursion tree, we can observe that many subproblems are solved
again and again. So we use Dynamic Programming. A table dp[][] is used such that in every
entry dp[i][j], i is mask and j is cap number.
Since we want to access all persons that can wear a given cap, we use an array of vectors,
capList[101]. A value capList[i] indicates the list of persons that can wear cap i.
Below is the implementation of above idea.

C/C++

// C++ program to find number of ways to wear hats


#include<bits/stdc++.h>
#define MOD 1000000007
using namespace std;
  
// capList[i]'th vector contains the list of persons having a cap with id i
// id is between 1 to 100 so we declared an array of 101 vectors as indexing
// starts from 0.
vector<int> capList[101];
  
// dp[2^10][101] .. in dp[i][j], i denotes the mask i.e., it tells that
// how many and which persons are wearing cap. j denotes the first j caps
// used. So, dp[i][j] tells the number ways we assign j caps to mask i
// such that none of them wears the same cap
int dp[1025][101];
  
// This is used for base case, it has all the N bits set
// so, it tells whether all N persons are wearing a cap.
int allmask;
  
// Mask is the set of persons, i is cap-id (OR the 
// number of caps processed starting from first cap).
long long int countWaysUtil(int mask, int i)
{
    // If all persons are wearing a cap so we
    // are done and this is one way so return 1
    if (mask == allmask) return 1;

402
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

  
    // If not everyone is wearing a cap and also there are no more
    // caps left to process, so there is no way, thus return 0;
    if (i > 100) return 0;
  
    // If we already have solved this subproblem, return the answer.
    if (dp[mask][i] != -1) return dp[mask][i];
  
    // Ways, when we don't include this cap in our arrangement
    // or solution set.
    long long int ways = countWaysUtil(mask, i+1);
  
    // size is the total number of persons having cap with id i.
    int size = capList[i].size();
  
    // So, assign one by one ith cap to all the possible persons
    // and recur for remaining caps.
    for (int j = 0; j < size; j++)
    {
        // if person capList[i][j] is already wearing a cap so continue as
        // we cannot assign him this cap
        if (mask & (1 << capList[i][j])) continue;
  
        // Else assign him this cap and recur for remaining caps with
        // new updated mask vector
        else ways += countWaysUtil(mask | (1 << capList[i][j]), i+1);
        ways %= MOD;
    }
  
    // Save the result and return it.
    return dp[mask][i] = ways;
}
  
// Reads n lines from standard input for current test case
void countWays(int n)
{
    //----------- READ INPUT --------------------------
    string temp, str;
    int x;
    getline(cin, str);  // to get rid of newline character
    for (int i=0; i<n; i++)
    {
        getline(cin, str);
        stringstream ss(str);
  
        // while there are words in the streamobject ss
        while (ss >> temp)
        {

403
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

            stringstream s;
            s << temp;
            s >> x;
  
            // add the ith person in the list of cap if with id x
            capList[x].push_back(i);
        }
    }
    //----------------------------------------------------
  
    // All mask is used to check whether all persons
    // are included or not, set all n bits as 1
    allmask = (1 << n) - 1;
  
    // Initialize all entries in dp as -1
    memset(dp, -1, sizeof dp);
  
    // Call recursive function count ways
    cout << countWaysUtil(0, 1) << endl;
}
  
// Driver Program
int main()

     int n;   // number of persons in every test case
     cin >> n;
     countWays(n);
     return 0;
}

Java

// Java program to find number of ways to wear hats


  
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Vector;
  
class Test
{
    static final int MOD = 1000000007;
      
    // for input
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      
    // capList[i]'th vector contains the list of persons having a cap with id i
    // id is between 1 to 100 so we declared an array of 101 vectors as indexing
    // starts from 0.

404
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

    static Vector<Integer> capList[] = new Vector[101];


      
       
    // dp[2^10][101] .. in dp[i][j], i denotes the mask i.e., it tells that
    // how many and which persons are wearing cap. j denotes the first j caps
    // used. So, dp[i][j] tells the number ways we assign j caps to mask i
    // such that none of them wears the same cap
    static int dp[][] = new int[1025][101];
       
    // This is used for base case, it has all the N bits set
    // so, it tells whether all N persons are wearing a cap.
    static int allmask;
       
    // Mask is the set of persons, i is cap-id (OR the 
    // number of caps processed starting from first cap).
    static long countWaysUtil(int mask, int i)
    {
        // If all persons are wearing a cap so we
        // are done and this is one way so return 1
        if (mask == allmask) return 1;
       
        // If not everyone is wearing a cap and also there are no more
        // caps left to process, so there is no way, thus return 0;
        if (i > 100) return 0;
       
        // If we already have solved this subproblem, return the answer.
        if (dp[mask][i] != -1) return dp[mask][i];
       
        // Ways, when we don't include this cap in our arrangement
        // or solution set.
        long ways = countWaysUtil(mask, i+1);
       
        // size is the total number of persons having cap with id i.
        int size = capList[i].size();
       
        // So, assign one by one ith cap to all the possible persons
        // and recur for remaining caps.
        for (int j = 0; j < size; j++)
        {
            // if person capList[i][j] is already wearing a cap so continue as
            // we cannot assign him this cap
            if ((mask & (1 << capList[i].get(j))) != 0) continue;
       
            // Else assign him this cap and recur for remaining caps with
            // new updated mask vector
            else ways += countWaysUtil(mask | (1 << capList[i].get(j)), i+1);
            ways %= MOD;
        }

405
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

       
        // Save the result and return it.
        return dp[mask][i] = (int) ways;
    }
       
    // Reads n lines from standard input for current test case
    static void countWays(int n) throws Exception
    {
        //----------- READ INPUT --------------------------
        String str;
        String split[];
        int x;
                
        for (int i=0; i<n; i++)
        {
            str = br.readLine();
            split = str.split(" ");
            
            // while there are words in the split[]
            for (int j = 0; j < split.length; j++) {
                 // add the ith person in the list of cap if with id x
                x = Integer.parseInt(split[j]);
                capList[x].add(i);
            }
            
        }
        //----------------------------------------------------
       
        // All mask is used to check of all persons
        // are included or not, set all n bits as 1
        allmask = (1 << n) - 1;
       
        // Initialize all entries in dp as -1
        for (int[] is : dp) {
            for (int i = 0; i < is.length; i++) {
                is[i] = -1;
            }
        }
       
        // Call recursive function count ways
        System.out.println(countWaysUtil(0, 1));
    }
  
    // Driver method
    public static void main(String args[]) throws Exception
    {
        int n;   // number of persons in every test case
          

406
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

        // initializing vector array


        for (int i = 0; i < capList.length; i++)
            capList[i] = new Vector<>();
          
          
        n = Integer.parseInt(br.readLine());
        countWays(n);
    }
}
// This code is contributed by Gaurav Miglani

Python

#Python program to find number of ways to wear hats


from collections import defaultdict
  
class AssignCap:
  
    # Initialize variables
    def __init__(self):
  
            self.allmask = 0
  
            self.total_caps = 100
  
            self.caps = defaultdict(list)
  
  
    #  Mask is the set of persons, i is the current cap number.
    def countWaysUtil(self,dp, mask, cap_no):
          
        # If all persons are wearing a cap so we
        # are done and this is one way so return 1
        if mask == self.allmask:
            return 1
  
        # If not everyone is wearing a cap and also there are no more
        # caps left to process, so there is no way, thus return 0;
        if cap_no > self.total_caps:
            return 0
  
        # If we have already solved this subproblem, return the answer.
        if dp[mask][cap_no]!= -1 :
            return dp[mask][cap_no]
  
        # Ways, when we don't include this cap in our arrangement
        # or solution set
        ways = self.countWaysUtil(dp, mask, cap_no + 1)

407
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

          
        # assign ith cap one by one  to all the possible persons
        # and recur for remaining caps.
        if cap_no in self.caps:
  
            for ppl in self.caps[cap_no]:
                  
                # if person 'ppl' is already wearing a cap then continue
                if mask & (1 << ppl) : continue
                  
                # Else assign him this cap and recur for remaining caps with
                # new updated mask vector
                ways += self.countWaysUtil(dp, mask | (1 << ppl), cap_no + 1) 
  
                ways = ways % (10**9 + 7)
  
        # Save the result and return it
        dp[mask][cap_no] = ways
  
        return dp[mask][cap_no]
  
  
  
    def countWays(self,N):
  
        # Reads n lines from standard input for current test case
        # create dictionary for cap. cap[i] = list of person having
        # cap no i
        for ppl in range(N):
  
            cap_possessed_by_person = map(int, raw_input().strip().split())
  
            for i in cap_possessed_by_person:
  
                self.caps[i].append(ppl)
  
        # allmask is used to check if all persons
        # are included or not, set all n bits as 1
        self.allmask = (1 << N) -1
  
        # Initialize all entries in dp as -1
        dp = [[-1 for j in range(self.total_caps + 1)] for i in range(2 ** N)]
  
        # Call recursive function countWaysUtil
        # result will be in dp[0][1]
        print self.countWaysUtil(dp, 0, 1,)
  
#Driver Program

408
Chapter 45. Bitmasking and Dynamic Programming | Set 1 (Count ways to assign unique
cap to every person)

def main():
    No_of_people = input() # number of persons in every test case
  
    AssignCap().countWays(No_of_people)
  
  
if __name__ == '__main__':
    main()
  
# This code is contributed by Neelam Yadav

Input:

3
5 100 1
2
5 100

Output:

This article is contributed by Gaurav Ahirwar. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/bitmasking-and-dynamic-programming-set-1-count-ways-to-assign-unique-cap-to-ev

409
Chapter 46

Bitmasking and Dynamic


Programming | Set-2 (TSP)

Bitmasking and Dynamic Programming | Set-2 (TSP) - GeeksforGeeks


In this post, we will be using our knowledge of dynamic programming and Bitmasking
technique to solve one of the famous NP-hard problem “Travelling Salesman Problem”.
Before solving the problem, we assume that the reader has the knowledge of

• DP and formation of DP transition relation


• Bitmasking in DP
• Travelling Salesman problem

To understand this concept lets consider the below problem :

Problem Description:

Given a 2D grid of characters representing


a town where '*' represents the
houses, '#' represents the blockage,
'.' represents the vacant street
area. Currently you are (0, 0) position.

Our task is to determine the minimum distance


to be moved to visit all the houses and return
to our initial position at (0, 0). You can
only move to adjacent cells that share exactly
1 edge with the current cell.

The above problem is the well-known Travelling Salesman Problem.

410
Chapter 46. Bitmasking and Dynamic Programming | Set-2 (TSP)

The first part is to calculate the minimum distance between the two cells. We can do it by
simply using a BFS as all the distances are unit distance. To optimize our solution we will
be pre-calculating the distances taking the initial location and the location of the houses as
the source point for our BFS.
Each BFS traversal takes O(size of grid) time. Therefore, it is O(X * size_of_grid) for
overall pre-calculation, where X = number of houses + 1 (initial position)
Now lets’s think of a DP state
So we will be needing to track the visited houses and the last visited house to uniquely
identify a state in this problem.
Therefore, we will be taking dp[index][mask] as our DP state.
Here,
index : tells us the location of current house
mask : tells us the houses that are visited ( if ith bit is set in mask then this means that
the ith dirty tile is cleaned)
Whereas dp[index][mask] will tell us the minimum distance to visit X(number of set bits in
mask) houses corresponding to their order of their occurrence in the mask where the last
visited house is house at location index.
State transition relation
So our initial state will be dp[0][0] this tells that we are currently at initial tile that is our
initial location and mask is 0 that states that no house is visited till now.
And our final destination state will be dp[any index][LIMIT_MASK], here
LIMIT_MASK = (1<<N) – 1
and N = number of houses.
Therefore our DP state transition can be stated as

dp(curr_idx)(curr_mask) = min{
for idx : off_bits_in_curr_mask
dp(idx)(cur_mask.set_bit(idx)) + dist[curr_idx][idx]
}

The above relation can be visualized as the minimum distance to visit all the houses by
standing at curr_idx house and by already visiting cur_mask houses is equal to min of
distance between the curr_idx house and idx house + minimum distance to visit all the
houses by standing at idx house and by already
visiting ( cur_mask | (1 <<idx) ) houses.
So, here we iterate over all possible idx values such that cur_mask has ith bit as 0 that tells
us that ith house is not visited.
Whenever we have our mask = LIMIT_MASK, this means that we have visited all the
houses in the town. So, we will add the distance from the last visited town (i.e the town at
cur_idx positon) to the initial position (0, 0).
The C++ program for the above implementation is given below:

411
Chapter 46. Bitmasking and Dynamic Programming | Set-2 (TSP)

#include <bits/stdc++.h>
using namespace std;
  
#define INF 99999999
#define MAXR 12
#define MAXC 12
#define MAXMASK 2048
#define MAXHOUSE 12
  
// stores distance taking souce
// as every dirty tile
int dist[MAXR][MAXC][MAXHOUSE];
  
// memoization for dp states
int dp[MAXHOUSE][MAXMASK];
  
// stores coordinates for
// dirty tiles
vector < pair < int, int > > dirty;
  
// Directions
int X[] = {-1, 0, 0, 1};
int Y[] = {0, 1, -1, 0};
  
char arr[21][21];
  
// len : number of dirty tiles + 1
// limit : 2 ^ len -1
// r, c : number of rows and columns
int len, limit, r, c;
  
  
// Returns true if current position
// is safe to visit
// else returns false
// Time Complexity : O(1)
bool safe(int x, int y)
{
    if (x >= r or y>= c or x<0 or y<0)
       return false;
    if (arr[x][y] == '#')
       return false;
    return true;
}
  
  
// runs BFS traversal at tile idx
// calulates distance to every cell

412
Chapter 46. Bitmasking and Dynamic Programming | Set-2 (TSP)

// in the grid
// Time Complexity : O(r*c)
void getDist(int idx){
  
    // visited array to track visited cells
    bool vis[21][21];
    memset(vis, false, sizeof(vis));
  
    // getting current positon
    int cx = dirty[idx].first;
    int cy = dirty[idx].second;
  
    // initializing queue for bfs
    queue < pair < int, int > > pq;
    pq.push({cx, cy});
  
    // initializing the dist to max
    // because some cells cannot be visited
    // by taking source cell as idx
    for (int i = 0;i<= r;i++)
        for (int j = 0;j<= c;j++)
            dist[i][j][idx] = INF;
  
    // base conditions
    vis[cx][cy] = true;
    dist[cx][cy][idx] = 0;
  
    while (! pq.empty())
    {
        auto x = pq.front();
        pq.pop();
        for (int i = 0;i<4;i++)
        {
           cx = x.first + X[i];
           cy = x.second + Y[i];
           if (safe(cx, cy))
           {
               if (vis[cx][cy])
                   continue;
               vis[cx][cy] = true;
               dist[cx][cy][idx] = dist[x.first][x.second][idx] + 1;
               pq.push({cx, cy});
            }
         }
    }
}
  
// Dynamic Programming state transition recursion

413
Chapter 46. Bitmasking and Dynamic Programming | Set-2 (TSP)

// with memoization. Time Complexity: O(n*n*2 ^ n)


int solve(int idx, int mask)
{
    // goal state
    if (mask == limit)
       return dist[0][0][idx];
  
    // if already visited state
    if (dp[idx][mask] != -1)
       return dp[idx][mask];
  
    int ret = INT_MAX;
  
    // state transiton relation
    for (int i = 0;i<len;i++)
    {
        if ((mask & (1<<i)) == 0)
        {
            int newMask = mask | (1<<i);
            ret = min( ret, solve(i, newMask)
                + dist[dirty[i].first][dirty[i].second][idx]);
        }
    }
  
    // adding memoization and returning
    return dp[idx][mask] = ret;
}
  
void init()
{
    // initializing containers
    memset(dp, -1, sizeof(dp));
    dirty.clear();
  
    // populating dirty tile positions
    for (int i = 0;i<r;i++)
        for (int j = 0;j<c;j++)
        {
            if (arr[i][j] == '*')
               dirty.push_back({i, j});
        }
  
    // inserting ronot's location at the
    // begining of the dirty tile
    dirty.insert(dirty.begin(), {0, 0});
  
    len = dirty.size();
  

414
Chapter 46. Bitmasking and Dynamic Programming | Set-2 (TSP)

    // calculating LIMIT_MASK


    limit = (1<<len) - 1;
  
    // precalculating distances from all
    // dirty tiles to each cell in the grid
    for (int i = 0;i<len;i++)
       getDist(i);
}
  
int main(int argc, char const *argv[])
{
    // Test case #1:
    //     .....*.
    //     ...#...
    //     .*.#.*.
    //     .......
  
char A[4][7] = {    {'.', '.', '.', '.', '.', '*', '.'},
                    {'.', '.', '.', '#', '.', '.', '.'},
                    {'.', '*', '.', '#', '.', '*', '.'},
                    {'.', '.', '.', '.', '.', '.', '.'}
                };
  
    r = 4; c = 7;
  
    cout << "The given grid : " << endl;
  
    for (int i = 0;i<r;i++)
    {
        for (int j = 0;j<c;j++)
        {
            cout << A[i][j] << " ";
            arr[i][j] = A[i][j];
        }
        cout << endl;
    }
  
    // - initializitiation
    // - precalculations
    init();
  
    int ans = solve(0, 1);
  
    cout << "Minimum distance for the given grid : ";
    cout << ans << endl;
  
  
    // Test Case #2

415
Chapter 46. Bitmasking and Dynamic Programming | Set-2 (TSP)

    //     ...#...
    //     ...#.*.
    //     ...#...
    //     .*.#.*.
    //     ...#...
  
    char Arr[5][7] = {  {'.', '.', '.', '#', '.', '.', '.'},
                        {'.', '.', '.', '#', '.', '*', '.'},
                        {'.', '.', '.', '#', '.', '.', '.'},
                        {'.', '*', '.', '#', '.', '*', '.'},
                        {'.', '.', '.', '#', '.', '.', '.'}
                };
  
    r = 5; c = 7;
  
    cout << "The given grid : " << endl;
  
    for (int i = 0;i<r;i++)
    {
        for (int j = 0;j<c;j++)
        {
            cout << Arr[i][j] << " ";
            arr[i][j] = Arr[i][j];
        }
        cout << endl;
    }
  
    // - initializitiation
    // - precalculations
    init();
    ans = solve(0, 1);
    cout << "Minimum distance for the given grid : ";
    if (ans >= INF)
        cout << "not possible" << endl;
    else
        cout << ans << endl;
  
    return 0;
}

Output:

The given grid :


. . . . . * .
. . . # . . .
. * . # . * .
. . . . . . .

416
Chapter 46. Bitmasking and Dynamic Programming | Set-2 (TSP)

Minimum distance for the given grid : 16


The given grid :
. . . # . . .
. . . # . * .
. . . # . . .
. * . # . * .
. . . # . . .
Minimum distance for the given grid : not possible

Note:
We have used the initial state to be dp[0][1] because we have pushed the start location at
the first position in the container of houses. Hence, our Bit Mask will be 1 as the 0th bit is
set i.e we have visited the starting location for our trip.
Time Complexity:
Consider the number of houses to be n. So, there are n * (2n ) states and at every state,
we are looping over n houses to transit over to next state and because of memoization we
are doing this looping transition only once for each state. Therefore, our Time Complexity
is O(n2 * 2n ).
Recommended:

• http://www.spoj.com/problems/CLEANRBT/
• https://www.youtube.com/watch?v=-JjA4BLQyqE

Source

https://www.geeksforgeeks.org/bitmasking-dynamic-programming-set-2-tsp/

417
Chapter 47

Check for possible path in 2D


matrix

Check for possible path in 2D matrix - GeeksforGeeks


Given a 2D array(m x n), check if there is any path from top left to bottom right. In the
matrix, -1 is considered as blockage (can’t go through this cell) and 0 is considered path cell
(can go through it).
Examples:

Input : arr[][] = {{ 0, 0, 0, -1, 0},


{-1, 0, 0, -1, -1},
{ 0, 0, 0, -1, 0},
{-1, 0, 0, 0, 0},
{ 0, 0, -1, 0, 0}}
Output : Yes

Input : arr[][] = {{ 0, 0, 0, -1, 0},


{-1, 0, 0, -1, -1},
{ 0, 0, 0, -1, 0},
{-1, 0, -1, 0, 0},
{ 0, 0, -1, 0, 0}}
Output : No

Approach :
A simple solution is to do BFS or DFS to find if there is a path.
A better solution is to mark all accessible nodes by changing their value to 1. First change
the value of first top left element value to 1 then in the first row get previous value and set
to current index in only first row if the value is -1 then no change then in first column do
the same.

418
Chapter 47. Check for possible path in 2D matrix

Then start from first row and first column and take previous row value and previous row
column and find max between them, and set to current index, if current index value is -1
then no change.
At the end if right bottom is 1 then return yes else return no.
C++

// CPP program to find if there is path 


// from top left to right bottom
#include <iostream>
using namespace std;
  
#define row 5
#define col 5
  
// to find the path from
// top left to bottom right
bool isPath(int arr[row][col])
{
    // set arr[0][0] = 1
    arr[0][0] = 1;
  
    // Mark reachable (from top left) nodes 
    // in first row and first column.
    for (int i = 1; i < row; i++) 
        if (arr[0][i] != -1)
            arr[0][i] = arr[0][i - 1];   
  
    for (int j = 1; j < col; j++) 
        if (arr[j][0] != -1)
            arr[j][0] = arr[j - 1][0];    
  
    // Mark reachable nodes in remaining
    // matrix.
    for (int i = 1; i < row; i++) 
        for (int j = 1; j < col; j++) 
          if (arr[i][j] != -1)
              arr[i][j] = max(arr[i][j - 1],
                            arr[i - 1][j]);       
      
    // return yes if right bottom 
    // index is 1
    return (arr[row - 1][col - 1] == 1);
}
  
// Driver Code
int main()
{
    // Given array

419
Chapter 47. Check for possible path in 2D matrix

    int arr[row][col] = { { 0, 0, 0, -1, 0 },


                          { -1, 0, 0, -1, -1 },
                          { 0, 0, 0, -1, 0 },
                          { -1, 0, -1, 0, -1 },
                          { 0, 0, -1, 0, 0 } };
  
    // path from arr[0][0] to arr[row][col]
    if (isPath(arr))
      cout << "Yes";
    else
      cout << "No";
  
return 0;
}

Java

// Java program to find if there is path


// from top left to right bottom
class GFG
{
    // to find the path from
    // top left to bottom right
    static boolean isPath(int arr[][])
    {
        // set arr[0][0] = 1
        arr[0][0] = 1;
  
        // Mark reachable (from top left) nodes
        // in first row and first column.
        for (int i = 1; i < 5; i++)
            if (arr[0][i] != -1)
                arr[0][i] = arr[0][i - 1];
        for (int j = 1; j < 5; j++)
            if (arr[j][0] != -1)
                arr[j][0] = arr[j - 1][0];
  
        // Mark reachable nodes in
        //  remaining matrix.
        for (int i = 1; i < 5; i++)
            for (int j = 1; j < 5; j++)
                if (arr[i][j] != -1)
                    arr[i][j] = Math.max(arr[i][j - 1],
                                        arr[i - 1][j]);
  
        // return yes if right 
        // bottom index is 1
        return (arr[5 - 1][5 - 1] == 1);

420
Chapter 47. Check for possible path in 2D matrix

    }
       
    //Driver code 
    public static void main(String[] args)
    {
        // Given array
        int arr[][] = { { 0, 0, 0, -1, 0 },
                        { -1, 0, 0, -1, -1 },
                        { 0, 0, 0, -1, 0 },
                        { -1, 0, -1, 0, -1 },
                        { 0, 0, -1, 0, 0 } };
  
        // path from arr[0][0] 
        // to arr[row][col]
        if (isPath(arr))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
// This code is contributed 
// by prerna saini 

C#

// C# program to find if there is path


// from top left to right bottom
using System;
  
class GFG
{
    // to find the path from
    // top left to bottom right
    static bool isPath(int [,]arr)
    {
        // set arr[0][0] = 1
        arr[0, 0] = 1;
  
        // Mark reachable (from top left) nodes
        // in first row and first column.
        for (int i = 1; i < 5; i++)
            if (arr[0, i] != -1)
                arr[0, i] = arr[0, i - 1];
        for (int j = 1; j < 5; j++)
            if (arr[j,0] != -1)
                arr[j,0] = arr[j - 1, 0];
  
        // Mark reachable nodes in

421
Chapter 47. Check for possible path in 2D matrix

        // remaining matrix.


        for (int i = 1; i < 5; i++)
            for (int j = 1; j < 5; j++)
                if (arr[i, j] != -1)
                    arr[i, j] = Math.Max(arr[i, j - 1],
                                        arr[i - 1, j]);
  
        // return yes if right 
        // bottom index is 1
        return (arr[5 - 1, 5 - 1] == 1);
    }
      
    //Driver code 
    public static void Main()
    {
        // Given array
        int [,]arr = { { 0, 0, 0, -1, 0 },
                        { -1, 0, 0, -1, -1 },
                        { 0, 0, 0, -1, 0 },
                        { -1, 0, -1, 0, -1 },
                        { 0, 0, -1, 0, 0 } };
  
        // path from arr[0][0] 
        // to arr[row][col]
        if (isPath(arr))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
  
// This code is contributed 
// by vt_m

PHP

<?php
// PHP program to find if 
// there is path from top
// left to right bottom
$row = 5;
$col = 5;
  
// to find the path from
// top left to bottom right
function isPath($arr)
{
    global $row, $col;

422
Chapter 47. Check for possible path in 2D matrix

      
    $arr[0][0] = 1;
  
    // Mark reachable (from 
    // top left) nodes in 
    // first row and first column.
    for ($i = 1; $i < $row; $i++) 
        if ($arr[0][$i] != -1)
            $arr[0][$i] = $arr[0][$i - 1]; 
  
    for ($j = 1; $j < $col; $j++) 
        if ($arr[$j][0] != -1)
            $arr[$j][0] = $arr[$j - 1][0]; 
  
    // Mark reachable nodes 
    // in remaining matrix.
    for ($i = 1; $i < $row; $i++) 
        for ($j = 1; $j < $col; $j++) 
        if ($arr[$i][$j] != -1)
            $arr[$i][$j] = max($arr[$i][$j - 1],
                               $arr[$i - 1][$j]); 
      
    // return yes if right 
    // bottom index is 1
    return ($arr[$row - 1][$col - 1] == 1);
}
  
// Driver Code
  
// Given array
$arr = array(array(0, 0, 0, 1, 0),
             array(-1, 0, 0, -1, -1),
             array(0, 0, 0, -1, 0),
             array(-1, 0, -1, 0, -1),
             array(0, 0, -1, 0, 0));
  
// path from arr[0][0]
// to arr[row][col]
if (isPath($arr))
echo "Yes";
else
echo "No";
      
// This code is contributed by anuj_67.
?>

Output:

423
Chapter 47. Check for possible path in 2D matrix

No

Time Complexity is O(n^2).


Improved By : vt_m

Source

https://www.geeksforgeeks.org/check-possible-path-2d-matrix/

424
Chapter 48

Check if all people can vote on


two machines

Check if all people can vote on two machines - GeeksforGeeks


There are n people and two identical voting machines. We are also given an array a[] of
size n such that a[i] stores time required by i-th person to go to any machine, mark his vote
and come back. At one time instant, only one person can be there on each of the machines.
Given a value x, defining the maximum allowable time for which machines are operational,
check whether all persons can cast their vote or not.
Examples:

Input : n = 3, x = 4
a[] = {2, 4, 2}
Output : YES
There are n = 3 persons say and maximum
allowed time is x = 4 units. Let the persons
be P0, P1 and P2 and two machines be M0 and M1.
At t0 : P0 goes to M0
At t0 : P2 goes to M1
At t2 : M0 is free, p3 goes to M0
At t4 : both M0 and M1 are free and all 3 have
given their vote.

Let sum be the total time taken by all n people. If sum <=x, then answer will obviously
be YES. Otherwise, we need to check whether the given array can be split in two parts
such that sum of first part and sum of second part are both less than or equal to x. The
problem is similar to the knapsack problem. Imagine two knapsacks each with capacity x.
Now find, maximum people who can vote on any one machine i.e. find maximum subset
sum for knapsack of capacity x. Let this sum be s1. Now if (sum-s1) <= x, then answer is
YES else answer is NO.

425
Chapter 48. Check if all people can vote on two machines

// C++ program to check if all people can


// vote using two machines within limited
// time
#include<bits/stdc++.h>
using namespace std;
  
// Returns true if n people can vote using
// two machines in x time.
bool canVote(int a[], int n, int x)
{
    // dp[i][j] stores maximum possible number
    // of people among arr[0..i-1] can vote
    // in j time.
    int dp[n+1][x+1];
    memset(dp, 0, sizeof(dp));
  
    // Find sum of all times
    int sum = 0;
    for (int i=0; i<=n; i++ )
        sum += a[i];
  
    // Fill dp[][] in bottom up manner (Similar
    // to knapsack).
    for (int i=1; i<=n; i++)
        for (int j=1; j<=x; j++)
            if (a[i] <= j)
                dp[i][j] = max(dp[i-1][j],
                        a[i] + dp[i-1][j-a[i]]);
            else
                dp[i][j] = dp[i-1][j];
  
    // If remaining people can go to other machine.
    return (sum - dp[n][x] <= x);
}
  
// Driver code
int main()
{
    int n = 3, x = 4;
    int a[] = {2, 4, 2};
    canVote(a, n, x)? cout << "YES\n" :
                      cout << "NO\n";
    return 0;
}

Output:

426
Chapter 48. Check if all people can vote on two machines

YES

Time Complexity : O(x * n)


Auxiliary Space : O(x * n)

Source

https://www.geeksforgeeks.org/check-people-can-vote-two-machines/

427
Chapter 49

Check if any valid sequence is


divisible by M

Check if any valid sequence is divisible by M - GeeksforGeeks


Given an array of N integers, using ‘+’ and ‘-‘ between the elements check if there is a way
to form a sequence of numbers which evaluate to a number divisible by M
Examples:

Input : arr = {1, 2, 3, 4, 6}


M = 4
Output : True,
There is a valid sequence i. e., (1 - 2
+ 3 + 4 + 6), which evaluates to 12 that
is divisible by 4

Input : arr = {1, 3, 9}


M = 2
Output : False
There is no sequence which evaluates to
a number divisible by M.

A simple solution is to recursively consider all possible scenarios ie either use a ;+’ or a ‘-‘
operator between the elements and maintain a variable sum which stores the result.If this
result is divisible by M then return true else return false
Recursive implementation is as follows:

bool isPossible(int index, int sum)


{
    // Base case

428
Chapter 49. Check if any valid sequence is divisible by M

    if (index == n) {
    
        // check if sum is divisible by M
        if ((sum % M) == 0)
            return true;
        return false;
    }
  
    // recursively call by considering '+' 
    // or '-' between index and index+1
  
    // 1.Try placing '+'
    bool placeAdd = isPossible(index + 1, 
                        sum + arr[index]);
  
    // 2. Try placing '-'
    bool placeMinus = isPossible(index + 1, 
                         sum - arr[index]);
  
    if (placeAdd || placeMinus) 
        return true;
      
    return false;
}

There are overlapping subproblems as shown in the image below (Note: the image represents
the recursion tree till index = 3)

429
Chapter 49. Check if any valid sequence is divisible by M

So, now we will solve this using dynamic programming


Method 1:
We apply Dynamic Programming with two states :-
(i) index,
(ii) sum
So DP[index][sum] stores the current index we are at and sum stores the result of evaluation
of the sequence formed till that index.

#include <bits/stdc++.h>
using namespace std;
  
const int MAX = 1000;
  
bool isPossible(int n, int index, int sum, 
          int M, int arr[], int dp[][MAX])
{
  
    // Base case
    if (index == n) {
  
        // check if sum is divisible by M

430
Chapter 49. Check if any valid sequence is divisible by M

        if ((sum % M) == 0)
            return true;
        return false;
    }
  
    // check if the current state 
    // is already computed
    if (dp[index][sum] != -1) 
        return dp[index][sum];
      
    // 1.Try placing '+'
    bool placeAdd = isPossible(n, index + 1, 
               sum + arr[index], M, arr, dp);
  
    // 2. Try placing '-'
    bool placeMinus = isPossible(n, index + 1, 
                sum - arr[index], M, arr, dp);
  
    // calculate value of res for recursive case
    bool res = (placeAdd || placeMinus);
  
    // store the value for res for current 
    // states and return for parent call
    dp[index][sum] = res;
    return res;
}
int main()
{
    int arr[] = { 1, 2, 3, 4, 6 };
    int n = sizeof(arr)/sizeof(arr[0]);
    int M = 4;
  
    int dp[n + 1][MAX];
    memset(dp, -1, sizeof(dp));
  
    bool res;
    res = isPossible(n, 0, 0, M, arr, dp);
  
    cout << (res ? "True" : "False") << endl;
    return 0;
}

Output:

True

The Complexity of this method is O(N*sum) where sum is the maximum possible sum for

431
Chapter 49. Check if any valid sequence is divisible by M

the sequence of integers and N is the number of elements in the array.


Method 2(efficient):
This is more efficient than Method 1. Here also, we apply Dynamic Programming but with
two different states :-
(i) index,
(ii) modulo
So DP[index][modulo] stores the modulus of the result of evaluation of the sequence formed
till that index, with M.

#include <bits/stdc++.h>
using namespace std;
  
const int MAX = 100;
  
int isPossible(int n, int index, int modulo,
            int M, int arr[], int dp[][MAX])
{
    // Calculate modulo for this call
    modulo = ((modulo % M) + M) % M;
  
    // Base case
    if (index == n) {
  
        // check if sum is divisible by M
        if (modulo == 0)
            return 1;
        return 0;
    }
  
    // check if the current state is 
    // already computed
    if (dp[index][modulo] != -1) 
        return dp[index][modulo];
  
    // 1.Try placing '+'
    int placeAdd = isPossible(n, index + 1,
            modulo + arr[index], M, arr, dp);
  
    // 2. Try placing '-'
    int placeMinus = isPossible(n, index + 1, 
            modulo - arr[index], M, arr, dp);
  
    // calculate value of res for recursive
    // case
    bool res = (placeAdd || placeMinus);
  
    // store the value for res for current 
    // states and return for parent call

432
Chapter 49. Check if any valid sequence is divisible by M

    dp[index][modulo] = res;
    return res;
}
  
int main()
{
    int arr[] = { 1, 2, 3, 4, 6 };
    int n = sizeof(arr)/sizeof(arr[0]);
    int M = 4;
  
    // MAX is the Maximum value M can take
    int dp[n + 1][MAX];
    memset(dp, -1, sizeof(dp));
  
    bool res;
    res = isPossible(n, 1, arr[0], M, arr, dp);
  
    cout << (res ? "True" : "False") << endl;
    return 0;
}

Output:

True

The Complexity of this method is O(N*M).

Source

https://www.geeksforgeeks.org/check-valid-sequence-divisible-m/

433
Chapter 50

Check if array sum can be made


K by three operations on it

Check if array sum can be made K by three operations on it - GeeksforGeeks


Given an array A of N integers and a positive integer K. Only three operations can be
performed on this array:
1) Replace an integer with the negative value of the integer,
2) Add index number (1-based indexing) of the element to the element itself and
3) Subtract index number of the element from the element itself.
The task is to check if the given array can be transformed, using any of above three allowed
operations performed only once on each element. such that the sum of the array becomes
K.
Examples:

Input : N = 3, K = 2
A[] = { 1, 1, 1 }
Output : Yes
Explanation
Replace index 0 element with -1. It will sum of array equal to k = 2.

Input : N = 4, K = 5
A[] = { 1, 2, 3, 4 }
Output : Yes

Pre Requisites Dynamic Programming


Approach The idea is to use dynamic programming to solve the problem.
Declare a 2D Boolean array, dp[][], where dp[i][j] states if there is any way to obtain the
sum of the array equal to j using some operations on the firsti elements of the array.
dp[i][j] will be true if the sum is possible else it will be False.

434
Chapter 50. Check if array sum can be made K by three operations on it

Also, it is possible that the intermediate sum of the array is negative, in that case do not
perform any operation and ignore it thus letting the sum be always positive because k is
always positive.
For calculating dp[i][j] we need the values of all states that can make a sum j if we apply an
operation on a[i] and add it to the sum.
Below is the C++ implementation of this approach

/* C++ Program to find if Array can have a sum


   of K by applying three types of possible 
   operations on it */
#include <bits/stdc++.h>
using namespace std;
#define MAX 100
  
// Check if it is possible to achieve a sum with
// three operation allowed.
int check(int i, int sum, int n, int k, int a[],
                               int dp[MAX][MAX])
{
    // If sum is negative.
    if (sum <= 0)
        return false;
  
    // If going out of bound.
    if (i >= n) {
        // If sum is achieved.
        if (sum == k)
            return true;
  
        return false;
    }
  
    // If the current state is not evaluated yet.
    if (dp[i][sum] != -1)
        return dp[i][sum];
  
    // Replacing element with negative value of
    // the element.
    dp[i][sum] = check(i + 1, sum - 2 * a[i], n, 
          k, a, dp) || check(i + 1, sum, n, k, a, dp);
  
    // Substracting index number from the element.
    dp[i][sum] = check(i + 1, sum - (i + 1), n, 
         k, a, dp) || dp[i][sum];
  
    // Adding index number to the element.
    dp[i][sum] = check(i + 1, sum + i + 1, n,

435
Chapter 50. Check if array sum can be made K by three operations on it

                      k, a, dp) || dp[i][sum];


  
    return dp[i][sum];
}
  
// Wrapper Function
bool wrapper(int n, int k, int a[])
{
    int sum = 0;
    for (int i = 0; i < n; i++) 
        sum += a[i];    
  
    int dp[MAX][MAX];
    memset(dp, -1, sizeof(dp));
  
    return check(0, sum, n, k, a, dp);
}
  
// Driver Code
int main()
{
    int a[] = { 1, 2, 3, 4 };
    int n = 4, k = 5;
    (wrapper(n, k, a) ? (cout << "Yes") : (cout << "No"));
    return 0;
}

Output:

Yes

Source

https://www.geeksforgeeks.org/check-if-array-sum-can-be-made-k-by-three-operations-on-it/

436
Chapter 51

Check if it is possible to
transform one string to another

Check if it is possible to transform one string to another - GeeksforGeeks


Given two strings s1 and s2(call letters in uppercase). Check if it is possible to convert s1
to s2 by performing following operations.

1. Make some lowercase letters uppercase.


2. Delete all the lowercase letters.

Examples:

Input : s1 = daBcd s2 = ABC


Output : yes
Explanation : daBcd -> dABCd -> ABC
Covert a and b at index 1 and 3 to
upper case, delete the rest those are
lowercase. We get the string s2.

Input : s1 = argaju s2 = RAJ


Output : yes
Explanation : argaju -> aRgAJu -> RAJ
convert index 1, 3 and 4 to uppercase
and then delete. All lowercase letters

Input : s1 = ABcd s2= BCD


Output : NO

Approach:
Let DPi, j be 1 if it is possible to convert 1st i characters of s1 to j characters of s2, else
DPi, j =0. Close observations gives us two conditions to deal with.

437
Chapter 51. Check if it is possible to transform one string to another

Initially DP0, 0 =1, if DPi, j =1 then it is possible to check for next sets using following
conditions.
1. If s1[i] in upper case is equal to s2[j] then it is possible to convert i+1 characters of s1 to
j+1 characters of s2, hence DPi+1, j+1 =1.
2. If s1[i] is in lower case, then it is possible to delete that element and hence i+1 characters
can be converted to j characters of s2. Hence DPi+1, j =1.
If DPn, m =1, then it is possible to convert s1 to s2 by following conditions.
Below is the CPP illustration of the above approach.

C++

// cpp program to check if a string can


// be converted to another string by
// performing operations
#include <bits/stdc++.h>
using namespace std;
  
// function to check if a string can be
// converted to  another string by
// performing following operations
bool check(string s1, string s2)
{
    // calculates length
    int n = s1.length();
    int m = s2.length();
  
    bool dp[n + 1][m + 1];
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            dp[i][j] = false;
        }
    }
    // mark 1st position as true
    dp[0][0] = true;
  
    // traverese for all DPi, j
    for (int i = 0; i < s1.length(); i++) {
        for (int j = 0; j <= s2.length(); j++) {
  
            // if possible for to convert i 
            // characters of s1 to j characters
            // of s2
            if (dp[i][j]) {
  
                // if upper_case(s1[i])==s2[j]
                // is same

438
Chapter 51. Check if it is possible to transform one string to another

                if (j < s2.length() && 


                    (toupper(s1[i]) == s2[j]))
                    dp[i + 1][j + 1] = true;
  
                // if not upper then deletion is 
                // possible
                if (!isupper(s1[i]))
                    dp[i + 1][j] = true;
            }
        }
    }
  
    return (dp[n][m]);
}
  
// driver code
int main()
{
    string s1 = "daBcd";
    string s2 = "ABC";
  
    if (check(s1, s2))
        cout << "YES";
    else
        cout << "NO";
  
    return 0;
}

Java

// Java program to check if a string can


// be converted to another string by
// performing operations
import java.io.*;
  
class GFG {
      
    // function to check if a string can be
    // converted to another string by
    // performing following operations
    static boolean check(String s1, String s2)
    {
        // calculates length
        int n = s1.length();
        int m = s2.length();
      
        boolean dp[][]=new boolean[n + 1][m + 1];

439
Chapter 51. Check if it is possible to transform one string to another

        for (int i = 0; i <= n; i++) 


        {
            for (int j = 0; j <= m; j++)
            {
                dp[i][j] = false;
            }
        }
        // mark 1st position as true
        dp[0][0] = true;
      
        // traverese for all DPi, j
        for (int i = 0; i < s1.length(); i++)
        {
            for (int j = 0; j <= s2.length(); j++)
            {
      
                // if possible for to convert i 
                // characters of s1 to j characters
                // of s2
                if (dp[i][j]) {
      
                    // if upper_case(s1[i])==s2[j]
                    // is same
                    if (j < s2.length() && 
                        (Character.toUpperCase(s1.charAt(i)) == s2.charAt(j)))
                        dp[i + 1][j + 1] = true;
      
                    // if not upper then deletion is 
                    // possible
                    if (!Character.isUpperCase(s1.charAt(i)))
                        dp[i + 1][j] = true;
                }
            }
        }
      
        return (dp[n][m]);
    }
      
    // driver code
    public static void main(String args[])
    {
        String s1 = "daBcd";
        String s2 = "ABC";
      
        if (check(s1, s2))
            System.out.println("YES");
        else
            System.out.println("NO");

440
Chapter 51. Check if it is possible to transform one string to another

      
    }
}
  
// This code is contributed by Nikita Tiwari.

Output:

YES

Source

https://www.geeksforgeeks.org/check-possible-transform-one-string-another/

441
Chapter 52

Check if possible to cross the


matrix with given power

Check if possible to cross the matrix with given power - GeeksforGeeks


Given a matrix of N X M, each cell consist of an integer. We have initial power of K
and we are allowed to move right, down or diagonal. When we move to any cell, we absorb
mat[i][j] value and loose that much amount from your power. If our power became less than
0 at any time, we cannot move further from that point. Now, our task is to find if there
is any path from (1, 1) to (n, m) that we can cover with power k. If possible, output the
maximum value we can absorb, else if there is no path print “-1”.
Examples :

Input : N = 3, M = 3, K = 7
mat[][] = { { 2, 3, 1 },
{ 6, 1, 9 },
{ 8, 2, 3 } };
Output : 6
Path (1, 1) -> (2, 2) -> (3, 3) to complete
journey to absorb 6 value.

Input : N = 3, M = 4, K = 9
mat[][] = {
{ 2, 3, 4, 1 },
{ 6, 5, 5, 3 },
{ 5, 2, 3, 4 }
};
Output : -1

The idea is to use Dynamic Programming to solve the problem.


Approach :

442
Chapter 52. Check if possible to cross the matrix with given power

• Declare a boolean 3D matrix, say dp[ ][ ][ ], with N*M*(K+1) dimension such that
dp[ i ][ j ][ k ] is true if it possible to reach the square in the ith row and jth column
with exactly k value collected so far.
• We can write the recurrence dp[ i ][ j ][ k ] = true if either

dp[i-1][j][k-mat[i][j]] or
dp[i][j-1][k-mat[i][j]] or
dp[i-1][j-1][k-mat[i][j]]

i.e the three possible moves we could have.


• We have base case dp[0][0][0] be true.
• The answer is -2 if dp[n-1][m-1][k] is false for all k between 0 and k+1.

• Otherwise, the answer is the maximum k such that dp[n-1][m-1][k] is true.

Below is C++ implementation of this approach :


CPP

// CPP program to find if it is possible to cross


// the matrix with given power
#include <bits/stdc++.h>
#define N 105
#define R 3
#define C 4
using namespace std;
  
int maximumValue(int n, int m, int p, int grid[R][C])
{
    bool dp[N][N][N];
  
    // Initializing array dp with false value.
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            for (int k = 0; k < N; k++)
                dp[i][j][k] = false;
        }
    }
  
    // For each value of dp[i][j][k]
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            for (int k = grid[i][j]; k <= p; k++) {
  
                // For first cell and for each value of k
                if (i == 0 && j == 0) {

443
Chapter 52. Check if possible to cross the matrix with given power

                    if (k == grid[i][j])
                        dp[i][j][k] = true;
                }
  
                // For first cell of each row
                else if (i == 0) {
                    dp[i][j][k] = (dp[i][j][k] || 
                        dp[i][j - 1][k - grid[i][j]]);
                }
  
                // For first cell of each column
                else if (j == 0) {
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
                }
  
                // For rest of the cell
                else {
  
                    // Down movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i][j - 1][k - grid[i][j]]);
  
                    // Right movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
  
                    // Diagonal movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j - 1][k - grid[i][j]]);
                }
            }
        }
    }
  
    // Finding maximum k.
    int ans = 0;
    for (ans = k; ans >= 0; ans--)
        if (dp[n - 1][m - 1][ans])
            break;
  
    return ans;
}
  
// Driver Code
int main()
{
    int n = 3, m = 4, p = 9;

444
Chapter 52. Check if possible to cross the matrix with given power

    int grid[R][C] = {
        { 2, 3, 4, 1 },
        { 6, 5, 5, 3 },
        { 5, 2, 3, 4 }
    };
  
    cout << maximumValue(n, m, p, grid) << endl;
    return 0;
}

Java

// Java program to find if it 


// is possible to cross the matrix
// with given power
class GFG
{
      
static final int N = 105;
static final int R = 3;
static final int C = 4;
  
static int maximumValue(int n, int m, int p,
                                int grid[][])
{
    boolean dp[][][] = new boolean[N][N][N];
    int i, j, k;
  
    // Initializing array dp with false value.
    for (i = 0; i < N; i++) {
        for (j = 0; j < N; j++) {
            for (k = 0; k < N; k++)
                dp[i][j][k] = false;
        }
    }
  
    // For each value of dp[i][j][k]
    for (i = 0; i < n; i++) {
        for (j = 0; j < m; j++) {
            for (k = grid[i][j]; k <= p; k++) {
  
                // For first cell and for 
                // each value of k
                if (i == 0 && j == 0) {
                    if (k == grid[i][j])
                        dp[i][j][k] = true;
                }
  

445
Chapter 52. Check if possible to cross the matrix with given power

                // For first cell of each row


                else if (i == 0) {
                    dp[i][j][k] = (dp[i][j][k] || 
                        dp[i][j - 1][k - grid[i][j]]);
                }
  
                // For first cell of each column
                else if (j == 0) {
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
                }
  
                // For rest of the cell
                else {
  
                    // Down movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i][j - 1][k - grid[i][j]]);
  
                    // Right movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j][k - grid[i][j]]);
  
                    // Diagonal movement.
                    dp[i][j][k] = (dp[i][j][k] ||
                        dp[i - 1][j - 1][k - grid[i][j]]);
                }
            }
        }
    }
    k = p;
      
    // Finding maximum k.
    int ans = 0;
    for (ans = k; ans >= 0; ans--)
        if (dp[n - 1][m - 1][ans])
            break;
  
    return ans;
}
  
  
// Driver code 
public static void main (String[] args)
{
    int n = 3, m = 4, p = 9;
    int grid[][] = {{ 2, 3, 4, 1 },
                    { 6, 5, 5, 3 },

446
Chapter 52. Check if possible to cross the matrix with given power

                    { 5, 2, 3, 4 }};
  
    System.out.println(maximumValue(n, m, p, grid));
}
}
  
// This code is contributed by Anant Agarwal.

C#

// C# program to find if it
// is possible to cross the matrix
// with given power
using System;
  
class GFG {
  
    static int N = 105;
    // static int R = 3;
    // static int C = 4;
  
    static int maximumValue(int n, int m, int p,
                                   int[, ] grid)
    {
        bool[,, ] dp = new bool[N, N, N];
        int i, j, k;
  
        // Initializing array dp with false value.
        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                for (k = 0; k < N; k++)
                    dp[i, j, k] = false;
            }
        }
  
        // For each value of dp[i][j][k]
        for (i = 0; i < n; i++) {
            for (j = 0; j < m; j++) {
                for (k = grid[i, j]; k <= p; k++) {
  
                    // For first cell and for
                    // each value of k
                    if (i == 0 && j == 0) {
                        if (k == grid[i, j])
                            dp[i, j, k] = true;
                    }
  
                    // For first cell of each row

447
Chapter 52. Check if possible to cross the matrix with given power

                    else if (i == 0) {
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i, j - 1, k - grid[i, j]]);
                    }
  
                    // For first cell of each column
                    else if (j == 0) {
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i - 1, j, k - grid[i, j]]);
                    }
  
                    // For rest of the cell
                    else {
  
                        // Down movement.
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i, j - 1, k - grid[i, j]]);
  
                        // Right movement.
                        dp[i, j, k] = (dp[i, j, k] || 
                        dp[i - 1, j, k - grid[i, j]]);
  
                        // Diagonal movement.
                        dp[i, j, k] = (dp[i, j, k] ||
                        dp[i - 1, j - 1, k - grid[i, j]]);
                    }
                }
            }
        }
        k = p;
  
        // Finding maximum k.
        int ans = 0;
        for (ans = k; ans >= 0; ans--)
            if (dp[n - 1, m - 1, ans])
                break;
  
        return ans;
    }
  
    // Driver code
    public static void Main()
    {
        int n = 3, m = 4, p = 9;
        int[, ] grid = { { 2, 3, 4, 1 },
                         { 6, 5, 5, 3 },
                         { 5, 2, 3, 4 } };
  

448
Chapter 52. Check if possible to cross the matrix with given power

        Console.WriteLine(maximumValue(n, m, p, grid));
    }
}
  
// This code is contributed by vt_m.

Output:

-1

Time Complexity: O(n3 )

Source

https://www.geeksforgeeks.org/check-possible-cross-matrix-given-power/

449
Chapter 53

Check whether row or column


swaps produce maximum size
binary sub-matrix with all 1s

Check whether row or column swaps produce maximum size binary sub-matrix with all 1s -
GeeksforGeeks
Given a binary matrix, the task is to find whether row swaps or column swaps give maximum
size sub-matrix with all 1’s. In a row swap, we are allowed to swap any two rows. In a
column swap we are allowed to swap any two columns. Output “Row Swap” or “Column
Swap” and the maximum size.
Examples:

Input : 1 1 1
1 0 1
Output : Column Swap
4
By swapping column 1 and column 2(0-based indexing),
index (0, 0) to (1, 1) makes the largest binary
sub-matrix.

Input : 0 0 0
1 1 0
1 1 0
0 0 0
1 1 0
Output : Row Swap
6

Input : 1 1 0

450
Chapter 53. Check whether row or column swaps produce maximum size binary sub-matrix
with all 1s

0 0 0
0 0 0
1 1 0
1 1 0
0 0 0
1 1 0
Output : Row Swap
8

The idea is to find both row swap and column swap maximum size binary submatrix and
compare.
To find the maximum sized binary sub-matrix with row swaps allowed, make a 2-D array,
say dp[i][j]. Each value of dp[i][j] contains the number of consecutive 1s on right side of (i,j)
in i-th row. Now, store each column in the 1-D temporary array one by one, say b[] and
sort, and find maximum b[i] * (n – i), since b[i] is indicating the sub-matrix width and (n –
i) is sub-matrix height.
Similarly, to find the maximum size binary sub-matrix with column swap allowed, find
dp[i][j], where each value contains the number of consecutive 1 below the (i, j) in j-th
column. Similarly, store each row in the 1-D temporary array one by one, say b[] and sort.
Find maximum b[i] * (m – i), since b[i] is indicating the submatrix height and (n – i) is
submatrix width.
Below is C++ implementation of this approach:

// C++ program to find maximum binary sub-matrix


// with row swaps and column swaps.
#include <bits/stdc++.h>
#define R 5
#define C 3
using namespace std;
  
// Precompute the number of consecutive 1 below the
// (i, j) in j-th column and the number of consecutive 1s
// on right side of (i, j) in i-th row.
void precompute(int mat[R][C], int ryt[][C + 2],
                               int dwn[R + 2][C + 2])
{
    // Travesing the 2d matrix from top-right.
    for (int j=C-1; j>=0; j--)
    {
        for (int i=0; i<R; ++i)
        {
            // If (i,j) contain 0, do nothing
            if (mat[i][j] == 0)
                ryt[i][j] = 0;
  
            // Counting consecutive 1 on right side

451
Chapter 53. Check whether row or column swaps produce maximum size binary sub-matrix
with all 1s

            else
                ryt[i][j] = ryt[i][j + 1] + 1;
        }
    }
  
  
    // Travesing the 2d matrix from bottom-left.
    for (int i = R - 1; i >= 0; i--)
    {
        for (int j = 0; j < C; ++j)
        {
            // If (i,j) contain 0, do nothing
            if (mat[i][j] == 0)
                dwn[i][j] = 0;
  
            // Counting consecutive 1 down to (i,j).
            else
                dwn[i][j] = dwn[i + 1][j] + 1;
        }
    }
}
  
// Return maximum size submatrix with row swap allowed.
int solveRowSwap(int ryt[R + 2][C + 2])
{
    int b[R] = { 0 }, ans = 0;
  
    for (int j=0; j<C; j++)
    {
        // Copying the column
        for (int i=0; i<R; i++)
            b[i] = ryt[i][j];
  
        // Sort the copied array
        sort(b, b + R);
  
        // Find maximum submatrix size.
        for (int i = 0; i < R; ++i)
            ans = max(ans, b[i] * (R - i));
    }
  
    return ans;
}
  
// Return maximum size submatrix with column
// swap allowed.
int solveColumnSwap(int dwn[R + 2][C + 2])
{

452
Chapter 53. Check whether row or column swaps produce maximum size binary sub-matrix
with all 1s

    int b[C] = { 0 }, ans = 0;


  
    for (int i = 0; i < R; ++i)
    {
        // Copying the row.
        for (int j = 0; j < C; ++j)
            b[j] = dwn[i][j];
  
        // Sort the copied array
        sort(b, b + C);
  
        // Find maximum submatrix size.
        for (int i = 0; i < C; ++i)
            ans = max(ans, b[i] * (C - i));
    }
  
    return ans;
}
  
void findMax1s(int mat[R][C])
{
    int ryt[R + 2][C + 2], dwn[R + 2][C + 2];
    memset(ryt, 0, sizeof ryt);
    memset(dwn, 0, sizeof dwn);
  
    precompute(mat, ryt, dwn);
  
    // Solving for row swap and column swap
    int rswap = solveRowSwap(ryt);
    int cswap = solveColumnSwap(dwn);
  
    // Comparing both.
    (rswap > cswap)? (cout << "Row Swap\n" << rswap << endl):
                     (cout << "Column Swap\n" << cswap << endl);
}
  
// Driven Program
int main()
{
    int mat[R][C] = {{ 0, 0, 0 },
                     { 1, 1, 0 },
                     { 1, 1, 0 },
                     { 0, 0, 0 },
                     { 1, 1, 0 }};
  
    findMax1s(mat);
    return 0;
}

453
Chapter 53. Check whether row or column swaps produce maximum size binary sub-matrix
with all 1s

Output:

Row Swap
6

Source

https://www.geeksforgeeks.org/check-whether-row-column-swap-produces-maximum-size-binary-sub-matrix-1s/

454
Chapter 54

Choice of Area

Choice of Area - GeeksforGeeks


Consider a game, in which you have two types of powers, A and B and there are 3 types
of Areas X, Y and Z. Every second you have to switch between these areas, each area has
specific properties by which your power A and power B increase or decrease. We need to
keep choosing areas in such a way that our survival time is maximized. Survival time ends
when any of the powers, A or B reaches less than 0.
Examples:

Initial value of Power A = 20


Initial value of Power B = 8

Area X (3, 2) : If you step into Area X,


A increases by 3,
B increases by 2

Area Y (-5, -10) : If you step into Area Y,


A decreases by 5,
B decreases by 10

Area Z (-20, 5) : If you step into Area Z,


A decreases by 20,
B increases by 5

It is possible to choose any area in our first step.


We can survive at max 5 unit of time by following
these choice of areas :
X -> Z -> X -> Y -> X

This problem can be solved using recursion, after each time unit we can go to any of the
area but we will choose that area which ultimately leads to maximum survival time. As

455
Chapter 54. Choice of Area

recursion can lead to solving same subproblem many time, we will memoize the result on
basis of power A and B, if we reach to same pair of power A and B, we won’t solve it again
instead we will take the previously calculated result.
Given below is the simple implementation of above approach.

CPP

//  C++ code to get maximum survival time


#include <bits/stdc++.h>
using namespace std;
  
//  structure to represent an area
struct area
{
    //  increment or decrement in A and B
    int a, b;
    area(int a, int b) : a(a), b(b)
    {}
};
  
//  Utility method to get maximum of 3 integers
int max(int a, int b, int c)
{
    return max(a, max(b, c));
}
  
//  Utility method to get maximum survival time
int maxSurvival(int A, int B, area X, area Y, area Z,
                int last, map<pair<int, int>, int>& memo)
{
    //  if any of A or B is less than 0, return 0
    if (A <= 0 || B <= 0)
        return 0;
    pair<int, int> cur = make_pair(A, B);
  
    //  if already calculated, return calculated value
    if (memo.find(cur) != memo.end())
        return memo[cur];
  
    int temp;
  
    //  step to areas on basis of last chose area
    switch(last)
    {
    case 1:
        temp = 1 + max(maxSurvival(A + Y.a, B + Y.b,
                                   X, Y, Z, 2, memo),
                       maxSurvival(A + Z.a, B + Z.b,

456
Chapter 54. Choice of Area

                                  X, Y, Z, 3, memo));
        break;
    case 2:
        temp = 1 + max(maxSurvival(A + X.a, B + X.b,
                                  X, Y, Z, 1, memo),
                       maxSurvival(A + Z.a, B + Z.b,
                                  X, Y, Z, 3, memo));
        break;
    case 3:
        temp = 1 + max(maxSurvival(A + X.a, B + X.b,
                                  X, Y, Z, 1, memo),
                       maxSurvival(A + Y.a, B + Y.b,
                                  X, Y, Z, 2, memo));
        break;
    }
  
    //  store the result into map
    memo[cur] = temp;
  
    return temp;
}
  
//  method returns maximum survival time
int getMaxSurvivalTime(int A, int B, area X, area Y, area Z)
{
    if (A <= 0 || B <= 0)
        return 0;
    map< pair<int, int>, int > memo;
  
    //  At first, we can step into any of the area
    return
        max(maxSurvival(A + X.a, B + X.b, X, Y, Z, 1, memo),
            maxSurvival(A + Y.a, B + Y.b, X, Y, Z, 2, memo),
            maxSurvival(A + Z.a, B + Z.b, X, Y, Z, 3, memo));
}
  
//  Driver code to test above method
int main()
{
    area X(3, 2);
    area Y(-5, -10);
    area Z(-20, 5);
  
    int A = 20;
    int B = 8;
    cout << getMaxSurvivalTime(A, B, X, Y, Z);
  
    return 0;

457
Chapter 54. Choice of Area

Python3

# Python code to get maximum survival time


  
# Class to represent an area
class area:
    def __init__(self, a, b):
        self.a = a
        self.b = b
  
# Utility method to get maximum survival time
def maxSurvival(A, B, X, Y, Z, last, memo):
    # if any of A or B is less than 0, return 0
    if (A <= 0 or B <= 0):
        return 0
    cur = area(A, B)
  
    # if already calculated, return calculated value
    for ele in memo.keys():
        if (cur.a == ele.a and cur.b == ele.b):
            return memo[ele]
  
    # step to areas on basis of last chosen area
    if (last == 1):
        temp = 1 + max(maxSurvival(A + Y.a, B + Y.b,
                                   X, Y, Z, 2, memo),
                       maxSurvival(A + Z.a, B + Z.b,
                                   X, Y, Z, 3, memo))
    elif (last == 2):
        temp = 1 + max(maxSurvival(A + X.a, B + X.b,
                                   X, Y, Z, 1, memo),
               maxSurvival(A + Z.a, B + Z.b,
                   X, Y, Z, 3, memo))
    elif (last == 3):
        temp = 1 + max(maxSurvival(A + X.a, B + X.b,
                   X, Y, Z, 1, memo),
               maxSurvival(A + Y.a, B + Y.b,
                   X, Y, Z, 2, memo))
  
    # store the result into map
    memo[cur] = temp
  
    return temp
  
# method returns maximum survival time
def getMaxSurvivalTime(A, B, X, Y, Z):

458
Chapter 54. Choice of Area

    if (A <= 0 or B <= 0):


        return 0
    memo = dict()
  
    # At first, we can step into any of the area
    return max(maxSurvival(A + X.a, B + X.b, X, Y, Z, 1, memo),
           maxSurvival(A + Y.a, B + Y.b, X, Y, Z, 2, memo),
           maxSurvival(A + Z.a, B + Z.b, X, Y, Z, 3, memo))
  
# Driver code to test above method
X = area(3, 2)
Y = area(-5, -10)
Z = area(-20, 5)
  
A = 20
B = 8
print(getMaxSurvivalTime(A, B, X, Y, Z))
  
# This code is contributed by Soumen Ghosh.

Output:

Source

https://www.geeksforgeeks.org/game-theory-choice-area/

459
Chapter 55

Choose maximum weight with


given weight and value ratio

Choose maximum weight with given weight and value ratio - GeeksforGeeks
Given weights and values of n items and a value k. We need to choose a subset of these
items in such a way that ratio of the sum of weight and sum of values of chosen items is K
and sum of weight is maximum among all possible subset choices.

Input : weight[] = [4, 8, 9]


values[] = [2, 4, 6]
K = 2
Output : 12
We can choose only first and second item only,
because (4 + 8) / (2 + 4) = 2 which is equal to K
we can't include third item with weight 9 because
then ratio condition won't be satisfied so result
will be (4 + 8) = 12

We can solve this problem using dynamic programming. We can make a 2 state dp where
dp(i, j) will store maximum possible sum of weights under given conditions when total items
are N and required ratio is K.
Now in two states of dp, we will store the last item chosen and the difference between sum
of weight and sum of values. We will multiply item values by K so that second state of dp
will actually store (sum of weight – K*(sum of values)) for chosen items. Now we can see
that our answer will be stored in dp(N-1, 0) because as last item is (N-1)th so all items
are being considered and difference between sum of weight and K*(sum of values) is 0 that
means sum of weight and sum of values has a ratio K.
After defining above dp state we can write transition among states simply as shown below,

460
Chapter 55. Choose maximum weight with given weight and value ratio

dp(last, diff) = max (dp(last - 1, diff),


dp(last-1, diff + wt[last] - val[last]*K))

dp(last – 1, diff) represents the condition when current


item is not chosen and
dp(last – 1, diff + wt[last] – val[last] * K)) represents
the condition when current item is chosen so difference
is updated with weight and value of current item.

In below code a top-down approach is used for solving this dynamic programming and for
storing dp states a map is used because the difference can be negative also and the 2D array
can create problem in that case and special care need to be taken.
C++

// C++ program to choose item with maximum


// sum of weight under given constraint
#include <bits/stdc++.h>
using namespace std;
  
// memoized recursive method to return maximum
// weight with K as ratio of weight and values
int maxWeightRec(int wt[], int val[], int K,
                  map<pair<int, int>, int>& mp,
                            int last, int diff)
{
    //  base cases : if no item is remaining
    if (last == -1)
    {
        if (diff == 0)
            return 0;
        else
            return INT_MIN;
    }
  
    // first make pair with last chosen item and
    // difference between weight and values
    pair<int, int> tmp = make_pair(last, diff);
    if (mp.find(tmp) != mp.end())
        return mp[tmp];
  
    /*  choose maximum value from following two
        1) not selecting the current item and calling
           recursively
        2) selection current item, including the weight
           and updating the difference before calling
           recurively */
    mp[tmp] = max(maxWeightRec(wt, val, K, mp, last - 1, diff),

461
Chapter 55. Choose maximum weight with given weight and value ratio

                   wt[last] + maxWeightRec(wt, val, K, mp,


                   last - 1, diff + wt[last] - val[last] * K));
  
    return mp[tmp];
}
  
// method returns maximum sum of weight with K
// as ration of sum of weight and their values
int maxWeight(int wt[], int val[], int K, int N)
{
    map<pair<int, int>, int> mp;
    return maxWeightRec(wt, val, K, mp, N - 1, 0);
}
  
//  Driver code to test above methods
int main()
{
    int wt[] = {4, 8, 9};
    int val[] = {2, 4, 6};
    int N = sizeof(wt) / sizeof(int);
    int K = 2;
  
    cout << maxWeight(wt, val, K, N);
    return 0;
}

Java

// Java program to choose item with maximum


// sum of weight under given constraint
  
import java.awt.Point;
import java.util.HashMap;
  
class Test
{
    // memoized recursive method to return maximum
    // weight with K as ratio of weight and values
    static int maxWeightRec(int wt[], int val[], int K,
                      HashMap<Point, Integer> hm,
                                int last, int diff)
    {
        //  base cases : if no item is remaining
        if (last == -1)
        {
            if (diff == 0)
                return 0;
            else

462
Chapter 55. Choose maximum weight with given weight and value ratio

                return Integer.MIN_VALUE;
        }
       
        // first make pair with last chosen item and
        // difference between weight and values
        Point tmp = new Point(last, diff);
        if (hm.containsKey(tmp))
            return hm.get(tmp);
       
        /*  choose maximum value from following two
            1) not selecting the current item and calling
               recursively
            2) selection current item, including the weight
               and updating the difference before calling
               recursively */
       hm.put(tmp,Math.max(maxWeightRec(wt, val, K, hm, last - 1, diff),
                       wt[last] + maxWeightRec(wt, val, K, hm,
                       last - 1, diff + wt[last] - val[last] * K)));
       
        return hm.get(tmp);
    }
       
    // method returns maximum sum of weight with K
    // as ration of sum of weight and their values
    static int maxWeight(int wt[], int val[], int K, int N)
    {
        HashMap<Point, Integer> hm = new HashMap<>();
        return maxWeightRec(wt, val, K, hm, N - 1, 0);
    }
      
    // Driver method
    public static void main(String args[])
    {
        int wt[] = {4, 8, 9};
        int val[] = {2, 4, 6};
          
        int K = 2;
       
        System.out.println(maxWeight(wt, val, K, wt.length));
    }
}
// This code is contributed by Gaurav Miglani

Output:

12

463
Chapter 55. Choose maximum weight with given weight and value ratio

Source

https://www.geeksforgeeks.org/choose-maximum-weight-given-weight-value-ratio/

464
Chapter 56

Clustering/Partitioning an
array such that sum of square
differences is minimum

Clustering/Partitioning an array such that sum of square differences is minimum - Geeks-


forGeeks
Given an array of n numbers and a number k. We need to divide the array into k par-
titions (clusters) of same or different length. For a given k, there can be one or more

ways to make clusters (partitions). We define a function Cost(i) for the cluster, as
the square of the difference between its first and last element. If the current cluster is

, where is the length of

current cluster, then .


Amongst all the possible kinds of partitions, we have to find the partition that will minimize
the function,

Examples :

Input : arr[] = {1, 5, 8, 10}


k = 2
Output : 20
Explanation :

465
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

Consider clustering 4 elements 1, 5, 8, 10


into 2 clusters. There are three options:
1. S1 = 1, S2 = 5, 8, 10, with total cost
+ = 25.
2. S1 = 1, 5, S2 = 8, 10, with total cost
+ = 20.
3. S1 = 1, 5, 8, S2 = 10, with total cost
+ = 49.
So, the optimal clustering is the second one,
so the output of the above problem is 20.

Input : arr[] = {5, 8, 1, 10}


k = 3
Output : 20
Explanation :
The three partitions are {5, 8}, {1} and {10}

To solve the problem, we assume that we have k slabs. We have to insert them in some k
different positions in the array, which will give us the required partition scheme, and the
one having minimum value for f(x) will be the answer.
Naive solution:
If we solve the above problem by the naive method, we would simply take all the possibilities
and compute the minimum.

C++

// C++ program to find minimum cost k partitions


// of array.
#include<iostream>
using namespace std;
  
// Initialize answer as infinite.
const int inf = 1000000000;
int ans = inf;
  
// function to generate all possible answers.
// and comute minimum of all costs.
// i   --> is index of previous partition
// par --> is current number of partitions
// a[] and n --> Input array and its size
// current_ans --> Cost of partitions made so far.
void solve(int i, int par, int a[], int n,
                  int k, int current_ans)
{
    // If number of partitions is more than k
    if (par > k)

466
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

        return;
  
    // If we have mad k partitions and have
    // reached last element
    if (par==k && i==n-1)
    {
        ans = min(ans, current_ans);
        return;
    }
  
    // 1) Partition array at different points
    // 2) For every point, increase count of 
    //    partitions, "par" by 1.
    // 3) Before recursive call, add cost of 
    //    the partition to current_ans
    for (int j=i+1; j<n; j++)
        solve(j, par+1, a, n, k, current_ans +
                  (a[j]-a[i+1])*(a[j]-a[i+1]));
}
  
// Driver code
int main()
{
    int k = 2;
    int a[] = {1, 5, 8, 10};
    int n = sizeof(a)/sizeof(a[0]);
    solve(-1, 0, a, n, k, 0);
    cout << ans << endl;
    return 0;
}

Java

// Java program to find minimum cost k partitions


// of array.
import java.io.*;
  
class GFG
{
    // Initialize answer as infinite.
    static int inf = 1000000000;
    static int ans = inf;
      
    // function to generate all possible answers.
    // and comute minimum of all costs.
    // i --> is index of previous partition
    // par --> is current number of partitions
    // a[] and n --> Input array and its size

467
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

    // current_ans --> Cost of partitions made so far.


    static void solve(int i, int par, int a[], int n,
                               int k, int current_ans)
    {
        // If number of partitions is more than k
        if (par > k)
            return;
      
        // If we have mad k partitions and have
        // reached last element
        if (par == k && i == n - 1)
        {
            ans = Math.min(ans, current_ans);
            return;
        }
      
        // 1) Partition array at different points
        // 2) For every point, increase count of 
        // partitions, "par" by 1.
        // 3) Before recursive call, add cost of 
        // the partition to current_ans
        for (int j = i + 1; j < n; j++)
            solve(j, par + 1, a, n, k, current_ans +
                 (a[j] - a[i + 1]) * (a[j] - a[i + 1]));
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int k = 2;
        int a[] = {1, 5, 8, 10};
        int n = a.length;
        solve(-1, 0, a, n, k, 0);
        System.out.println(ans);
          
    }

  
// This code is contributed by vt_m.

C#

// C# program to find minimum


// cost k partitions of array.
using System;
  
class GFG
{

468
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

    // Initialize answer as infinite.


    static int inf = 1000000000;
    static int ans = inf;
      
    // function to generate all possible answers.
    // and comute minimum of all costs.
    // i --> is index of previous partition
    // par --> is current number of partitions
    // a[] and n --> Input array and its size
    // current_ans --> Cost of partitions made so far.
    static void solve(int i, int par, int []a,
                      int n, int k, int current_ans)
    {
        // If number of partitions is more than k
        if (par > k)
            return;
      
        // If we have mad k partitions and
        // have reached last element
        if (par == k && i == n - 1)
        {
            ans = Math.Min(ans, current_ans);
            return;
        }
      
        // 1) Partition array at different points
        // 2) For every point, increase count of 
        // partitions, "par" by 1.
        // 3) Before recursive call, add cost of 
        // the partition to current_ans
        for (int j = i + 1; j < n; j++)
            solve(j, par + 1, a, n, k, current_ans +
                 (a[j] - a[i + 1]) * (a[j] - a[i + 1]));
    }
      
    // Driver code
    public static void Main () 
    {
        int k = 2;
        int []a = {1, 5, 8, 10};
        int n = a.Length;
        solve(-1, 0, a, n, k, 0);
        Console.Write(ans);
    }

  
// This code is contributed by nitin mittal.

469
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

Output:

20

Time Complexity: Its clear that the above algorithm has Time Complexity of .

Dynamic Programming:
We create a table dp[n+1][k+1] table and initialize all values as infinite.

dp[i][j] stores optimal partition cost


for arr[0..i-1] and j partitions.

Let us compute the value of dp[i][j]. we take an index m, such that m < i, and put a partition
next to that position such that there is no slab in between the indices i and m. It can be
seen simply that answer to the current scenario is dp[m][j-1] + (a[i-1]-a[m])*(a[i-1]-a[m]),

where the first term signifies the minimum f(x) till the element with j-1 partitions
and the second one signifies the cost of current cluster. So we will take the minimum of all
the possible indices m and dp[i][j] will be assigned the minimum amongst them.
C++

// C++ program to find minimum cost k partitions


// of array.
#include<iostream>
using namespace std;
const int inf = 1000000000;
  
// Returns minimum cost of partitioning a[] in
// k clusters.
int minCost(int a[], int n, int k)
{
    // Create a dp[][] table and initialize
    // all values as infinite. dp[i][j] is
    // going to store optimal partition cost
    // for arr[0..i-1] and j partitions
    int dp[n+1][k+1];
    for (int i=0; i<=n; i++)
        for (int j=0;j<=k;j++)
            dp[i][j] = inf;
  
    // Fill dp[][] in bottom up manner
    dp[0][0] = 0;

470
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

  
    // Current ending position (After i-th
    // iteration result for a[0..i-1] is computed.
    for (int i=1;i<=n;i++)
  
        // j is number of partitions
        for (int j=1;j<=k;j++)
  
            // Picking previous partition for
            // current i.
            for (int m=i-1;m>=0;m--)
                dp[i][j] = min(dp[i][j], dp[m][j-1] +
                          (a[i-1]-a[m])*(a[i-1]-a[m]));
  
  
    return dp[n][k];
}
  
// Driver code
int main()
{
    int k = 2;
    int a[] = {1, 5, 8, 10};
    int n = sizeof(a)/sizeof(a[0]);
    cout << minCost(a, n, k) << endl;
    return 0;
}

Java

// Java program to find minimum cost 


// k partitions of array.
import java.io.*;
  
class GFG 
{
    static int inf = 1000000000;
      
    // Returns minimum cost of partitioning 
    // a[] in k clusters.
    static int minCost(int a[], int n, int k)
    {
        // Create a dp[][] table and initialize
        // all values as infinite. dp[i][j] is
        // going to store optimal partition cost
        // for arr[0..i-1] and j partitions
        int dp[][] = new int[n + 1][k + 1];
        for (int i = 0; i <= n; i++)

471
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

            for (int j = 0; j <= k; j++)


                dp[i][j] = inf;
      
        // Fill dp[][] in bottom up manner
        dp[0][0] = 0;
      
        // Current ending position (After i-th
        // iteration result for a[0..i-1] is computed.
        for (int i = 1; i <= n; i++)
      
            // j is number of partitions
            for (int j = 1; j <= k; j++)
      
                // Picking previous partition for
                // current i.
                for (int m = i - 1; m >= 0; m--)
                    dp[i][j] = Math.min(dp[i][j], dp[m][j - 1] +
                              (a[i - 1] - a[m]) * (a[i - 1] - a[m]));
      
      
        return dp[n][k];
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int k = 2;
        int a[] = {1, 5, 8, 10};
        int n = a.length;
        System.out.println(minCost(a, n, k));
              
    }
}
  
// This code is contributed by vt_m.

C#

// C# program to find minimum cost 


// k partitions of array.
using System;
  
class GFG {
      
    static int inf = 1000000000;
      
    // Returns minimum cost of partitioning 
    // a[] in k clusters.

472
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

    static int minCost(int []a, int n, int k)


    {
          
        // Create a dp[][] table and initialize
        // all values as infinite. dp[i][j] is
        // going to store optimal partition cost
        // for arr[0..i-1] and j partitions
        int [,]dp = new int[n + 1,k + 1];
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= k; j++)
                dp[i,j] = inf;
      
        // Fill dp[][] in bottom
        // up manner
        dp[0,0] = 0;
      
        // Current ending position 
        // (After i-th iteration 
        // result for a[0..i-1]
        // is computed.
        for (int i = 1; i <= n; i++)
      
            // j is number of partitions
            for (int j = 1; j <= k; j++)
      
                // Picking previous
                // partition for
                // current i.
                for (int m = i - 1; m >= 0; m--)
                    dp[i,j] = Math.Min(dp[i,j],
                                 dp[m,j - 1] +
                               (a[i - 1] - a[m]) * 
                               (a[i - 1] - a[m]));
      
      
        return dp[n,k];
    }
      
    // Driver code
    public static void Main () 
    {
        int k = 2;
        int []a = {1, 5, 8, 10};
        int n = a.Length;
        Console.Write(minCost(a, n, k));
              
    }
}

473
Chapter 56. Clustering/Partitioning an array such that sum of square differences is
minimum

  
// This code is contributed by nitin mittal

Output:

20

Time Complexity: Having the three simple loops, the complexity of the above algorithm

is .
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/clusteringpartitioning-an-array-such-that-sum-of-square-differences-is-minimum/

474
Chapter 57

Coin game winner where every


player has three choices

Coin game winner where every player has three choices - GeeksforGeeks
A and B are playing a game. At the beginning there are n coins. Given two more numbers
x and y. In each move a player can pick x or y or l coins. A always starts the game. The
player who picks the last coin wins the game. For a given value of n, find whether A will
win the game or not if both are playing optimally.
Examples:

Input : n = 5, x = 3, y = 4
Output : A
There are 5 coins, every player can pick 1 or
3 or 4 coins on his/her turn.
A can win by picking 3 coins in first chance.
Now 2 coins will be left so B will pick one
coin and now A can win by picking the last coin.

Input : 2 3 4
Output : B

Let us take few example values of n for x = 3, y = 4.


n = 0 A can not pick any coin so he losses
n = 1 A can pick 1 coin and win the game
n = 2 A can pick only 1 coin. Now B will pick 1 coin and win the game
n = 3 4 A will win the game by picking 3 or 4 coins
n = 5, 6 A will choose 3 or 4 coins. Now B will have to choose from 2 coins so A will win.
We can observe that A wins game for n coins only when it loses for coins n-1, n-x and n-y.

C++

475
Chapter 57. Coin game winner where every player has three choices

// CPP program to find winner of game


// if player can pick 1, x, y coins
#include <bits/stdc++.h>
using namespace std;
  
// To find winner of game
bool findWinner(int x, int y, int n)
{
    // To store results
    int dp[n + 1];
  
    // Initial values
    dp[0] = false;
    dp[1] = true;
  
    // Computing other values.
    for (int i = 2; i <= n; i++) {
  
        // If A losses any of i-1 or i-x
        // or i-y game then he will
        // definitely win game i
        if (i - 1 >= 0 and !dp[i - 1])
            dp[i] = true;
        else if (i - x >= 0 and !dp[i - x])
            dp[i] = true;
        else if (i - y >= 0 and !dp[i - y])
            dp[i] = true;
  
        // Else A loses game.
        else
            dp[i] = false;
    }
  
    // If dp[n] is true then A will
    // game otherwise  he losses
    return dp[n];
}
  
// Driver program to test findWinner();
int main()
{
    int x = 3, y = 4, n = 5;
    if (findWinner(x, y, n))
        cout << 'A';
    else
        cout << 'B';
  
    return 0;

476
Chapter 57. Coin game winner where every player has three choices

Java

// Java program to find winner of game


// if player can pick 1, x, y coins
import java.util.Arrays;
  
public class GFG { 
      
    // To find winner of game
    static boolean findWinner(int x, int y, int n)
    {
        // To store results
        boolean[] dp = new boolean[n + 1];
       
        Arrays.fill(dp, false);
      
        // Initial values
        dp[0] = false;
        dp[1] = true;
       
        // Computing other values.
        for (int i = 2; i <= n; i++) {
       
            // If A losses any of i-1 or i-x
            // or i-y game then he will
            // definitely win game i
            if (i - 1 >= 0 && dp[i - 1] == false)
                dp[i] = true;
            else if (i - x >= 0 && dp[i - x] == false)
                dp[i] = true;
            else if (i - y >= 0 && dp[i - y] == false)
                dp[i] = true;
       
            // Else A loses game.
            else
                dp[i] = false;
        }
       
        // If dp[n] is true then A will
        // game otherwise  he losses
        return dp[n];
    }
       
    // Driver program to test findWinner();
    public static void main(String args[])
    {

477
Chapter 57. Coin game winner where every player has three choices

        int x = 3, y = 4, n = 5;
        if (findWinner(x, y, n) == true)
            System.out.println('A');
        else
            System.out.println('B');
    }
}
// This code is contributed by Sumit Ghosh

Python3

# Python3 program to find winner of game


# if player can pick 1, x, y coins
  
# To find winner of game
def findWinner(x, y, n):
      
    # To store results
    dp = [0 for i in range(n + 1)]
  
    # Initial values
    dp[0] = False
    dp[1] = True
  
    # Computing other values.
    for i in range(2, n + 1):
  
        # If A losses any of i-1 or i-x
        # or i-y game then he will
        # definitely win game i
        if (i - 1 >= 0 and not dp[i - 1]):
            dp[i] = True
        elif (i - x >= 0 and not dp[i - x]):
            dp[i] = True
        elif (i - y >= 0 and not dp[i - y]):
            dp[i] = True
  
        # Else A loses game.
        else:
            dp[i] = False
  
    # If dp[n] is true then A will
    # game otherwise he losses
    return dp[n]
  
# Driver Code
x = 3; y = 4; n = 5
if (findWinner(x, y, n)):

478
Chapter 57. Coin game winner where every player has three choices

    print('A')
else:
    print('B')
  
# This code is contributed by Azkia Anam

C#

// C# program to find winner of game


// if player can pick 1, x, y coins
using System;
  
public class GFG { 
      
    // To find winner of game
    static bool findWinner(int x, int y, int n)
    {
          
        // To store results
        bool[] dp = new bool[n + 1];
      
        for(int i = 0; i < n+1; i++)
            dp[i] =false;
      
        // Initial values
        dp[0] = false;
        dp[1] = true;
      
        // Computing other values.
        for (int i = 2; i <= n; i++)
        {
      
            // If A losses any of i-1 or i-x
            // or i-y game then he will
            // definitely win game i
            if (i - 1 >= 0 && dp[i - 1] == false)
                dp[i] = true;
            else if (i - x >= 0 && dp[i - x] == false)
                dp[i] = true;
            else if (i - y >= 0 && dp[i - y] == false)
                dp[i] = true;
      
            // Else A loses game.
            else
                dp[i] = false;
        }
      
        // If dp[n] is true then A will

479
Chapter 57. Coin game winner where every player has three choices

        // game otherwise he losses


        return dp[n];
    }
      
    // Driver program to test findWinner();
    public static void Main()
    {
        int x = 3, y = 4, n = 5;
          
        if (findWinner(x, y, n) == true)
            Console.WriteLine('A');
        else
            Console.WriteLine('B');
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to find winner of game
// if player can pick 1, x, y coins
  
// To find winner of game
function findWinner( $x, $y, $n)
{
      
    // To store results
    $dp= array();
  
    // Initial values
    $dp[0] = false;
    $dp[1] = true;
  
    // Computing other values.
    for ($i = 2; $i <= $n; $i++)
    {
  
        // If A losses any of i-1 or i-x
        // or i-y game then he will
        // definitely win game i
        if ($i - 1 >= 0 and !$dp[$i - 1])
            $dp[$i] = true;
        else if ($i - $x >= 0 and !$dp[$i - $x])
            $dp[$i] = true;
        else if ($i - $y >= 0 and !$dp[$i - $y])
            $dp[$i] = true;

480
Chapter 57. Coin game winner where every player has three choices

  
        // Else A loses game.
        else
            $dp[$i] = false;
    }
  
    // If dp[n] is true then A will
    // game otherwise he losses
    return $dp[$n];
}
  
// Driver program to test findWinner();
    $x = 3; $y = 4; $n = 5;
    if (findWinner($x, $y, $n))
        echo 'A';
    else
        echo 'B';
          
// This code is contributed by anuj_67.
?>

Output:

Improved By : vt_m

Source

https://www.geeksforgeeks.org/coin-game-winner-every-player-three-choices/

481
Chapter 58

Collect maximum coins before


hitting a dead end

Collect maximum coins before hitting a dead end - GeeksforGeeks


Given a character matrix where every cell has one of the following values.

'C' --> This cell has coin

'#' --> This cell is a blocking cell.


We can not go anywhere from this.

'E' --> This cell is empty. We don't get


a coin, but we can move from here.

Initial position is cell (0, 0) and initial direction is right.


Following are rules for movements across cells.
If face is Right, then we can move to below cells
Move one step ahead, i.e., cell (i, j+1) and direction remains right.
Move one step down and face left, i.e., cell (i+1, j) and direction becomes left.
If face is Left, then we can move to below cells

1. Move one step ahead, i.e., cell (i, j-1) and direction remains left.
2. Move one step down and face right, i.e., cell (i+1, j) and direction becomes right.

Final position can be anywhere and final direction can also be anything. The target is to
collect maximum coins.

482
Chapter 58. Collect maximum coins before hitting a dead end

Example:

We strongly recommend you to minimize your browser and try this yourself
first.
The above problem can be recursively defined as below:

maxCoins(i, j, d): Maximum number of coins that can be


collected if we begin at cell (i, j)
and direction d.
d can be either 0 (left) or 1 (right)

// If this is a blocking cell, return 0. isValid() checks


// if i and j are valid row and column indexes.
If (arr[i][j] == '#' or isValid(i, j) == false)
return 0

// Initialize result
If (arr[i][j] == 'C')
result = 1;
Else
result = 0;

If (d == 0) // Left direction
return result + max(maxCoins(i+1, j, 1), // Down
maxCoins(i, j-1, 0)); // Ahead in left

If (d == 1) // Right direction

483
Chapter 58. Collect maximum coins before hitting a dead end

return result + max(maxCoins(i+1, j, 1), // Down


maxCoins(i, j+1, 0)); // Ahead in right

Below is C++ implementation of above recursive algorithm.

// A Naive Recursive C++ program to find maximum number of coins


// that can be collected before hitting a dead end
#include<bits/stdc++.h>
using namespace std;
#define R 5
#define C 5
  
// to check whether current cell is out of the grid or not
bool isValid(int i, int j)
{
    return (i >=0 && i < R && j >=0 && j < C);
}
  
// dir = 0 for left, dir = 1 for facing right.  This function returns
// number of maximum coins that can be collected starting from (i, j).
int maxCoinsRec(char arr[R][C],  int i, int j, int dir)
{
    // If this is a invalid cell or if cell is a blocking cell
    if (isValid(i,j) == false || arr[i][j] == '#')
        return 0;
  
    // Check if this cell contains the coin 'C' or if its empty 'E'.
    int result = (arr[i][j] == 'C')? 1: 0;
  
    // Get the maximum of two cases when you are facing right in this cell
    if (dir == 1) // Direction is right
       return result + max(maxCoinsRec(arr, i+1, j, 0),     // Down
                             maxCoinsRec(arr, i, j+1, 1));  // Ahead in right
  
    // Direction is left
    // Get the maximum of two cases when you are facing left in this cell
     return  result + max(maxCoinsRec(arr, i+1, j, 1),    // Down
                           maxCoinsRec(arr, i, j-1, 0));  // Ahead in left
}
  
// Driver program to test above function
int main()
{
    char arr[R][C] = { {'E', 'C', 'C', 'C', 'C'},
                       {'C', '#', 'C', '#', 'E'},
                       {'#', 'C', 'C', '#', 'C'},
                       {'C', 'E', 'E', 'C', 'E'},
                       {'C', 'E', '#', 'C', 'E'}

484
Chapter 58. Collect maximum coins before hitting a dead end

                     };
  
   // As per the question initial cell is (0, 0) and direction is
    // right
    cout << "Maximum number of collected coins is "
         << maxCoinsRec(arr, 0, 0, 1);
  
    return 0;
}

Output:

Maximum number of collected coins is 8

The time complexity of above solution recursive is exponential. We can solve this problem
in Polynomial Time using Dynamic Programming. The idea is to use a 3 dimensional table
dp[R][C][k] where R is number of rows, C is number of columns and d is direction. Below
is Dynamic Programming based C++ implementation.

// A Dynamic Programming based C++ program to find maximum


// number of coins that can be collected before hitting a
// dead end
#include<bits/stdc++.h>
using namespace std;
#define R 5
#define C 5
  
// to check whether current cell is out of the grid or not
bool isValid(int i, int j)
{
    return (i >=0 && i < R && j >=0 && j < C);
}
  
// dir = 0 for left, dir = 1 for right.  This function returns
// number of maximum coins that can be collected starting from
// (i, j).
int maxCoinsUtil(char arr[R][C],  int i, int j, int dir,
                 int dp[R][C][2])
{
    // If this is a invalid cell or if cell is a blocking cell
    if (isValid(i,j) == false || arr[i][j] == '#')
        return 0;
  
    // If this subproblem is already solved than return the
    // already evaluated answer.
    if (dp[i][j][dir] != -1)
       return dp[i][j][dir];

485
Chapter 58. Collect maximum coins before hitting a dead end

  
    // Check if this cell contains the coin 'C' or if its 'E'.
    dp[i][j][dir] = (arr[i][j] == 'C')? 1: 0;
  
    // Get the maximum of two cases when you are facing right
    // in this cell
    if (dir == 1) // Direction is right
       dp[i][j][dir] += max(maxCoinsUtil(arr, i+1, j, 0, dp), // Down
                            maxCoinsUtil(arr, i, j+1, 1, dp)); // Ahead in rught
  
    // Get the maximum of two cases when you are facing left
    // in this cell
    if (dir == 0) // Direction is left
       dp[i][j][dir] += max(maxCoinsUtil(arr, i+1, j, 1, dp),  // Down
                            maxCoinsUtil(arr, i, j-1, 0, dp)); // Ahead in left
  
    // return the answer
    return dp[i][j][dir];
}
  
// This function mainly creates a lookup table and calls
// maxCoinsUtil()
int maxCoins(char arr[R][C])
{
    // Create lookup table and initialize all values as -1
    int dp[R][C][2];
    memset(dp, -1, sizeof dp);
  
    // As per the question initial cell is (0, 0) and direction
    // is right
    return maxCoinsUtil(arr, 0, 0, 1, dp);
}
  
// Driver program to test above function
int main()
{
    char arr[R][C] = { {'E', 'C', 'C', 'C', 'C'},
                       {'C', '#', 'C', '#', 'E'},
                       {'#', 'C', 'C', '#', 'C'},
                       {'C', 'E', 'E', 'C', 'E'},
                       {'C', 'E', '#', 'C', 'E'}
                     };
  
  
    cout << "Maximum number of collected coins is "
         << maxCoins(arr);
  
    return 0;

486
Chapter 58. Collect maximum coins before hitting a dead end

Output:

Maximum number of collected coins is 8

Time Complexity of above solution is O(R x C x d). Since d is 2, time complexity can be
written as O(R x C).
Thanks to Gaurav Ahirwar for suggesting above solution.

Source

https://www.geeksforgeeks.org/collect-maximum-coins-before-hitting-a-dead-end/

487
Chapter 59

Collect maximum points in a


grid using two traversals

Collect maximum points in a grid using two traversals - GeeksforGeeks


Given a matrix where every cell represents points. How to collect maximum points using
two traversals under following conditions?
Let the dimensions of given grid be R x C.
1) The first traversal starts from top left corner, i.e., (0, 0) and should reach left bottom
corner, i.e., (R-1, 0). The second traversal starts from top right corner, i.e., (0, C-1) and
should reach bottom right corner, i.e., (R-1, C-1)/
2) From a point (i, j), we can move to (i+1, j+1) or (i+1, j-1) or (i+1, j)
3) A traversal gets all points of a particular cell through which it passes. If one traversal
has already collected points of a cell, then the other traversal gets no points if goes through
that cell again.

Input :
int arr[R][C] = {{3, 6, 8, 2},
{5, 2, 4, 3},
{1, 1, 20, 10},
{1, 1, 20, 10},
{1, 1, 20, 10},
};

Output: 73

Explanation :

First traversal collects total points of value 3 + 2 + 20 + 1 + 1 = 27

488
Chapter 59. Collect maximum points in a grid using two traversals

Second traversal collects total points of value 2 + 4 + 10 + 20 + 10 = 46.


Total Points collected = 27 + 46 = 73.

We strongly recommend you to minimize your browser and try this yourself
first.
The idea is to do both traversals concurrently. We start first from (0, 0) and second traversal
from (0, C-1) simultaneously. The important thing to note is, at any particular step both
traversals will be in same row as in all possible three moves, row number is increased. Let
(x1, y1) and (x2, y2) denote current positions of first and second traversals respectively.
Thus at any time x1 will be equal to x2 as both of them move forward but variation is
possible along y. Since variation in y could occur in 3 ways no change (y), go left (y – 1),
go right (y + 1). So in total 9 combinations among y1, y2 are possible. The 9 cases as
mentioned below after base cases.

Both traversals always move forward along x


Base Cases:
// If destinations reached
if (x == R-1 && y1 == 0 && y2 == C-1)
maxPoints(arr, x, y1, y2) = arr[x][y1] + arr[x][y2];

// If any of the two locations is invalid (going out of grid)


if input is not valid
maxPoints(arr, x, y1, y2) = -INF (minus infinite)

// If both traversals are at same cell, then we count the value of cell
// only once.
If y1 and y2 are same
result = arr[x][y1]
Else
result = arr[x][y1] + arr[x][y2]

result += max { // Max of 9 cases


maxPoints(arr, x+1, y1+1, y2),
maxPoints(arr, x+1, y1+1, y2+1),
maxPoints(arr, x+1, y1+1, y2-1),
maxPoints(arr, x+1, y1-1, y2),
maxPoints(arr, x+1, y1-1, y2+1),
maxPoints(arr, x+1, y1-1, y2-1),
maxPoints(arr, x+1, y1, y2),
maxPoints(arr, x+1, y1, y2+1),
maxPoints(arr, x+1, y1, y2-1)
}

The above recursive solution has many subproblems that are solved again and again. There-
fore, we can use Dynamic Programming to solve the above problem more efficiently. Below
is memoization (Memoization is alternative to table based iterative solution in Dynamic Pro-

489
Chapter 59. Collect maximum points in a grid using two traversals

gramming) based implementation. In below implementation, we use a memoization table


‘mem’ to keep track of already solved problems.

// A Memoization based program to find maximum collection


// using two traversals of a grid
#include<bits/stdc++.h>
using namespace std;
#define R 5
#define C 4
  
// checks whether a given input is valid or not
bool isValid(int x, int y1, int y2)
{
    return (x >= 0 && x < R && y1 >=0 &&
            y1 < C && y2 >=0 && y2 < C);
}
  
// Driver function to collect max value
int getMaxUtil(int arr[R][C], int mem[R][C][C], int x, int y1, int y2)
{
    /*---------- BASE CASES -----------*/
    // if P1 or P2 is at an invalid cell
    if (!isValid(x, y1, y2)) return INT_MIN;
  
    // if both traversals reach their destinations
    if (x == R-1 && y1 == 0 && y2 == C-1)
       return (y1 == y2)? arr[x][y1]: arr[x][y1] + arr[x][y2];
  
    // If both traversals are at last row but not at their destination
    if (x == R-1) return INT_MIN;
  
    // If subproblem is already solved
    if (mem[x][y1][y2] != -1) return mem[x][y1][y2];
  
    // Initialize answer for this subproblem
    int ans = INT_MIN;
  
    // this variable is used to store gain of current cell(s)
    int temp = (y1 == y2)? arr[x][y1]: arr[x][y1] + arr[x][y2];
  
    /* Recur for all possible cases, then store and return the
       one with max value */
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1, y2-1));
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1, y2+1));
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1, y2));
  
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1-1, y2));
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1-1, y2-1));

490
Chapter 59. Collect maximum points in a grid using two traversals

    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1-1, y2+1));


  
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1+1, y2));
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1+1, y2-1));
    ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1+1, y2+1));
  
    return (mem[x][y1][y2] = ans);
}
  
// This is mainly a wrapper over recursive function getMaxUtil().
// This function creates a table for memoization and calls
// getMaxUtil()
int geMaxCollection(int arr[R][C])
{
    // Create a memoization table and initialize all entries as -1
    int mem[R][C][C];
    memset(mem, -1, sizeof(mem));
  
    // Calculation maximum value using memoization based function
    // getMaxUtil()
    return getMaxUtil(arr, mem, 0, 0, C-1);
}
  
// Driver program to test above functions
int main()
{
    int arr[R][C] = {{3, 6, 8, 2},
                     {5, 2, 4, 3},
                     {1, 1, 20, 10},
                     {1, 1, 20, 10},
                     {1, 1, 20, 10},
                    };
    cout << "Maximum collection is " << geMaxCollection(arr);
    return 0;
}

Output:

Maximum collection is 73

Thanks to Gaurav Ahirwar for suggesting above problem and solution.

Source

https://www.geeksforgeeks.org/collect-maximum-points-in-a-grid-using-two-traversals/

491
Chapter 60

Compute nCr % p | Set 1


(Introduction and Dynamic
Programming Solution)

Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution) - Geeks-


forGeeks
Given three numbers n, r and p, compute value of n Cr mod p.

Example:

Input: n = 10, r = 2, p = 13
Output: 6
Explanation: 10C2 is 45 and 45 % 13 is 6.

A Simple Solution is to first compute n Cr , then compute n Cr % p. This solution works


fine when the value of n Cr is small.
What if the value of n Cr is large?
The value of n Cr %p is generally needed for large values of n when n Cr cannot fit in a variable,
and causes overflow. So computing n Cr and then using modular operator is not a good idea
as there will be overflow even for slightly larger values of n and r. For example the methods
discussed here and here cause overflow for n = 50 and r = 40.
The idea is to compute n Cr using below formula

C(n, r) = C(n-1, r-1) + C(n-1, r)


C(n, 0) = C(n, n) = 1

492
Chapter 60. Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution)

Working of Above formula and Pascal Triangle:


Let us see how above formula works for C(4,3)
1==========>> n = 0, C(0,0) = 1
1–1========>> n = 1, C(1,0) = 1, C(1,1) = 1
1–2–1======>> n = 2, C(2,0) = 1, C(2,1) = 2, C(2,2) = 1
1–3–3–1====>> n = 3, C(3,0) = 1, C(3,1) = 3, C(3,2) = 3, C(3,3)=1
1–4–6–4–1==>> n = 4, C(4,0) = 1, C(4,1) = 4, C(4,2) = 6, C(4,3)=4, C(4,4)=1
So here every loop on i, builds i’th row of pascal triangle, using (i-1)th row
Extension of above formula for modular arithmetic:
We can use distributive property of modulor operator to find nCr % p using above formula.

C(n, r)%p = [ C(n-1, r-1)%p + C(n-1, r)%p ] % p


C(n, 0) = C(n, n) = 1

The above formula can implemented using Dynamic Programming using a 2D array.
The 2D array based dynamic programming solution can be further optimized by constructing
one row at a time. See Space optimized version in below post for details.
Binomial Coefficient using Dynamic Programming
Below is implementation based on the space optimized version discussed in above post.

C++

// A Dynamic Programming based solution to compute nCr % p


#include<bits/stdc++.h>
using namespace std;
  
// Returns nCr % p
int nCrModp(int n, int r, int p)
{
    // The array C is going to store last row of
    // pascal triangle at the end. And last entry
    // of last row is nCr
    int C[r+1];
    memset(C, 0, sizeof(C));
  
    C[0] = 1; // Top row of Pascal Triangle
  
    // One by constructs remaining rows of Pascal
    // Triangle from top to bottom
    for (int i = 1; i <= n; i++)
    {
        // Fill entries of current row using previous
        // row values

493
Chapter 60. Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution)

        for (int j = min(i, r); j > 0; j--)


  
            // nCj = (n-1)Cj + (n-1)C(j-1);
            C[j] = (C[j] + C[j-1])%p;
    }
    return C[r];
}
  
// Driver program
int main()
{
    int n = 10, r = 2, p = 13;
    cout << "Value of nCr % p is " << nCrModp(n, r, p);
    return 0;
}

JAVA

// A Dynamic Programming based


// solution to compute nCr % p
import java.io.*;
import java.util.*;
import java.math.*;
  
class GFG {
      
    // Returns nCr % p
    static int nCrModp(int n, int r, int p)
    {
        // The array C is going to store last 
        // row of pascal triangle at the end.
        // And last entry of last row is nCr
        int C[]=new int[r+1];
        Arrays.fill(C,0);
      
        C[0] = 1; // Top row of Pascal Triangle
      
        // One by constructs remaining rows of Pascal
        // Triangle from top to bottom
        for (int i = 1; i <= n; i++)
        {
            // Fill entries of current row using previous
            // row values
            for (int j = Math.min(i, r); j > 0; j--)
      
                // nCj = (n-1)Cj + (n-1)C(j-1);
                C[j] = (C[j] + C[j-1])%p;
        }

494
Chapter 60. Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution)

        return C[r];
    }
      
    // Driver program
    public static void main(String args[])
    {
        int n = 10, r = 2, p = 13;
        System.out.println("Value of nCr % p is "
                           + nCrModp(n, r, p));
          
    }
}
  
  
// This code is contributed by Nikita Tiwari.

Python3

# A Dynamic Programming based solution to compute nCr % p


  
# Returns nCr % p
def nCrModp(n, r, p):
  
    # The array C is going to store last row of
    # pascal triangle at the end. And last entry
    # of last row is nCr.
    C = [0 for i in range(r+1)]
  
    C[0] = 1 # Top row of Pascal Triangle
  
    # One by constructs remaining rows of Pascal
    # Triangle from top to bottom
    for i in range(1, n+1):
  
        # Fill entries of current row 
        # using previous row values
        for j in range(min(i, r), 0, -1):
  
            # nCj = (n - 1)Cj + (n - 1)C(j - 1)
            C[j] = (C[j] + C[j-1]) % p
  
    return C[r]
  
# Driver Program
n = 10
r = 2
p = 13
print('Value of nCr % p is', nCrModp(n, r, p))

495
Chapter 60. Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution)

  
# This code is contributed by Soumen Ghosh

C#

// A Dynamic Programming based


// solution to compute nCr % p
using System;
  
class GFG {
      
    // Returns nCr % p
    static int nCrModp(int n, int r, int p)
    {
          
        // The array C is going to store last 
        // row of pascal triangle at the end.
        // And last entry of last row is nCr
        int []C = new int[r + 1];
          
        for(int i = 0; i < r + 1; i++)
            C[i] = 0;
      
      
        C[0] = 1; // Top row of Pascal Triangle
      
        // One by constructs remaining rows
        // of Pascal Triangle from top to bottom
        for (int i = 1; i <= n; i++)
        {
              
            // Fill entries of current row using
            // previous row values
            for (int j = Math.Min(i, r); j > 0; j--)
      
                // nCj = (n-1)Cj + (n-1)C(j-1);
                C[j] = (C[j] + C[j-1]) % p;
        }
          
        return C[r];
    }
      
    // Driver program
    public static void Main()
    {
        int n = 10, r = 2, p = 13;
          
        Console.Write("Value of nCr % p is "

496
Chapter 60. Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution)

                            + nCrModp(n, r, p));


          
    }
}
  
  
// This code is contributed by nitin mittal.

[
PHP

<?php
// A Dynamic Programming based
// solution to compute nCr % p
      
// Returns nCr % p
function nCrModp($n, $r, $p)
{
  
// The array C is going 
// to store last row of
// pascal triangle at 
// the end. And last entry
// of last row is nCr
$C = array();
  
for( $i = 0; $i < $r + 1; $i++)
    $C[$i] = 0;
  
// Top row of Pascal
// Triangle
$C[0] = 1; 
  
// One by constructs remaining 
// rows of Pascal Triangle from 
// top to bottom
for ($i = 1; $i <= $n; $i++)
{
      
    // Fill entries of current 
    // row using previous row values
    for ($j = Min($i, $r); $j > 0; $j--)
  
        // nCj = (n-1)Cj + (n-1)C(j-1);
        $C[$j] = ($C[$j] + 
                  $C[$j - 1]) % $p;
}

497
Chapter 60. Compute nCr % p | Set 1 (Introduction and Dynamic Programming Solution)

  
return $C[$r];
}
  
// Driver Code
$n = 10; $r = 2;$p = 13;
  
echo "Value of nCr % p is " ,
         nCrModp($n, $r, $p);
  
// This code is contributed
// by anuj_67.
?>

Output:

Value of nCr % p is 6

Time complexity of above solution is O(n*r) and it requires O(n) space. There are more
and better solutions to above problem.
Compute nCr % p | Set 2 (Lucas Theorem)
Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/compute-ncr-p-set-1-introduction-and-dynamic-programming-solution/

498
Chapter 61

Compute sum of digits in all


numbers from 1 to n

Compute sum of digits in all numbers from 1 to n - GeeksforGeeks


Given a number x, find sum of digits in all numbers from 1 to n.
Examples:

Input: n = 5
Output: Sum of digits in numbers from 1 to 5 = 15

Input: n = 12
Output: Sum of digits in numbers from 1 to 12 = 51

Input: n = 328
Output: Sum of digits in numbers from 1 to 328 = 3241

Naive Solution:
A naive solution is to go through every number x from 1 to n, and compute sum in x by
traversing all digits of x. Below is the implementation of this idea.

C++

// A Simple C++ program to compute sum of digits in numbers from 1 to n


#include<bits/stdc++.h>
using namespace std;
  
int sumOfDigits(int );
  
// Returns sum of all digits in numbers from 1 to n
int sumOfDigitsFrom1ToN(int n)

499
Chapter 61. Compute sum of digits in all numbers from 1 to n

{
    int result = 0; // initialize result
  
    // One by one compute sum of digits in every number from
    // 1 to n
    for (int x = 1; x <= n; x++)
        result += sumOfDigits(x);
  
    return result;
}
  
// A utility function to compute sum of digits in a
// given number x
int sumOfDigits(int x)
{
    int sum = 0;
    while (x != 0)
    {
        sum += x %10;
        x   = x /10;
    }
    return sum;
}
  
// Driver Program
int main()
{
    int n = 328;
    cout << "Sum of digits in numbers from 1 to " << n << " is "
         << sumOfDigitsFrom1ToN(n);
    return 0;
}

Java

// A Simple JAVA program to compute sum of


// digits in numbers from 1 to n
import java.io.*;
  
class GFG {
      
    // Returns sum of all digits in numbers 
    // from 1 to n
    static int sumOfDigitsFrom1ToN(int n)
    {
        int result = 0; // initialize result
       
        // One by one compute sum of digits

500
Chapter 61. Compute sum of digits in all numbers from 1 to n

        // in every number from 1 to n


        for (int x = 1; x <= n; x++)
            result += sumOfDigits(x);
       
        return result;
    }
       
    // A utility function to compute sum 
    // of digits in a given number x
    static int sumOfDigits(int x)
    {
        int sum = 0;
        while (x != 0)
        {
            sum += x % 10;
            x   = x / 10;
        }
        return sum;
    }
       
    // Driver Program
    public static void main(String args[])
    {
        int n = 328;
        System.out.println("Sum of digits in numbers"
                          +" from 1 to " + n + " is "
                          + sumOfDigitsFrom1ToN(n));
    }
}
  
/*This code is contributed by Nikita Tiwari.*/

Python3

# A Simple Python program to compute sum


# of digits in numbers from 1 to n
  
# Returns sum of all digits in numbers 
# from 1 to n
def sumOfDigitsFrom1ToN(n) :
  
    result = 0   # initialize result
   
    # One by one compute sum of digits 
    # in every number from 1 to n
    for x in range(1, n+1) :
        result = result + sumOfDigits(x)
   

501
Chapter 61. Compute sum of digits in all numbers from 1 to n

    return result
  
# A utility function to compute sum of 
# digits in a given number x
def sumOfDigits(x) :
    sum = 0
    while (x != 0) :
        sum = sum + x % 10
        x   = x // 10
      
    return sum
  
  
# Driver Program
n = 328
print("Sum of digits in numbers from 1 to", n, "is", sumOfDigitsFrom1ToN(n))
  
  
# This code is contributed by Nikita Tiwari.

C#

// A Simple C# program to compute sum of


// digits in numbers from 1 to n
  
using System;
  
public class GFG {
      
    // Returns sum of all digits in numbers 
    // from 1 to n
    static int sumOfDigitsFrom1ToN(int n)
    {
          
        // initialize result
        int result = 0;
      
        // One by one compute sum of digits
        // in every number from 1 to n
        for (int x = 1; x <= n; x++)
            result += sumOfDigits(x);
      
        return result;
    }
      
    // A utility function to compute sum 
    // of digits in a given number x
    static int sumOfDigits(int x)

502
Chapter 61. Compute sum of digits in all numbers from 1 to n

    {
        int sum = 0;
          
        while (x != 0)
        {
            sum += x % 10;
            x = x / 10;
        }
          
        return sum;
    }
      
    // Driver Program
    public static void Main()
    {
        int n = 328;
          
        Console.WriteLine("Sum of digits"
               + " in numbers from 1 to "
                             + n + " is "
                + sumOfDigitsFrom1ToN(n));
    }
}
  
// This code is contributed by shiv_bhakt.

PHP

<?php
  
// A Simple php program to compute sum 
//of digits in numbers from 1 to n
  
// Returns sum of all digits in
// numbers from 1 to n
function sumOfDigitsFrom1ToN($n)
{
    $result = 0; // initialize result
  
    // One by one compute sum of digits
    // in every number from 1 to n
    for ($x = 1; $x <= $n; $x++)
        $result += sumOfDigits($x);
  
    return $result;
}
  
// A utility function to compute sum

503
Chapter 61. Compute sum of digits in all numbers from 1 to n

// of digits in a given number x


function sumOfDigits($x)
{
    $sum = 0;
    while ($x != 0)
    {
        $sum += $x %10;
        $x = $x /10;
    }
    return $sum;
}
  
// Driver Program
  
    $n = 328;
    echo "Sum of digits in numbers from" 
               . " 1 to " . $n . " is " 
               . sumOfDigitsFrom1ToN($n);
      
// This code is contributed by ajit
?>

Output

Sum of digits in numbers from 1 to 328 is 3241

Efficient Solution:
Above is a naive solution. We can do it more efficiently by finding a pattern.
Let us take few examples.

sum(9) = 1 + 2 + 3 + 4 ........... + 9
= 9*10/2
= 45

sum(99) = 45 + (10 + 45) + (20 + 45) + ..... (90 + 45)


= 45*10 + (10 + 20 + 30 ... 90)
= 45*10 + 10(1 + 2 + ... 9)
= 45*10 + 45*10
= sum(9)*10 + 45*10

sum(999) = sum(99)*10 + 45*100

In general, we can compute sum(10d – 1) using below formula

504
Chapter 61. Compute sum of digits in all numbers from 1 to n

sum(10d - 1) = sum(10d-1 - 1) * 10 + 45*(10d-1)

In below implementation, the above formula is implemented using dynamic programming


as there are overlapping subproblems.
The above formula is one core step of the idea. Below is complete algorithm
Algorithm: sum(n)

1) Find number of digits minus one in n. Let this value be 'd'.


For 328, d is 2.

2) Compute some of digits in numbers from 1 to 10d - 1.


Let this sum be w. For 328, we compute sum of digits from 1 to
99 using above formula.

3) Find Most significant digit (msd) in n. For 328, msd is 3.

4) Overall sum is sum of following terms

a) Sum of digits in 1 to "msd * 10d - 1". For 328, sum of


digits in numbers from 1 to 299.
For 328, we compute 3*sum(99) + (1 + 2)*100. Note that sum of
sum(299) is sum(99) + sum of digits from 100 to 199 + sum of digits
from 200 to 299.
Sum of 100 to 199 is sum(99) + 1*100 and sum of 299 is sum(99) + 2*100.
In general, this sum can be computed as w*msd + (msd*(msd-1)/2)*10d

b) Sum of digits in msd * 10d to n. For 328, sum of digits in


300 to 328.
For 328, this sum is computed as 3*29 + recursive call "sum(28)"
In general, this sum can be computed as msd * (n % (msd*10d) + 1)
+ sum(n % (10d))

Below is the implementation of above aglorithm.

C++

// C++ program to compute sum of digits in numbers from 1 to n


#include<bits/stdc++.h>
using namespace std;
  
// Function to computer sum of digits in numbers from 1 to n
// Comments use example of 328 to explain the code
int sumOfDigitsFrom1ToN(int n)
{

505
Chapter 61. Compute sum of digits in all numbers from 1 to n

    // base case: if n<10 return sum of


    // first n natural numbers
    if (n<10)
      return n*(n+1)/2;
  
    // d = number of digits minus one in n. For 328, d is 2
    int d = log10(n);
  
    // computing sum of digits from 1 to 10^d-1,
    // d=1 a[0]=0;
    // d=2 a[1]=sum of digit from 1 to 9 = 45
    // d=3 a[2]=sum of digit from 1 to 99 = a[1]*10 + 45*10^1 = 900
    // d=4 a[3]=sum of digit from 1 to 999 = a[2]*10 + 45*10^2 = 13500
    int *a = new int[d+1];
    a[0] = 0, a[1] = 45;
    for (int i=2; i<=d; i++)
        a[i] = a[i-1]*10 + 45*ceil(pow(10,i-1));
  
    // computing 10^d
    int p = ceil(pow(10, d));
  
    // Most significant digit (msd) of n,
    // For 328, msd is 3 which can be obtained using 328/100
    int msd = n/p;
  
    // EXPLANATION FOR FIRST and SECOND TERMS IN BELOW LINE OF CODE
    // First two terms compute sum of digits from 1 to 299
    // (sum of digits in range 1-99 stored in a[d]) +
    // (sum of digits in range 100-199, can be calculated as 1*100 + a[d]
    // (sum of digits in range 200-299, can be calculated as 2*100 + a[d]
    //  The above sum can be written as 3*a[d] + (1+2)*100
  
    // EXPLANATION FOR THIRD AND FOURTH TERMS IN BELOW LINE OF CODE
    // The last two terms compute sum of digits in number from 300 to 328
    // The third term adds 3*29 to sum as digit 3 occurs in all numbers 
    //                from 300 to 328
    // The fourth term recursively calls for 28
    return msd*a[d] + (msd*(msd-1)/2)*p +  
           msd*(1+n%p) + sumOfDigitsFrom1ToN(n%p);
}
  
// Driver Program
int main()
{
    int n = 328;
    cout << "Sum of digits in numbers from 1 to " << n << " is "
         << sumOfDigitsFrom1ToN(n);
    return 0;

506
Chapter 61. Compute sum of digits in all numbers from 1 to n

Java

// JAVA program to compute sum of digits 


// in numbers from 1 to n
import java.io.*;
import java.math.*;
  
class GFG{
      
    // Function to computer sum of digits in 
    // numbers from 1 to n. Comments use 
    // example of 328 to explain the code
    static int sumOfDigitsFrom1ToN(int n)
    {
        // base case: if n<10 return sum of
        // first n natural numbers
        if (n < 10)
          return (n * (n + 1) / 2);
       
        // d = number of digits minus one in
        // n. For 328, d is 2
        int d = (int)(Math.log10(n));
       
        // computing sum of digits from 1 to 10^d-1,
        // d=1 a[0]=0;
        // d=2 a[1]=sum of digit from 1 to 9 = 45
        // d=3 a[2]=sum of digit from 1 to 99 = 
        // a[1]*10 + 45*10^1 = 900
        // d=4 a[3]=sum of digit from 1 to 999 =
        // a[2]*10 + 45*10^2 = 13500
        int a[] = new int[d+1];
        a[0] = 0; a[1] = 45;
        for (int i = 2; i <= d; i++)
            a[i] = a[i-1] * 10 + 45 * 
                 (int)(Math.ceil(Math.pow(10, i-1)));
       
        // computing 10^d
        int p = (int)(Math.ceil(Math.pow(10, d)));
       
        // Most significant digit (msd) of n,
        // For 328, msd is 3 which can be obtained
        // using 328/100
        int msd = n / p;
       
        // EXPLANATION FOR FIRST and SECOND TERMS IN
        // BELOW LINE OF CODE

507
Chapter 61. Compute sum of digits in all numbers from 1 to n

        // First two terms compute sum of digits from


        // 1 to 299 
        // (sum of digits in range 1-99 stored in a[d]) +
        // (sum of digits in range 100-199, can be 
        // calculated as 1*100 + a[d]
        // (sum of digits in range 200-299, can be 
        // calculated as 2*100 + a[d]
        //  The above sum can be written as 3*a[d] + 
        // (1+2)*100
       
        // EXPLANATION FOR THIRD AND FOURTH TERMS IN 
        // BELOW LINE OF CODE
        // The last two terms compute sum of digits in 
        // number from 300 to 328. The third term adds
        // 3*29 to sum as digit 3 occurs in all numbers 
        // from 300 to 328. The fourth term recursively
        // calls for 28
        return (msd * a[d] + (msd * (msd - 1) / 2) * p +  
              msd * (1 + n % p) + sumOfDigitsFrom1ToN(n % p));
    }
       
    // Driver Program
    public static void main(String args[])
    {
        int n = 328;
        System.out.println("Sum of digits in numbers " +
                          "from 1 to " +n + " is " + 
                          sumOfDigitsFrom1ToN(n));
    }
}
  
/*This code is contributed by Nikita Tiwari.*/

Python3

# PYTHON 3 program to compute sum of digits


# in numbers from 1 to n
import math
  
# Function to computer sum of digits in 
# numbers from 1 to n. Comments use example
# of 328 to explain the code
def sumOfDigitsFrom1ToN( n) :
    
    # base case: if n<10 return sum of
    # first n natural numbers
    if (n<10) :
        return (n*(n+1)/2)

508
Chapter 61. Compute sum of digits in all numbers from 1 to n

   
    # d = number of digits minus one in n.
    # For 328, d is 2
    d = (int)(math.log10(n))
   
    """computing sum of digits from 1 to 10^d-1,
    d=1 a[0]=0;
    d=2 a[1]=sum of digit from 1 to 9 = 45
    d=3 a[2]=sum of digit from 1 to 99 = a[1]*10 
    + 45*10^1 = 900
    d=4 a[3]=sum of digit from 1 to 999 = a[2]*10 
    + 45*10^2 = 13500"""
    a = [0] * (d + 1)
    a[0] = 0
    a[1] = 45
    for i in range(2, d+1) :
        a[i] = a[i-1] * 10 + 45 * (int)(math.ceil(math.pow(10,i-1)))
   
    # computing 10^d
    p = (int)(math.ceil(math.pow(10, d)))
   
    # Most significant digit (msd) of n,
    # For 328, msd is 3 which can be obtained
    # using 328/100
    msd = n//p
   
    """EXPLANATION FOR FIRST and SECOND TERMS IN
    BELOW LINE OF CODE
    First two terms compute sum of digits from 1 to 299
    (sum of digits in range 1-99 stored in a[d]) +
    (sum of digits in range 100-199, can be calculated 
    as 1*100 + a[d]. (sum of digits in range 200-299,
    can be calculated as 2*100 + a[d]
    The above sum can be written as 3*a[d] + (1+2)*100
   
    EXPLANATION FOR THIRD AND FOURTH TERMS IN BELOW
    LINE OF CODE
    The last two terms compute sum of digits in number
    from 300 to 328. The third term adds 3*29 to sum
    as digit 3 occurs in all numbers from 300 to 328.
    The fourth term recursively calls for 28"""
    return (int)(msd * a[d] + (msd*(msd-1) // 2) * p +  
           msd * (1 + n % p) + sumOfDigitsFrom1ToN(n % p))
  
# Driver Program
n = 328
print("Sum of digits in numbers from 1 to", 
      n ,"is",sumOfDigitsFrom1ToN(n))

509
Chapter 61. Compute sum of digits in all numbers from 1 to n

  
  
# This code is contributed by Nikita Tiwari.

C#

// C# program to compute sum of digits 


// in numbers from 1 to n
  
using System;
  
public class GFG {
      
    // Function to computer sum of digits in 
    // numbers from 1 to n. Comments use 
    // example of 328 to explain the code
    static int sumOfDigitsFrom1ToN(int n)
    {
          
        // base case: if n<10 return sum of
        // first n natural numbers
        if (n < 10)
            return (n * (n + 1) / 2);
      
        // d = number of digits minus one in
        // n. For 328, d is 2
        int d = (int)(Math.Log(n) / Math.Log(10));
      
        // computing sum of digits from 1 to 10^d-1,
        // d=1 a[0]=0;
        // d=2 a[1]=sum of digit from 1 to 9 = 45
        // d=3 a[2]=sum of digit from 1 to 99 = 
        // a[1]*10 + 45*10^1 = 900
        // d=4 a[3]=sum of digit from 1 to 999 =
        // a[2]*10 + 45*10^2 = 13500
        int[] a = new int[d+1];
        a[0] = 0; a[1] = 45;
          
        for (int i = 2; i <= d; i++)
            a[i] = a[i-1] * 10 + 45 * 
                (int)(Math.Ceiling(Math.Pow(10, i-1)));
      
        // computing 10^d
        int p = (int)(Math.Ceiling(Math.Pow(10, d)));
      
        // Most significant digit (msd) of n,
        // For 328, msd is 3 which can be obtained
        // using 328/100

510
Chapter 61. Compute sum of digits in all numbers from 1 to n

        int msd = n / p;
      
        // EXPLANATION FOR FIRST and SECOND TERMS IN
        // BELOW LINE OF CODE
        // First two terms compute sum of digits from
        // 1 to 299 
        // (sum of digits in range 1-99 stored in a[d]) +
        // (sum of digits in range 100-199, can be 
        // calculated as 1*100 + a[d]
        // (sum of digits in range 200-299, can be 
        // calculated as 2*100 + a[d]
        // The above sum can be written as 3*a[d] + 
        // (1+2)*100
      
        // EXPLANATION FOR THIRD AND FOURTH TERMS IN 
        // BELOW LINE OF CODE
        // The last two terms compute sum of digits in 
        // number from 300 to 328. The third term adds
        // 3*29 to sum as digit 3 occurs in all numbers 
        // from 300 to 328. The fourth term recursively
        // calls for 28
        return (msd * a[d] + (msd * (msd - 1) / 2) * p + 
            msd * (1 + n % p) + sumOfDigitsFrom1ToN(n % p));
    }
      
    // Driver Program
    public static void Main()
    {
        int n = 328;
        Console.WriteLine("Sum of digits in numbers " +
                             "from 1 to " +n + " is " + 
                               sumOfDigitsFrom1ToN(n));
    }
}
  
// This code is contributed by shiv_bhakt.

Output

Sum of digits in numbers from 1 to 328 is 3241

The efficient algorithm has one more advantage that we need to compute the array ‘a[]’ only
once even when we are given multiple inputs.
This article is computed by Shubham Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : shiv_bhakt, jit_t

511
Chapter 61. Compute sum of digits in all numbers from 1 to n

Source

https://www.geeksforgeeks.org/count-sum-of-digits-in-numbers-from-1-to-n/

512
Chapter 62

Construction of Longest
Increasing Subsequence using
Dynamic Programming

Construction of Longest Increasing Subsequence using Dynamic Programming - Geeks-


forGeeks
The longest Increasing Subsequence (LIS) problem is to find the length of the longest subse-
quence of a given sequence such that all elements of the subsequence are sorted in increasing
order.
Examples:

Input: [10, 22, 9, 33, 21, 50, 41, 60, 80]


Output: [10, 22, 33, 50, 60, 80]
OR [10 22 33 41 60 80] or any other LIS of same length.

In previous post, we have discussed about Longest Increasing Subsequence problem. How-
ever, the post only covered code related to querying size of LIS, but not the construction
of LIS. In this post, we will discuss how to print LIS using similar DP solution discussed
earlier.
Let arr[0..n-1] be the input array. We define vector L such that L[i] is itself is a vector that
stores LIS of arr that ends with arr[i]. For example, for array [3, 2, 6, 4, 5, 1],

L[0]: 3
L[1]: 2
L[2]: 2 6
L[3]: 2 4
L[4]: 2 4 5
L[5]: 1

513
Chapter 62. Construction of Longest Increasing Subsequence using Dynamic Programming

Therefore for an index i, L[i] can be recursively written as –

L[0] = {arr[O]}
L[i] = {Max(L[j])} + arr[i]
where j < i and arr[j] < arr[i] and if there is no such j then L[i] = arr[i]

Below is C++ implementation of above idea –

/* Dynamic Programming solution to construct Longest


   Increasing Subsequence */
#include <iostream>
#include <vector>
using namespace std;
  
// Utility function to print LIS
void printLIS(vector<int>& arr)
{
    for (int x : arr)
        cout << x << " ";
    cout << endl;
}
  
// Function to construct and print Longest Increasing
// Subsequence
void constructPrintLIS(int arr[], int n)
{
    // L[i] - The longest increasing sub-sequence 
    // ends with arr[i]
    vector<vector<int> > L(n);
  
    // L[0] is equal to arr[0]
    L[0].push_back(arr[0]);
  
    // start from index 1
    for (int i = 1; i < n; i++)
    {
        // do for every j less than i
        for (int j = 0; j < i; j++)
        {
            /* L[i] = {Max(L[j])} + arr[i]
            where j < i and arr[j] < arr[i] */
            if ((arr[i] > arr[j]) &&
                    (L[i].size() < L[j].size() + 1))
                L[i] = L[j];
        }
  

514
Chapter 62. Construction of Longest Increasing Subsequence using Dynamic Programming

        // L[i] ends with arr[i]


        L[i].push_back(arr[i]);
    }
  
    // L[i] now stores increasing sub-sequence of
    // arr[0..i] that ends with arr[i]
    vector<int> max = L[0];
  
    // LIS will be max of all increasing sub-
    // sequences of arr
    for (vector<int> x : L)
        if (x.size() > max.size())
            max = x;
  
    // max will contain LIS
    printLIS(max);
}
  
// Driver function
int main()
{
    int arr[] = { 3, 2, 6, 4, 5, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // construct and print LIS of arr
    constructPrintLIS(arr, n);
  
    return 0;
}

Output:

2 4 5

Note that the time complexity of the above Dynamic Programming (DP) solution is O(n^2)
and there is a O(n Log n) non-DP solution for the LIS problem. See below post for O(n
Log n) solution.
Construction of Longest Monotonically Increasing Subsequence (N log N)

Source

https://www.geeksforgeeks.org/construction-of-longest-increasing-subsequence-using-dynamic-programming/

515
Chapter 63

Convert to Strictly increasing


array with minimum changes

Convert to Strictly increasing array with minimum changes - GeeksforGeeks


Given an array of n integers. Write a program to find minimum number of changes in array
so that array is strictly increasing. In strictly increasing array A[i] < A[i+1] for 0 <= i < n
Examples:

Input : arr[] = { 1, 2, 6, 5, 4}
Output : 2
We can a[2] to any value between 2 and 5
and a[4] to any value greater then 5.

Input : arr[] = { 1, 2, 3, 5, 7, 11 }
Output : 0
Array is already strictly increasing.

The problem is variation of Longest Increasing Subsequence. The numbers which are already
a part of LIS need not to be changed. So minimum elements to change is difference of size
of array and number of elements in LIS.
C++

// CPP program to find min elements to


// change so array is strictly increasing
#include <bits/stdc++.h>
using namespace std;
  
// To find min elements to remove from array
// to make it strictly increasing

516
Chapter 63. Convert to Strictly increasing array with minimum changes

int minRemove(int arr[], int n)


{
    int LCS[n], len = 0;
  
    // Mark all elements of LCS as 1
    for (int i = 0; i < n; i++)
        LCS[i] = 1;
  
    // Find LCS of array
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < i; j++) {
            if (arr[i] > arr[j])
                LCS[i] = max(LCS[i], LCS[j] + 1);
        }
        len = max(len, LCS[i]);
    }
  
    // Return min changes for array
    // to strictly increasing
    return n - len;
}
  
// Driver program to test minRemove()
int main()
{
    int arr[] = { 1, 2, 6, 5, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << minRemove(arr, n);
  
    return 0;
}

Java

// Java program to find min elements to


// change so array is strictly increasing
public class Main {
  
    // To find min elements to remove from array
    // to make it strictly increasing
    static int minRemove(int arr[], int n)
    {
        int LCS[] = new int[n];
        int len = 0;
  
        // Mark all elements of LCS as 1
        for (int i = 0; i < n; i++)

517
Chapter 63. Convert to Strictly increasing array with minimum changes

            LCS[i] = 1;
  
        // Find LCS of array
        for (int i = 1; i < n; i++) {
            for (int j = 0; j < i; j++) {
                if (arr[i] > arr[j])
                    LCS[i] = Math.max(LCS[i], 
                                 LCS[j] + 1);
            }
            len = Math.max(len, LCS[i]);
        }
  
        // Return min changes for array
        // to strictly increasing
        return n - len;
    }
  
    // Driver program to test minRemove()
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 6, 5, 4 };
        int n = arr.length;
  
        System.out.println(minRemove(arr, n));
    }
}

Python3

# Python3 program to find min elements to


# change so array is strictly increasing
  
# Find min elements to remove from array
# to make it strictly increasing
def minRemove(arr, n):
    LCS = [0 for i in range(n)]
    len = 0
  
    # Mark all elements of LCS as 1
    for i in range(n):
        LCS[i] = 1
  
    # Find LCS of array
    for i in range(1, n):
          
        for j in range(i):
            if (arr[i] > arr[j]):
                LCS[i] = max(LCS[i], LCS[j] + 1)

518
Chapter 63. Convert to Strictly increasing array with minimum changes

                  
        len = max(len, LCS[i])
  
    # Return min changes for array
    # to strictly increasing
    return (n - len)
  
# Driver Code
arr = [ 1, 2, 6, 5, 4 ]
n = len(arr)
print(minRemove(arr, n))
  
# This code is contributed by Azkia Anam.

C#

// C# program to find min 


// elements to change so 
// array is strictly
// increasing
using System;
  
class GFG 
{
  
    // To find min elements to
    // remove from array to 
    // make it strictly increasing
    static int minRemove(int []arr, 
                         int n)
    {
        int []LCS = new int[n];
        int len = 0;
  
        // Mark all elements
        // of LCS as 1
        for (int i = 0; i < n; i++)
            LCS[i] = 1;
  
        // Find LCS of array
        for (int i = 1; i < n; i++) 
        {
            for (int j = 0; j < i; j++) 
            {
                if (arr[i] > arr[j])
                    LCS[i] = Math.Max(LCS[i], 
                                 LCS[j] + 1);
            }

519
Chapter 63. Convert to Strictly increasing array with minimum changes

            len = Math.Max(len, LCS[i]);


        }
  
        // Return min changes 
        // for array to strictly 
        // increasing
        return n - len;
    }
  
    // Driver Code
    public static void Main()
    {
        int []arr = {1, 2, 6, 5, 4};
        int n = arr.Length;
  
        Console.WriteLine(minRemove(arr, n));
    }
}
  
// This code is contributed
// by anuj_67.

PHP

<?php
// PHP program to find min
// elements to change so 
// array is strictly increasing
  
// To find min elements to 
// remove from array to make 
// it strictly increasing
function minRemove($arr, $n)
{
    $LCS = array();
    $len = 0;
  
    // Mark all elements
    // of LCS as 1
    for ($i = 0; $i < $n; $i++)
        $LCS[$i] = 1;
  
    // Find LCS of array
    for ($i = 1; $i < $n; $i++) 
    {
        for ($j = 0; $j < $i; $j++)
        {
            if ($arr[$i] > $arr[$j])

520
Chapter 63. Convert to Strictly increasing array with minimum changes

                $LCS[$i] = max($LCS[$i], 
                               $LCS[$j] + 1);
        }
        $len = max($len, $LCS[$i]);
    }
  
    // Return min changes 
    // for array to strictly 
    // increasing
    return $n - $len;
}
  
// Driver Code
$arr = array(1, 2, 6, 5, 4);
$n = count($arr);
  
echo minRemove($arr, $n);
  
// This code is contributed
// by anuj_6
?>

Output:

Improved By : vt_m

Source

https://www.geeksforgeeks.org/convert-strictly-increasing-array-minimum-changes/

521
Chapter 64

Count numbers from 1 to n that


have 4 as a digit

Count numbers from 1 to n that have 4 as a digit - GeeksforGeeks


Given a number n, find count of all numbers from 1 to n that have 4 as a digit.
Examples :

Input: n = 5
Output: 1
Only 4 has '4' as digit

Input: n = 50
Output: 14

Input: n = 328
Output: 60

This problem is mainly a variation of previous article on Compute sum of digits in all
numbers from 1 to n.
Naive Solution:
A naive solution is to go through every number x from 1 to n, and check if x has 4. To check
if x has or not, we can traverse all digits of x. Below is the implementation of above idea :

Source

https://www.geeksforgeeks.org/count-numbers-from-1-to-n-that-have-4-as-a-a-digit/
C++

522
Chapter 64. Count numbers from 1 to n that have 4 as a digit

// A Simple C++ program to compute sum of digits in numbers from 1 to n


#include<iostream>
using namespace std;
  
bool has4(int x);
  
// Returns sum of all digits in numbers from 1 to n
int countNumbersWith4(int n)
{
    int result = 0; // initialize result
  
    // One by one compute sum of digits in every number from
    // 1 to n
    for (int x=1; x<=n; x++)
        result += has4(x)? 1 : 0;
  
    return result;
}
  
// A utility function to compute sum of digits in a
// given number x
bool has4(int x)
{
    while (x != 0)
    {
        if (x%10 == 4)
           return true;
        x   = x /10;
    }
    return false;
}
  
// Driver Program
int main()
{
   int n = 328;
   cout << "Count of numbers from 1 to " << n 
        << " that have 4 as a a digit is " 
        << countNumbersWith4(n) << endl;
   return 0;
}

Java

// Java program to compute sum of


// digits in numbers from 1 to n
import java.io.*;
  

523
Chapter 64. Count numbers from 1 to n that have 4 as a digit

class GFG {
      
    // Returns sum of all digits
    // in numbers from 1 to n
    static int countNumbersWith4(int n)
    {
        // initialize result
        int result = 0;
       
        // One by one compute sum of digits
        // in every number from 1 to n
        for (int x=1; x<=n; x++)
            result += has4(x)? 1 : 0;
       
        return result;
    }
      
    // A utility function to compute sum
    // of digits in a given number x
    static boolean has4(int x)
    {
        while (x != 0)
        {
            if (x%10 == 4)
               return true;
            x   = x /10;
        }
        return false;
    }
       
    // Driver Program
    public static void main(String args[])
    {
       int n = 328;
       System.out.println("Count of numbers from 1 to "
                          + " that have 4 as a a digit is "
                          + countNumbersWith4(n)) ;
    }
}
  
// This code is contributed by Nikita Tiwari.

Python

# A Simple Python 3 program to compute


# sum of digits in numbers from 1 to n
  
# Returns sum of all digits in numbers from 1 to n

524
Chapter 64. Count numbers from 1 to n that have 4 as a digit

def countNumbersWith4(n) :
    result = 0 # initialize result
  
    # One by one compute sum of digits
    # in every number from 1 to n
    for x in range(1, n + 1) :
        if(has4(x) == True) :
            result = result + 1
  
    return result
  
# A utility function to compute sum  
# of digits in a given number x
def has4(x) :
    while (x != 0) :
        if (x%10 == 4) :
            return True
        x = x //10
      
    return False
      
# Driver Program
n = 328
print ("Count of numbers from 1 to ", n,
        " that have 4 as a a digit is ", 
                    countNumbersWith4(n)) 
  
  
# This code is contributed by Nikita Tiwari.

C#

// C# program to compute sum of


// digits in numbers from 1 to n
using System;
  
public class GFG 
{
      
    // Returns sum of all digits
    // in numbers from 1 to n
    static int countNumbersWith4(int n)
    {
          
        // initialize result
        int result = 0;
      
        // One by one compute sum of digits

525
Chapter 64. Count numbers from 1 to n that have 4 as a digit

        // in every number from 1 to n


        for (int x = 1; x <= n; x++)
            result += has4(x) ? 1 : 0;
      
        return result;
    }
      
    // A utility function to compute sum
    // of digits in a given number x
    static bool has4(int x)
    {
        while (x != 0)
        {
            if (x % 10 == 4)
            return true;
            x = x / 10;
        }
        return false;
    }
      
    // Driver Code
    public static void Main()
    {
        int n = 328;
        Console.WriteLine("Count of numbers from 1 to "
                        + " that have 4 as a a digit is "
                        + countNumbersWith4(n)) ;
    }
}
  
// This code is contributed by Sam007 

PHP

<?php
// PHP program to compute sum of
// digits in numbers from 1 to n
  
// Returns sum of all digits 
// in numbers from 1 to n
function countNumbersWith4($n)
{
    $result = 0; // initialize result
  
    // One by one compute sum of 
    // digits in every number from 1 to n
    for ($x = 1; $x <= $n; $x++)
        $result += has4($x) ? 1 : 0;

526
Chapter 64. Count numbers from 1 to n that have 4 as a digit

  
    return $result;
}
  
// A utility function to compute 
// sum of digits in a given number x
function has4($x)
{
    while ($x != 0)
    {
        if ($x % 10 == 4)
        return true;
        $x = intval($x / 10);
    }
    return false;
}
  
// Driver Code
$n = 328;
echo "Count of numbers from 1 to " . $n . 
        " that have 4 as a a digit is " .
                   countNumbersWith4($n);
      
// This code is contributed by Sam007
?>

Output :

Count of numbers from 1 to 328 that have 4 as a a digit is 60

Efficient Solution:
Above is a naive solution. We can do it more efficiently by finding a pattern.
Let us take few examples.

Count of numbers from 0 to 9 = 1


Count of numbers from 0 to 99 = 1*9 + 10 = 19
Count of numbers from 0 to 999 = 19*9 + 100 = 271

In general, we can write


count(10d) = 9 * count(10d - 1) + 10d - 1

In below implementation, the above formula is implemented using dynamic programming


as there are overlapping subproblems.
The above formula is one core step of the idea. Below is complete algorithm.

527
Chapter 64. Count numbers from 1 to n that have 4 as a digit

1) Find number of digits minus one in n. Let this value be 'd'.


For 328, d is 2.

2) Compute some of digits in numbers from 1 to 10d - 1.


Let this sum be w. For 328, we compute sum of digits from 1 to
99 using above formula.

3) Find Most significant digit (msd) in n. For 328, msd is 3.

4.a) If MSD is 4. For example if n = 428, then count of


numbers is sum of following.
1) Count of numbers from 1 to 399
2) Count of numbers from 400 to 428 which is 29.

4.b) IF MSD > 4. For example if n is 728, then count of


numbers is sum of following.
1) Count of numbers from 1 to 399 and count of numbers
from 500 to 699, i.e., "a[2] * 6"
2) Count of numbers from 400 to 499, i.e. 100
3) Count of numbers from 700 to 728, recur for 28
4.c) IF MSD < 4. For example if n is 328, then count of
numbers is sum of following.
1) Count of numbers from 1 to 299 a
2) Count of numbers from 300 to 328, recur for 28

Below is implementation of above algorithm.


C++

// C++ program to count numbers having 4 as a digit


#include<bits/stdc++.h>
using namespace std;
  
// Function to count numbers from 1 to n that have
// 4 as a digit
int countNumbersWith4(int n)
{
    // Base case
   if (n < 4)
      return 0;
  
   // d = number of digits minus one in n. For 328, d is 2
   int d = log10(n);
  
   // computing count of numbers from 1 to 10^d-1,
   // d=0 a[0] = 0;
   // d=1 a[1] = count of numbers from 0 to 9 = 1
   // d=2 a[2] = count of numbers from 0 to 99 = a[1]*9 + 10 = 19

528
Chapter 64. Count numbers from 1 to n that have 4 as a digit

   // d=3 a[3] = count of numbers from 0 to 999 = a[2]*19 + 100 = 171
   int *a = new int[d+1];
   a[0] = 0, a[1] = 1;
   for (int i=2; i<=d; i++)
      a[i] = a[i-1]*9 + ceil(pow(10,i-1));
  
   // Computing 10^d
   int p = ceil(pow(10, d));
  
    // Most significant digit (msd) of n,
    // For 328, msd is 3 which can be obtained using 328/100
   int msd = n/p;
  
   // If MSD is 4. For example if n = 428, then count of
   // numbers is sum of following.
   // 1) Count of numbers from 1 to 399
   // 2) Count of numbers from 400 to 428 which is 29.
   if (msd == 4)
      return (msd)*a[d] + (n%p) + 1;
  
   // IF MSD > 4. For example if n is 728, then count of
   // numbers is sum of following.
   // 1) Count of numbers from 1 to 399 and count of numbers
   //    from 500 to 699, i.e., "a[2] * 6"
   // 2) Count of numbers from 400 to 499, i.e. 100
   // 3) Count of numbers from 700 to 728, recur for 28
   if (msd > 4)
      return (msd-1)*a[d] + p + countNumbersWith4(n%p);
  
   // IF MSD < 4. For example if n is 328, then count of
   // numbers is sum of following.
   // 1) Count of numbers from 1 to 299 a
   // 2) Count of numbers from 300 to 328, recur for 28
   return (msd)*a[d] + countNumbersWith4(n%p);
}
  
// Driver Program
int main()
{
   int n = 328;
   cout << "Count of numbers from 1 to " << n 
        << " that have 4 as a a digit is " 
        << countNumbersWith4(n) << endl;
   return 0;
}

Output:

529
Chapter 64. Count numbers from 1 to n that have 4 as a digit

Count of numbers from 1 to 328 that have 4 as a a digit is 60

This article is contributed by Shivam. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Improved By : Sam007

530
Chapter 65

Count All Palindrome


Sub-Strings in a String | Set 1

Count All Palindrome Sub-Strings in a String | Set 1 - GeeksforGeeks


Given a string, the task is to count all palindrome substring in a given string. Length of
palindrome substring is greater then or equal to 2.
Examples:

Input : str = "abaab"


Output: 3
Explanation :
All palindrome substring are :
"aba" , "aa" , "baab"

Input : str = "abbaeae"


Output: 4
Explanation :
All palindrome substring are :
"bb" , "abba" ,"aea","eae"

We have discussed a similar problem below.


Find all distinct palindromic sub-strings of a given string
The above problem can be recursively defined.

Initial Values : i = 0, j = n-1;


Given string 'str'

CountPS(i, j)

531
Chapter 65. Count All Palindrome Sub-Strings in a String | Set 1

// If length of string is 2 then we


// check both character are same or not
If (j == i+1)
return str[i] == str[j]

Else If str[i..j] is PALINDROME


// increment count by 1 and check for
// rest palindromic substring (i, j-1), (i+1, j)
// remove common palindrome substring (i+1, j-1)
return countPS(i+1, j) + countPS(i, j-1) + 1 -
countPS(i+1, j-1);

Else // if NOT PALINDROME


// We check for rest palindromic substrings (i, j-1)
// and (i+1, j)
// remove common palindrome substring (i+1 , j-1)
return countPS(i+1, j) + countPS(i, j-1) -
countPS(i+1 , j-1);

If we draw recursion tree of above recursive solution, we can observe overlapping Subprolems.
Since the problem has overlapping subproblems, we can solve it efficiently using Dynamic
Programming. Below is Dynamic Programming based solution.
C/C++

// C++ program to find palindromic substrings of a string


#include<bits/stdc++.h>
using namespace std;
  
// Returna total number of palindrome substring of
// length greater then equal to 2
int CountPS(char str[], int n)
{
    // creat empty 2-D matrix that counts all palindrome
    // substring. dp[i][j] stores counts of palindromic
    // substrings in st[i..j]
    int dp[n][n];
    memset(dp, 0, sizeof(dp));
  
    // P[i][j] = true if substring str[i..j] is palindrome,
    // else false
    bool P[n][n];
    memset(P, false , sizeof(P));
  
    // palindrome of single lenght
    for (int i= 0; i< n; i++)

532
Chapter 65. Count All Palindrome Sub-Strings in a String | Set 1

        P[i][i] = true;
  
    // palindrome of length 2
    for (int i=0; i<n-1; i++)
    {
        if (str[i] == str[i+1])
        {
            P[i][i+1] = true;
            dp[i][i+1] = 1 ;
        }
    }
  
    // Palindromes of length more then 2. This loop is similar
    // to Matrix Chain Multiplication. We start with a gap of
    // length 2 and fill DP table in a way that gap between
    // starting and ending indexes increases one by one by
    // outer loop.
    for (int gap=2 ; gap<n; gap++)
    {
        // Pick starting point for current gap
        for (int i=0; i<n-gap; i++)
        {
            // Set ending point
            int j = gap + i;
  
            // If current string is palindrome
            if (str[i] == str[j] && P[i+1][j-1] )
                P[i][j] = true;
  
            // Add current palindrome substring ( + 1)
            // and rest palinrome substring (dp[i][j-1] + dp[i+1][j])
            // remove common palinrome substrings (- dp[i+1][j-1])
            if (P[i][j] == true)
                dp[i][j] = dp[i][j-1] + dp[i+1][j] + 1 - dp[i+1][j-1];
            else
                dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1];
        }
    }
  
    // return total palindromic substrings
    return dp[0][n-1];
}
  
// Driver program
int main()
{
    char str[] = "abaab";
    int n = strlen(str);

533
Chapter 65. Count All Palindrome Sub-Strings in a String | Set 1

    cout << CountPS(str, n) << endl;


    return 0;
}

Java

// Java program to find palindromic substrings of a string


  
public class GFG 
{
    // Returna total number of palindrome substring of
    // length greater then equal to 2
    static int CountPS(char str[], int n)
    {
        // creat empty 2-D matrix that counts all palindrome
        // substring. dp[i][j] stores counts of palindromic
        // substrings in st[i..j]
        int dp[][] = new int[n][n];
       
        // P[i][j] = true if substring str[i..j] is palindrome,
        // else false
        boolean P[][] = new boolean[n][n];
       
        // palindrome of single lenght
        for (int i= 0; i< n; i++)
            P[i][i] = true;
       
        // palindrome of length 2
        for (int i=0; i<n-1; i++)
        {
            if (str[i] == str[i+1])
            {
                P[i][i+1] = true;
                dp[i][i+1] = 1 ;
            }
        }
       
        // Palindromes of length more then 2. This loop is similar
        // to Matrix Chain Multiplication. We start with a gap of
        // length 2 and fill DP table in a way that gap between
        // starting and ending indexes increases one by one by
        // outer loop.
        for (int gap=2 ; gap<n; gap++)
        {
            // Pick starting point for current gap
            for (int i=0; i<n-gap; i++)
            {
                // Set ending point

534
Chapter 65. Count All Palindrome Sub-Strings in a String | Set 1

                int j = gap + i;
       
                // If current string is palindrome
                if (str[i] == str[j] && P[i+1][j-1] )
                    P[i][j] = true;
       
                // Add current palindrome substring ( + 1)
                // and rest palinrome substring (dp[i][j-1] + dp[i+1][j])
                // remove common palinrome substrings (- dp[i+1][j-1])
                if (P[i][j] == true)
                    dp[i][j] = dp[i][j-1] + dp[i+1][j] + 1 - dp[i+1][j-1];
                else
                    dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1];
            }
        }
       
        // return total palindromic substrings
        return dp[0][n-1];
    }
      
    // Driver Method
    public static void main(String[] args)
    {
        String str = "abaab";
        System.out.println(CountPS(str.toCharArray(), str.length()));
    }
}

Output:

Time complexity O(n2 )


Auxiliary Space O(n2 )
Count All Palindrome Sub-Strings in a String | Set 2

Source

https://www.geeksforgeeks.org/count-palindrome-sub-strings-string/

535
Chapter 66

Count All Palindromic


Subsequence in a given String

Count All Palindromic Subsequence in a given String - GeeksforGeeks


Find how many palindromic subsequence (need not necessarily be distinct) can be formed
in a given string. Note that the empty string is not considered as a palindrome.
Examples:

Input : str = "abcd"


Output : 4
Explanation :- palindromic subsequence are : "a" ,"b", "c" ,"d"

Input : str = "aab"


Output : 4
Explanation :- palindromic subsequence are :"a", "a", "b", "aa"

Input : str = "aaaa"


Output : 15

The above problem can be recursively defined.

Initial Values : i= 0, j= n-1;

CountPS(i,j)
// Every single character of a string is a palindrome
// subsequence
if i == j
return 1 // palindrome of length 1

536
Chapter 66. Count All Palindromic Subsequence in a given String

// If first and last characters are same, then we


// consider it as palindrome subsequence and check
// for the rest subsequence (i+1, j), (i, j-1)
Else if (str[i] == str[j)]
return countPS(i+1, j) + countPS(i, j-1) + 1;

else
// check for rest sub-sequence and remove common
// palindromic subsequences as they are counted
// twice when we do countPS(i+1, j) + countPS(i,j-1)
return countPS(i+1, j) + countPS(i, j-1) - countPS(i+1, j-1)

If we draw recursion tree of above recursive solution, we can observe overlapping Subpro-
lems. Since the problem has overlapping subproblems, we can solve it efficiently using
Dynamic Programming. Below is Dynamic Programming based solution.

C++

// Counts Palindromic Subsequence in a given String


#include<iostream>
#include<cstring>
using namespace std;
  
// Function return the total palindromic subsequence
int countPS(string str)
{
    int N = str.length();
  
    // create a 2D array to store the count of palindromic
    // subsequence
    int cps[N+1][N+1];
    memset(cps, 0 ,sizeof(cps));
  
    // palindromic subsequence of length 1
    for (int i=0; i<N; i++)
        cps[i][i] = 1;
  
    // check subsequence of length L is palindrome or not
    for (int L=2; L<=N; L++)
    {
        for (int i=0; i<N; i++)
        {
            int k = L+i-1;
            if (str[i] == str[k])
                cps[i][k] = cps[i][k-1] +
                            cps[i+1][k] + 1;
            else

537
Chapter 66. Count All Palindromic Subsequence in a given String

                cps[i][k] = cps[i][k-1] +
                            cps[i+1][k] -
                            cps[i+1][k-1];
        }
    }
  
    // return total palindromic subsequence
    return cps[0][N-1];
}
  
// Driver program
int main()
{
    string str = "abcb";
    cout << "Total palindromic subsequence are : "
         << countPS(str) << endl;
    return 0;
}

Java

// Java code to Count Palindromic Subsequence


// in a given String
public class GFG 
{      
    // Function return the total palindromic 
    // subsequence
    static int countPS(String str)
    {
        int N = str.length();
       
        // create a 2D array to store the count
        // of palindromic subsequence
        int[][] cps = new int[N+1][N+1];
       
        // palindromic subsequence of length 1
        for (int i = 0; i < N; i++)
            cps[i][i] = 1;
       
        // check subsequence of length L is 
        // palindrome or not
        for (int L=2; L<=N; L++)
        {
            for (int i = 0; i < N; i++)
            {
                int k = L + i - 1;
                if (k < N){
                if (str.charAt(i) == str.charAt(k))

538
Chapter 66. Count All Palindromic Subsequence in a given String

                    cps[i][k] = cps[i][k-1] +
                                cps[i+1][k] + 1;
                else
                    cps[i][k] = cps[i][k-1] +
                                cps[i+1][k] -
                                cps[i+1][k-1];
                }
            }
        }
       
        // return total palindromic subsequence
        return cps[0][N-1];
    }
       
    // Driver program
    public static void main(String args[])
    {
        String str = "abcb";
        System.out.println("Total palindromic "+
                            "subsequence are : "
                              + countPS(str));
    }
}
// This code is contributed by Sumit Ghosh

Python3

# Python3 code to Count Palindromic


# Subsequence in a given String
  
# Function return the total  
# palindromic subsequence
def countPS(str):
  
    N = len(str)
      
    # Create a 2D array to store the count
    # of palindromic subsequence
    cps = [[0 for i in range(N + 2)]for j in range(N + 2)]
      
    # palindromic subsequence of length 1
    for i in range(N):
        cps[i][i] = 1
      
    # check subsequence of length L  
    # is palindrome or not
    for L in range(2, N + 1):
      

539
Chapter 66. Count All Palindromic Subsequence in a given String

        for i in range(N):
            k = L + i - 1
            if (k < N):
                if (str[i] == str[k]):
                    cps[i][k] = (cps[i][k - 1] +
                                cps[i + 1][k] + 1)
                else:
                    cps[i][k] = (cps[i][k - 1] +
                                cps[i + 1][k] -
                                cps[i + 1][k - 1])
      
    # return total palindromic subsequence
    return cps[0][N - 1]
      
# Driver program
str = "abcb"
print("Total palindromic subsequence are : "
                            , countPS(str))
  
  
# This code is contributed by Anant Agarwal.

C#

// C# code to Count Palindromic Subsequence


// Subsequence in a given String
using System;
  
class GFG {
      
    // Function return the total  
    // palindromic subsequence
    static int countPS(string str)
    {
        int N = str.Length;
      
        // create a 2D array to store the 
        // count of palindromic subsequence
        int[,] cps = new int[N + 1, N + 1];
      
        // palindromic subsequence
        // of length 1
        for (int i = 0; i < N; i++)
            cps[i, i] = 1;
      
        // check subsequence of length  
        // L is palindrome or not
        for (int L = 2; L <= N; L++)

540
Chapter 66. Count All Palindromic Subsequence in a given String

        {
            for (int i = 0; i < N; i++)
            {
                int k = L + i - 1;
                if (k < N) {
                if (str[i] == str[k])
                    cps[i, k] = cps[i, k - 1] + 
                                cps[i + 1, k] + 1;
                else
                    cps[i, k] = cps[i, k - 1] +
                                cps[i + 1, k] -
                                cps[i + 1, k - 1];
                }
            }
        }
      
        // return total palindromic
        // subsequence
        return cps[0, N - 1];
    }
      
    // Driver Code
    public static void Main()
    {
        string str = "abcb";
        Console.Write("Total palindromic "+
                       "subsequence are : "
                           + countPS(str));
    }
}
  
// This code is contributed by nitin mittal.

Output:

Total palindromic subsequence are : 6

Time Complexity : O(N2 )


Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/count-palindromic-subsequence-given-string/

541
Chapter 67

Count Balanced Binary Trees of


Height h

Count Balanced Binary Trees of Height h - GeeksforGeeks


Given a height h, count and return the maximum number of balanced binary trees possible
with height h. A balanced binary tree is one in which for every node, the difference between
heights of left and right subtree is not more than 1.
Examples :

Input : h = 3
Output : 15

Input : h = 4
Output : 315

Following are the balanced binary trees of height 3.

Height of tree, h = 1 + max(left height, right height)


Since the difference between the heights of left and right subtree is not more than one,
possible heights of left and right part can be one of the following:

542
Chapter 67. Count Balanced Binary Trees of Height h

1. (h-1), (h-2)
2. (h-2), (h-1)
3. (h-1), (h-1)

count(h) = count(h-1) * count(h-2) +


count(h-2) * count(h-1) +
count(h-1) * count(h-1)
= 2 * count(h-1) * count(h-2) +
count(h-1) * count(h-1)
= count(h-1) * (2*count(h - 2) +
count(h - 1))

Hence we can see that the problem has optimal substructure property.
A recursive function to count no of balanced binary trees of height h is:

int countBT(int h)
{
// One tree is possible with height 0 or 1
if (h == 0 || h == 1)
return 1;
return countBT(h-1) * (2 *countBT(h-2) +
countBT(h-1));
}

The time complexity of this recursive approach will be exponential. The recursion tree for
the problem with h = 3 looks like :

As we can see, sub-problems are solved repeatedly. Therefore we store the results as we
compute them.
An efficient dynamic programming approach will be as follows :
CPP

// C++ program to count number of balanced


// binary trees of height h.
#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
   

543
Chapter 67. Count Balanced Binary Trees of Height h

long long int countBT(int h) {


       
    long long int dp[h + 1];
    //base cases
    dp[0] = dp[1] = 1;
    for(int i = 2; i <= h; i++) {
        dp[i] = (dp[i - 1] * ((2 * dp [i - 2])%mod + dp[i - 1])%mod) % mod;
    }
    return dp[h];
}
  
  
// Driver program
int main()
{
    int h = 3;
    cout << "No. of balanced binary trees"
            " of height h is: "
         << countBT(h) << endl;
}

PHP

<?php
// PHP program to count
// number of balanced
  
$mod =1000000007;
  
function countBT($h)
{
    global $mod;
      
    // base cases
    $dp[0] = $dp[1] = 1;
    for($i = 2; $i <= $h; $i++) 
    {
        $dp[$i] = ($dp[$i - 1] * 
                  ((2 * $dp [$i - 2]) % 
                  $mod + $dp[$i - 1]) % 
                          $mod) % $mod;
    }
    return $dp[$h];
}
  
  
// Driver Code
$h = 3;

544
Chapter 67. Count Balanced Binary Trees of Height h

echo "No. of balanced binary trees",


                " of height h is: ",
                    countBT($h) ,"\n";
  
  
// This code is contributed by aj_36
?>

Output :

No of balanced binary trees of height h is: 15

Improved By : Anuj_Sharma, jit_t

Source

https://www.geeksforgeeks.org/count-balanced-binary-trees-height-h/

545
Chapter 68

Count Derangements
(Permutation such that no
element appears in its original
position)

Count Derangements (Permutation such that no element appears in its original position) -
GeeksforGeeks
A Derangement is a permutation of n elements, such that no element appears in its original
position. For example, a derangement of {0, 1, 2, 3} is {2, 3, 1, 0}.
Given a number n, find total number of Derangements of a set of n elements.
Examples :

Input: n = 2
Output: 1
For two elements say {0, 1}, there is only one
possible derangement {1, 0}

Input: n = 3
Output: 2
For three elements say {0, 1, 2}, there are two
possible derangements {2, 0, 1} and {1, 2, 0}

Input: n = 4
Output: 9
For four elements say {0, 1, 2, 3}, there are 9
possible derangements {1, 0, 3, 2} {1, 2, 3, 0}

546
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

{1, 3, 0, 2}, {2, 3, 0, 1}, {2, 0, 3, 1}, {2, 3,


1, 0}, {3, 0, 1, 2}, {3, 2, 0, 1} and {3, 2, 1, 0}

Let countDer(n) be count of derangements for n elements. Below is recursive relation for it.

countDer(n) = (n - 1) * [countDer(n - 1) + countDer(n - 2)]

How does above recursive relation work?


There are n – 1 ways for element 0 (this explains multiplication with n – 1).
Let 0 be placed at index i. There are now two possibilities, depending on whether or not
element i is placed at 0 in return.

1. i is placed at 0: This case is equivalent to solving the problem for n-2 elements as
two elements have just swapped their positions.
2. i is not placed at 0: This case is equivalent to solving the problem for n-1 elements
as now there are n-1 elements, n-1 positions and every element has n-2 choices

Below is Simple Solution based on above recursive formula.

C++

// A Naive Recursive C++ program 


// to count derangements
#include <bits/stdc++.h>
using namespace std;
  
int countDer(int n)
{
// Base cases
if (n == 1) return 0;
if (n == 0) return 1;
if (n == 2) return 1;
  
// countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
return (n - 1) * (countDer(n - 1) + 
                  countDer(n - 2));
}
  
// Driver Code
int main()
{
    int n = 4;
    cout << "Count of Derangements is " 
         << countDer(n);
    return 0;
}

547
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

Java

// A Naive Recursive java 


// program to count derangements
import java.io.*;
  
class GFG 
{
      
    // Function to count
    // derangements
    static int countDer(int n)
    {
        // Base cases
        if (n == 1) return 0;
        if (n == 0) return 1;
        if (n == 2) return 1;
          
        // countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
        return (n - 1) * (countDer(n - 1) + 
                          countDer(n - 2));
    }
      
    // Driver Code
    public static void main (String[] args)
    {
        int n = 4;
        System.out.println( "Count of Derangements is "
                             +countDer(n));
  
    }
}
  
// This code is contributed by vt_m

Python3

# A Naive Recursive Python3 


# program to count derangements
  
def countDer(n):
      
    # Base cases
    if (n == 1): return 0
    if (n == 0): return 1
    if (n == 2): return 1
      

548
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

    # countDer(n) = (n-1)[countDer(n-1) + der(n-2)]


    return (n - 1) * (countDer(n - 1) + 
                      countDer(n - 2))
  
# Driver Code
n = 4
print("Count of Derangements is ", countDer(n))
  
  
# This code is contributed by Azkia Anam.

C#

// A Naive Recursive C#
// program to count derangements
using System;
  
class GFG 
{
      
    // Function to count
    // derangements
    static int countDer(int n)
    {
        // Base cases
        if (n == 1) return 0;
        if (n == 0) return 1;
        if (n == 2) return 1;
          
        // countDer(n) = (n-1)[countDer(n-1) + der(n-2)]
        return (n - 1) * (countDer(n - 1) + 
                          countDer(n - 2));
    }
      
    // Driver Code
    public static void Main ()
    {
        int n = 4;
        Console.Write( "Count of Derangements is " +
                        countDer(n));
  
    }
}
  
// This code is contributed by nitin mittal.

PHP

549
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

<?php
// A Naive Recursive PHP program 
// to count derangements
  
function countDer($n)
{
      
    // Base cases
    if ($n == 1) 
        return 0;
    if ($n == 0)
        return 1;
    if ($n == 2) 
        return 1;
      
    // countDer(n) = (n-1)[countDer(n-1) +
    // der(n-2)]
    return ($n - 1) * (countDer($n - 1) + 
                       countDer($n - 2));
}
  
    // Driver Code
    $n = 4;
    echo "Count of Derangements is ", countDer($n);
  
// This code is contributed by nitin mittal.
?>

Output:

Count of Derangements is 9

Time Complexity: T(n) = T(n-1) + T(n-2) which is exponential.


We can observe that this implementation does repeated work. For example see recursion
tree for countDer(5), countDer(3) is being being evaluated twice.

cdr() ==> countDer()

cdr(5)
/ \
cdr(4) cdr(3)
/ \ / \
cdr(3) cdr(2) cdr(2) cdr(1)

An Efficient Solution is to use Dynamic Programming to store results of subproblems in


an array and build the array in bottom up manner.

550
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

C++

// A Dynamic programming based C++ 


// program to count derangements
#include <bits/stdc++.h>
using namespace std;
  
int countDer(int n)
{
    // Create an array to store 
    // counts for subproblems
    int der[n + 1];
  
    // Base cases
    der[0] = 1;
    der[1] = 0;
    der[2] = 1;
  
    // Fill der[0..n] in bottom up manner 
    // using above recursive formula
    for (int i = 3; i <= n; ++i)
        der[i] = (i - 1) * (der[i - 1] + 
                            der[i - 2]);
  
    // Return result for n
    return der[n];
}
  
// Driver code
int main()
{
    int n = 4;
    cout << "Count of Derangements is " 
         << countDer(n);
    return 0;
}

Java

// A Dynamic programming based 


// java program to count derangements
import java.io.*;
  
class GFG 
{
      
    // Function to count

551
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

    // derangements 
    static int countDer(int n)
    {
        // Create an array to store
        // counts for subproblems
        int der[] = new int[n + 1];
      
        // Base cases
        der[0] = 1;
        der[1] = 0;
        der[2] = 1;
      
        // Fill der[0..n] in bottom up 
        // manner using above recursive
        // formula
        for (int i = 3; i <= n; ++i)
            der[i] = (i - 1) * (der[i - 1] + 
                                der[i - 2]);
      
        // Return result for n
        return der[n];
    }
      
    // Driver program
    public static void main (String[] args) 
    {
        int n = 4;
        System.out.println("Count of Derangements is " + 
                            countDer(n));
      
    }
}
  
// This code is contributed by vt_m

Python3

# A Dynamic programming based Python3


# program to count derangements
  
def countDer(n):
      
    # Create an array to store
    # counts for subproblems
    der = [0 for i in range(n + 1)]
      
    # Base cases
    der[0] = 1

552
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

    der[1] = 0
    der[2] = 1
      
    # Fill der[0..n] in bottom up manner 
    # using above recursive formula
    for i in range(3, n + 1):
        der[i] = (i - 1) * (der[i - 1] + 
                            der[i - 2])
          
    # Return result for n
    return der[n]
  
# Driver Code
n = 4
print("Count of Derangements is ", countDer(n))
  
# This code is contributed by Azkia Anam.

C#

   
// A Dynamic programming based 
// C# program to count derangements
using System;
  
class GFG 
{
      
    // Function to count
    // derangements 
    static int countDer(int n)
    {
        // Create an array to store
        // counts for subproblems
        int []der = new int[n + 1];
      
        // Base cases
        der[0] = 1;
        der[1] = 0;
        der[2] = 1;
      
        // Fill der[0..n] in bottom up 
        // manner using above recursive
        // formula
        for (int i = 3; i <= n; ++i)
            der[i] = (i - 1) * (der[i - 1] + 
                                der[i - 2]);
      

553
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

        // Return result for n


        return der[n];
    }
      
    // Driver code
    public static void Main () 
    {
        int n = 4;
        Console.Write("Count of Derangements is " + 
                       countDer(n));
      
    }
}
  
// This code is contributed by nitin mittal

PHP

<?php
// A Dynamic programming based PHP
// program to count derangements
  
function countDer($n)
{
    // Create an array to store 
    // counts for subproblems
  
    // Base cases
    $der[0] = 1;
    $der[1] = 0;
    $der[2] = 1;
  
    // Fill der[0..n] in bottom up manner 
    // using above recursive formula
    for ($i = 3; $i <= $n; ++$i)
        $der[$i] = ($i - 1) * ($der[$i - 1] + 
                               $der[$i - 2]);
  
    // Return result for n
    return $der[$n];
}
  
// Driver code
$n = 4;
echo "Count of Derangements is ",
                    countDer($n);
  
// This code is contributed by aj_36

554
Chapter 68. Count Derangements (Permutation such that no element appears in its
original position)

?>

Output :

Count of Derangements is 9

Time Complexity : O(n)


Auxiliary Space : O(n)
Thanks to Utkarsh Trivedi for suggesting above solution.
References:
https://en.wikipedia.org/wiki/Derangement
Improved By : nitin mittal, jit_t

Source

https://www.geeksforgeeks.org/count-derangements-permutation-such-that-no-element-appears-in-its-original-posit

555
Chapter 69

Count Distinct Subsequences

Count Distinct Subsequences - GeeksforGeeks


Given a string, find the count of distinct subsequences of it.
Examples:

Input : str = "gfg"


Output : 7
The seven distinct subsequences are "", "g", "f",
"gf", "fg", "gg" and "gfg"

Input : str = "ggg"


Output : 4
The four distinct subsequences are "", "g", "gg"
and "ggg"

The problem of counting distinct subsequences is easy if all characters of input string are
distinct. The count is equal to n C0 + n C1 + n C2 + … n Cn = 2n .
How to count distinct subsequences when there can be repetition in input string?
A Simple Solution to count distinct subsequences in a string with duplicates is to generate
all subsequences. For every subsequence, store it in a hash table if it doesn’t exist already.
Time complexity of this solution is exponential and it requires exponential extra space.
An Efficient Solution doesn’t require generation of subsequences.

Let countSub(n) be count of subsequences of


first n characters in input string. We can
recursively write it as below.

countSub(n) = 2*Count(n-1) - Repetition

556
Chapter 69. Count Distinct Subsequences

If current character, i.e., str[n-1] of str has


not appeared before, then
Repetition = 0

Else:
Repetition = Count(m)
Here m is index of previous occurrence of
current character. We basically remove all
counts ending with previous occurrence of
current character.

How does this work?


If there are no repetitions, then count becomes double of count for n-1 because we get
count(n-1) more subsequences by adding current character at the end of all subsequences
possible with n-1 length.
If there repetitions, then we find count of all distinct subsequences ending with previous
occurrence. This count can be obtained be recursively calling for index of previous occur-
rence.
Since above recurrence has overlapping subproblems, we can solve it using Dynamic Pro-
gramming.
Below is C++ implementation of above idea.

C++

// C++ program to count number of distinct


// subsequences of a given string.
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 256;
  
// Returns count of distinct sunsequences of str.
int countSub(string str)
{
    // Create an array to store index
    // of last
    vector<int> last(MAX_CHAR, -1);
  
    // Length of input string
    int n = str.length();
  
    // dp[i] is going to store count of distinct
    // subsequences of length i.
    int dp[n+1];
  
    // Empty substring has only one subsequence

557
Chapter 69. Count Distinct Subsequences

    dp[0] = 1;
  
    // Traverse through all lengths from 1 to n.
    for (int i=1; i<=n; i++)
    {
        // Number of subsequences with substring
        // str[0..i-1]
        dp[i] = 2*dp[i-1];
  
        // If current character has appeared
        // before, then remove all subsequences
        // ending with previous occurrence.
        if (last[str[i-1]] != -1)
            dp[i] = dp[i] - dp[last[str[i-1]]];
  
        // Mark occurrence of current character
        last[str[i-1]] = (i-1);
    }
  
    return dp[n];
}
  
// Driver code
int main()
{
   cout << countSub("gfg");
   return 0;
}

Java

// Java program to count number of distinct


// subsequences of a given string.
import java.util.ArrayList;
import java.util.Arrays;
public class Count_Subsequences {
      
    static final int MAX_CHAR = 256;
       
    // Returns count of distinct sunsequences of str.
    static int countSub(String str)
    {
        // Create an array to store index
        // of last
        int[] last = new int[MAX_CHAR];
        Arrays.fill(last, -1);
          
        // Length of input string

558
Chapter 69. Count Distinct Subsequences

        int n = str.length();
       
        // dp[i] is going to store count of distinct
        // subsequences of length i.
        int[] dp = new int[n+1];
       
        // Empty substring has only one subsequence
        dp[0] = 1;
       
        // Traverse through all lengths from 1 to n.
        for (int i=1; i<=n; i++)
        {
            // Number of subsequences with substring
            // str[0..i-1]
            dp[i] = 2*dp[i-1];
       
            // If current character has appeared
            // before, then remove all subsequences
            // ending with previous occurrence.
            if (last[(int)str.charAt(i-1)] != -1)
                dp[i] = dp[i] - dp[last[(int)str.charAt(i-1)]];
       
            // Mark occurrence of current character
            last[(int)str.charAt(i-1)] = (i-1);
        }
       
        return dp[n];
    }
       
    // Driver code
    public static void main(String args[])
    {
       System.out.println(countSub("gfg"));
    }
}
// This code is contributed by Sumit Ghosh

Output:

Time Complexity : O(n)


Auxiliary Space : O(n)
Improved By : s_pandey06

559
Chapter 69. Count Distinct Subsequences

Source

https://www.geeksforgeeks.org/count-distinct-subsequences/

560
Chapter 70

Count Possible Decodings of a


given Digit Sequence

Count Possible Decodings of a given Digit Sequence - GeeksforGeeks


Let 1 represent ‘A’, 2 represents ‘B’, etc. Given a digit sequence, count the number of
possible decodings of the given digit sequence.
Examples:

Input: digits[] = "121"


Output: 3
// The possible decodings are "ABA", "AU", "LA"

Input: digits[] = "1234"


Output: 3
// The possible decodings are "ABCD", "LCD", "AWD"

An empty digit sequence is considered to have one decoding. It may be assumed that the
input contains valid digits from 0 to 9 and there are no leading 0’s, no extra trailing 0’s and
no two or more consecutive 0’s.
This problem is recursive and can be broken in sub-problems. We start from end of the
given digit sequence. We initialize the total count of decodings as 0. We recur for two
subproblems.
1) If the last digit is non-zero, recur for remaining (n-1) digits and add the result to total
count.
2) If the last two digits form a valid character (or smaller than 27), recur for remaining (n-2)
digits and add the result to total count.
Following is the implementation of the above approach.

CPP

561
Chapter 70. Count Possible Decodings of a given Digit Sequence

// A naive recursive C++ implementation to count number of decodings


// that can be formed from a given digit sequence
#include <iostream>
#include <cstring>
using namespace std;
  
// Given a digit sequence of length n, returns count of possible
// decodings by replacing 1 with A, 2 woth B, ... 26 with Z
int countDecoding(char *digits, int n)
{
    // base cases
    if (n == 0 || n == 1)
        return 1;
  
    int count = 0;  // Initialize count
  
    // If the last digit is not 0, then last digit must add to
    // the number of words
    if (digits[n-1] > '0')
        count =  countDecoding(digits, n-1);
  
    // If the last two digits form a number smaller than or equal to 26,
    // then consider last two digits and recur
    if (digits[n-2] == '1' || (digits[n-2] == '2' && digits[n-1] < '7') )
        count +=  countDecoding(digits, n-2);
  
    return count;
}
  
// Driver program to test above function
int main()
{
    char digits[] = "1234";
    int n = strlen(digits);
    cout << "Count is " << countDecoding(digits, n);
    return 0;
}

Java

// A naive recursive C++ implementation 


// to count number of decodings that
// can be formed from a given digit sequence
  
class GFG {
      
// Given a digit sequence of length n,
// returns count of possible decodings by

562
Chapter 70. Count Possible Decodings of a given Digit Sequence

// replacing 1 with A, 2 woth B, ... 26 with Z


static int countDecoding(char[] digits, int n) 
{
    // base cases
    if (n == 0 || n == 1)
    return 1;
  
    // Initialize count
    int count = 0; 
  
    // If the last digit is not 0, then 
    // last digit must add to
    // the number of words
    if (digits[n - 1] > '0')
    count = countDecoding(digits, n - 1);
  
    // If the last two digits form a number
    // smaller than or equal to 26,
    // then consider last two digits and recur
    if (digits[n - 2] == '1' || 
       (digits[n - 2] == '2' && digits[n - 1] < '7'))
    count += countDecoding(digits, n - 2);
  
    return count;
}
  
// Driver program to test above function
public static void main(String[] args) 
{
    char digits[] = {'1', '2', '3', '4'};
    int n = digits.length;
    System.out.printf("Count is %d", countDecoding(digits, n));
}
}
  
// This code is contributed by Smitha Dinesh Semwal.

Python3

# A Dynamic Programming based


# Python 3 implementation to count decodings
  
# A Dynamic Programming based
# function to count decodings
def countDecodingDP(digits, n):
          
        # A table to store results of subproblems
    count = [0] * (n+1) 

563
Chapter 70. Count Possible Decodings of a given Digit Sequence

    count[0] = 1
    count[1] = 1
  
    for i in range(2, n+1):
      
        count[i] = 0
  
        # If the last digit is not 0,
                # then last digit must add to
        # the number of words
        if (digits[i-1] > '0'):
            count[i] = count[i-1]
  
        # If second last digit is smaller
                # than 2 and last digit is
        # smaller than 7, then last two
                # digits form a valid character
        if (digits[i-2] == '1' or (digits[i-2] == '2' and digits[i-1] < '7') ):
            count[i] += count[i-2]
      
    return count[n]
  
  
# Driver program to test above function
digits = ['1','2','3','4']
n = len(digits)
  
print("Count is ",countDecodingDP(digits, n))
  
# This code is contributed by
# Smitha Dinesh Semwal

C#

// A naive recursive php implementation 


// to count number of decodings that
// can be formed from a given digit sequence
using System;
  
class GFG {
      
    // Given a digit sequence of length n,
    // returns count of possible decodings 
    // by replacing 1 with A, 2 woth B, ...
    // 26 with Z
    static int countDecoding(char []digits, int n) 
    {
          

564
Chapter 70. Count Possible Decodings of a given Digit Sequence

        // base cases


        if (n == 0 || n == 1)
        return 1;
      
        // Initialize count
        int count = 0; 
      
        // If the last digit is not 0, then 
        // last digit must add to
        // the number of words
        if (digits[n - 1] > '0')
        count = countDecoding(digits, n - 1);
      
        // If the last two digits form a number
        // smaller than or equal to 26, then 
        // consider last two digits and recur
        if (digits[n - 2] == '1' || 
                    (digits[n - 2] == '2' && 
                       digits[n - 1] < '7'))
            count += countDecoding(digits, n - 2);
      
        return count;
    }
      
    // Driver program to test above function
    public static void Main() 
    {
        char []digits = {'1', '2', '3', '4'};
        int n = digits.Length;
        Console.Write("Count is ");
        Console.Write(countDecoding(digits, n));
    }
}
  
// This code is contributed by nitin mittal.

]
Output:

Count is 3

The time complexity of above the code is exponential. If we take a closer look at the above
program, we can observe that the recursive solution is similar to Fibonacci Numbers. There-
fore, we can optimize the above solution to work in O(n) time using Dynamic Programming.
Following is C++ implementation for the same.

// A Dynamic Programming based C++ implementation to count decodings

565
Chapter 70. Count Possible Decodings of a given Digit Sequence

#include <iostream>
#include <cstring>
using namespace std;
  
// A Dynamic Programming based function to count decodings
int countDecodingDP(char *digits, int n)
{
    int count[n+1]; // A table to store results of subproblems
    count[0] = 1;
    count[1] = 1;
  
    for (int i = 2; i <= n; i++)
    {
        count[i] = 0;
  
        // If the last digit is not 0, then last digit must add to
        // the number of words
        if (digits[i-1] > '0')
            count[i] = count[i-1];
  
        // If second last digit is smaller than 2 and last digit is
        // smaller than 7, then last two digits form a valid character
        if (digits[i-2] == '1' || (digits[i-2] == '2' && digits[i-1] < '7') )
            count[i] += count[i-2];
    }
    return count[n];
}
  
// Driver program to test above function
int main()
{
    char digits[] = "1234";
    int n = strlen(digits);
    cout << "Count is " << countDecodingDP(digits, n);
    return 0;
}

Output:

Count is 3

Time Complexity of the above solution is O(n) and it requires O(n) auxiliary space. We can
reduce auxiliary space to O(1) by using space optimized version discussed in the Fibonacci
Number Post.
Improved By : nitin mittal

566
Chapter 70. Count Possible Decodings of a given Digit Sequence

Source

https://www.geeksforgeeks.org/count-possible-decodings-given-digit-sequence/

567
Chapter 71

Count all increasing


subsequences

Count all increasing subsequences - GeeksforGeeks


We are given an array of digits (values lie in range from 0 to 9). The task is to count all the
sub sequences possible in array such that in each subsequence every digit is greater than its
previous digits in the subsequence.
Examples:

Input : arr[] = {1, 2, 3, 4}


Output: 15
There are total increasing subsequences
{1}, {2}, {3}, {4}, {1,2}, {1,3}, {1,4},
{2,3}, {2,4}, {3,4}, {1,2,3}, {1,2,4},
{1,3,4}, {2,3,4}, {1,2,3,4}

Input : arr[] = {4, 3, 6, 5}


Output: 8
Sub-sequences are {4}, {3}, {6}, {5},
{4,6}, {4,5}, {3,6}, {3,5}

Input : arr[] = {3, 2, 4, 5, 4}


Output : 14
Sub-sequences are {3}, {2}, {4}, {3,4},
{2,4}, {5}, {3,5}, {2,5}, {4,5}, {3,2,5}
{3,4,5}, {4}, {3,4}, {2,4}

Method 1 (Similar to LIS)


A Simple Solution is to use Dynamic Programming Solution of Longest Increasing Subse-
quence (LIS) problem. Like LIS problem, we first compute count of increasing subsequences

568
Chapter 71. Count all increasing subsequences

ending at every index. Finally, we return sum of all values (In LCS problem, we return max
of all values).

// We count all increasing subsequences ending at every


// index i
subCount(i) = Count of increasing subsequences ending
at arr[i].

// Like LCS, this value can be recursively computed


subCount(i) = 1 + &Sum; subCount(j)
where j is index of all elements
such that arr[j] < arr[i] and j < i.
1 is added as every element itself is a subsequence
of size 1.

// Finally we add all counts to get the result.


Result = � subCount(i)
where i varies from 0 to n-1.

Illustration:

For example, arr[] = {3, 2, 4, 5, 4}

// There are no smaller elements on left of arr[0]


// and arr[1]
subCount(0) = 1
subCount(1) = 1

// Note that arr[0] and arr[1] are smaller than arr[2]


subCount(2) = 1 + subCount(0) + subCount(1) = 3

subCount(3) = 1 + subCount(0) + subCount(1) + subCount(2)


= 1 + 1 + 1 + 3
= 6

subCount(3) = 1 + subCount(0) + subCount(1)


= 1 + 1 + 1
= 3

Result = subCount(0) + subCount(1) + subCount(2) + subCount(3)


= 1 + 1 + 3 + 6 + 3
= 14.

Time Complexity : O(n2 )


Auxiliary Space : O(n)

569
Chapter 71. Count all increasing subsequences

Refer this for implementation.

Method 2 (Efficient)
The above solution doesn’t use the fact that we have only 10 possible values in given array.
We can use this fact by using an array count[] such that count[d] stores current count digits
smaller than d.

For example, arr[] = {3, 2, 4, 5, 4}

// We create a count array and initialize it as 0.


count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

// Note that here value is used as index to store counts


count[3] += 1 = 1 // i = 0, arr[0] = 3
count[2] += 1 = 1 // i = 1, arr[0] = 2

// Let us compute count for arr[2] which is 4


count[4] += 1 + count[3] + count[2] += 1 + 1 + 1 = 3

// Let us compute count for arr[3] which is 5


count[5] += 1 + count[3] + count[2] + count[4]
+= 1 + 1 + 1 + 3
= 6

// Let us compute count for arr[4] which is 4


count[4] += 1 + count[0] + count[1]
+= 1 + 1 + 1
+= 3
= 3 + 3
= 6

Note that count[] = {0, 0, 1, 1, 6, 6, 0, 0, 0, 0}


Result = count[0] + count[1] + ... + count[9]
= 1 + 1 + 6 + 6 {count[2] = 1, count[3] = 1
count[4] = 6, count[5] = 6}
= 14.

Below is the implementation of above idea.

C++

// C++ program to count increasing subsequences


// in an array of digits.
#include<bits/stdc++.h>

570
Chapter 71. Count all increasing subsequences

using namespace std;


  
// Function To Count all the sub-sequences
// possible in which digit is greater than
// all previous digits arr[] is array of n
// digits
int countSub(int arr[], int n)
{
    // count[] array is used to store all sub-
    // sequences possible using that digit
    // count[] array covers all the digit
    // from 0 to 9
    int count[10] = {0};
  
    // scan each digit in arr[]
    for (int i=0; i<n; i++)
    {
        // count all possible sub-sequences by
        // the digits less than arr[i] digit
        for (int j=arr[i]-1; j>=0; j--)
            count[arr[i]] += count[j];
  
        // store sum of all sub-sequences plus
        // 1 in count[] array
        count[arr[i]]++;
    }
  
    // now sum up the all sequences possible in
    // count[] array
    int result = 0;
    for (int i=0; i<10; i++)
        result += count[i];
  
    return result;
}
  
// Driver program to run the test case
int main()
{
    int arr[] = {3, 2, 4, 5, 4};
    int n = sizeof(arr)/sizeof(arr[0]);
  
    cout << countSub(arr,n);
    return 0;
}

Java

571
Chapter 71. Count all increasing subsequences

// Java program to count increasing 


// subsequences in an array of digits.
import java.io.*;
  
class GFG {
  
    // Function To Count all the sub-sequences
    // possible in which digit is greater than
    // all previous digits arr[] is array of n
    // digits
    static int countSub(int arr[], int n)
    {
        // count[] array is used to store all
        // sub-sequences possible using that 
        // digit count[] array covers all 
        // the digit from 0 to 9
        int count[] = new int[10];  
  
        // scan each digit in arr[] 
        for (int i = 0; i < n; i++)
        {
            // count all possible sub-
            // sequences by the digits
            // less than arr[i] digit
            for (int j = arr[i] - 1; j >= 0; j--)
                count[arr[i]] += count[j];  
                  
            // store sum of all sub-sequences 
            // plus 1 in count[] array
            count[arr[i]]++;
        }   
  
        // now sum up the all sequences
        // possible in count[] array
        int result = 0;
        for (int i = 0; i < 10; i++)
            result += count[i];
  
        return result;
    }
  
    // Driver program to run the test case
    public static void main(String[] args)
    {
        int arr[] = {3, 2, 4, 5, 4};
        int n = arr.length;
  
        System.out.println(countSub(arr,n));

572
Chapter 71. Count all increasing subsequences

    }
}
// This code is contributed by Prerna Saini

Python3

   
# Python3 program to count increasing 
# subsequences in an array of digits.
  
# Function To Count all the sub-
# sequences possible in which digit
# is greater than all previous digits
# arr[] is array of n digits
def countSub(arr, n):
  
    # count[] array is used to store all 
    # sub-sequences possible using that 
    # digit count[] array covers all the 
    # digit from 0 to 9
    count = [0 for i in range(10)]
  
    # scan each digit in arr[]
    for i in range(n):
      
        # count all possible sub-sequences by
        # the digits less than arr[i] digit
        for j in range(arr[i] - 1, -1, -1):
            count[arr[i]] += count[j]
  
        # store sum of all sub-sequences 
        # plus 1 in count[] array
        count[arr[i]] += 1
      
  
    # Now sum up the all sequences 
    # possible in count[] array
    result = 0
    for i in range(10):
        result += count[i]
  
    return result
  
# Driver Code
arr = [3, 2, 4, 5, 4]
n = len(arr)
print(countSub(arr, n))
  

573
Chapter 71. Count all increasing subsequences

# This code is contributed by Anant Agarwal.

C#

// C# program to count increasing 


// subsequences in an array of digits.
using System;
class GFG {
  
    // Function To Count all the sub-sequences
    // possible in which digit is greater than
    // all previous digits arr[] is array of n
    // digits
    static int countSub(int []arr, int n)
    {
        // count[] array is used to store all
        // sub-sequences possible using that 
        // digit count[] array covers all 
        // the digit from 0 to 9
        int []count = new int[10];  
  
        // scan each digit in arr[] 
        for (int i = 0; i < n; i++)
        {
            // count all possible sub-
            // sequences by the digits
            // less than arr[i] digit
            for (int j = arr[i] - 1; j >= 0; j--)
                count[arr[i]] += count[j];  
                  
            // store sum of all sub-sequences 
            // plus 1 in count[] array
            count[arr[i]]++;
        }   
  
        // now sum up the all sequences
        // possible in count[] array
        int result = 0;
        for (int i = 0; i < 10; i++)
            result += count[i];
  
        return result;
    }
  
    // Driver program 
    public static void Main()
    {
        int []arr = {3, 2, 4, 5, 4};

574
Chapter 71. Count all increasing subsequences

        int n = arr.Length;
  
        Console.WriteLine(countSub(arr,n));
    }
}
// This code is contributed by Anant Agarwal.

Output:

14

Time Complexity : O(n) Note that the inner loop runs at most 10 times.
Auxiliary Space : O(1) Note that count has at-most 10 elements.

Source

https://www.geeksforgeeks.org/count-all-increasing-subsequences/

575
Chapter 72

Count all possible paths from


top left to bottom right of a
mXn matrix

Count all possible paths from top left to bottom right of a mXn matrix - GeeksforGeeks
The problem is to count all the possible paths from top left to bottom right of a mXn matrix
with the constraints that from each cell you can either move only to right or down
Examples :

Input : m = 2, n = 2;
Output : 2
There are two paths
(0, 0) -> (0, 1) -> (1, 1)
(0, 0) -> (1, 0) -> (1, 1)

Input : m = 2, n = 3;
Output : 3
There are three paths
(0, 0) -> (0, 1) -> (0, 2) -> (1, 2)
(0, 0) -> (0, 1) -> (1, 1) -> (1, 2)
(0, 0) -> (1, 0) -> (1, 1) -> (1, 2)

We have discussed a solution to print all possible paths, counting all paths is easier. Let
NumberOfPaths(m, n) be the count of paths to reach row number m and column number n
in the matrix, NumberOfPaths(m, n) can be recursively written as following.
C++

#include <iostream>

576
Chapter 72. Count all possible paths from top left to bottom right of a mXn matrix

using namespace std;


  
// Returns count of possible paths to reach cell at row 
// number m and column  number n from the topmost leftmost 
// cell (cell at 1, 1)
int  numberOfPaths(int m, int n)
{
   // If either given row number is first or given column 
   // number is first
   if (m == 1 || n == 1)
        return 1;
  
   // If diagonal movements are allowed then the last 
   // addition is required.
   return  numberOfPaths(m-1, n) + numberOfPaths(m, n-1);
           // + numberOfPaths(m-1,n-1);
}
  
int main()
{
    cout << numberOfPaths(3, 3);
    return 0;
}

Java

// A Java program to count all possible paths 


// from top left to bottom right
  
class GFG
{
      
    // Returns count of possible paths to reach 
    // cell at row number m and column number n 
    // from the topmost leftmost cell (cell at 1, 1)
    static int  numberOfPaths(int m, int n)
    {
        // If either given row number is first or 
        // given column number is first
        if (m == 1 || n == 1)
            return 1;
   
        // If diagonal movements are allowed then 
        // the last addition is required.
        return  numberOfPaths(m-1, n) + numberOfPaths(m, n-1);
                // + numberOfPaths(m-1,n-1);
    }
   

577
Chapter 72. Count all possible paths from top left to bottom right of a mXn matrix

    public static void main(String args[])


    {
       System.out.println(numberOfPaths(3, 3));
    }
}
  
// This code is contributed by Sumit Ghosh

Python

# Python program to count all possible paths 


# from top left to bottom right
   
# function to return count of possible paths
# to reach cell at row number m and column
# number n from the topmost leftmost
# cell (cell at 1, 1)
def numberOfPaths(m, n):
   # If either given row number is first
   # or given column number is first
   if(m == 1 or n == 1):
        return 1
    
   # If diagonal movements are allowed
   # then the last addition
   # is required.
   return  numberOfPaths(m-1, n) + numberOfPaths(m, n-1)
  
# Driver program to test above function  
m = 3
n = 3
print(numberOfPaths(m, n))
  
# This code is contributed by Aditi Sharma

Output:

The time complexity of above recursive solution is exponential. There are many overlap-
ping subproblems. We can draw a recursion tree for numberOfPaths(3, 3) and see many
overlapping subproblems. The recursion tree would be similar to Recursion tree for Longest
Common Subsequence problem.
So this problem has both properties (see this and this) of a dynamic programming problem.

578
Chapter 72. Count all possible paths from top left to bottom right of a mXn matrix

Like other typical Dynamic Programming(DP) problems, recomputations of same subprob-


lems can be avoided by constructing a temporary array count[][] in bottom up manner using
the above recursive formula.
C

#include <iostream>
using namespace std;
  
// Returns count of possible paths to reach cell at
// row number m and column  number n from the topmost 
// leftmost cell (cell at 1, 1)
int numberOfPaths(int m, int n)
{
    // Create a 2D table to store results of subproblems
    int count[m][n];
  
    // Count of paths to reach any cell in first column is 1
    for (int i = 0; i < m; i++)
        count[i][0] = 1;
  
    // Count of paths to reach any cell in first column is 1
    for (int j = 0; j < n; j++)
        count[0][j] = 1;
  
    // Calculate count of paths for other cells in 
    // bottom-up manner using the recursive solution
    for (int i = 1; i < m; i++)
    {
        for (int j = 1; j < n; j++)
  
            // By uncommenting the last part the code calculatest he total
            // possible paths if the diagonal Movements are allowed
            count[i][j] = count[i-1][j] + count[i][j-1]; //+ count[i-1][j-1];
  
    }
    return count[m-1][n-1];
}
  
// Driver program to test above functions
int main()
{
    cout << numberOfPaths(3, 3);
    return 0;
}

Java

// A Java program to count all possible paths 

579
Chapter 72. Count all possible paths from top left to bottom right of a mXn matrix

// from top left to bottom right


class GFG 
{
    // Returns count of possible paths to reach 
    // cell at row number m and column number n from
    //  the topmost leftmost cell (cell at 1, 1)
    static int numberOfPaths(int m, int n)
    {
        // Create a 2D table to store results 
        // of subproblems
        int count[][] = new int[m][n];
   
        // Count of paths to reach any cell in 
        // first column is 1
        for (int i = 0; i < m; i++)
            count[i][0] = 1;
   
        // Count of paths to reach any cell in
        // first column is 1
        for (int j = 0; j < n; j++)
            count[0][j] = 1;
   
        // Calculate count of paths for other 
        // cells in bottom-up manner using
        // the recursive solution
        for (int i = 1; i < m; i++)
        {
            for (int j = 1; j < n; j++)
   
            // By uncommenting the last part the 
            // code calculatest he total possible paths 
            // if the diagonal Movements are allowed
            count[i][j] = count[i-1][j] + count[i][j-1]; //+ count[i-1][j-1];
   
        }
        return count[m-1][n-1];
    }
   
    // Driver program to test above function
    public static void main(String args[])
    {
        System.out.println(numberOfPaths(3, 3));
    }
}
  
// This code is contributed by Sumit Ghosh

Python

580
Chapter 72. Count all possible paths from top left to bottom right of a mXn matrix

# Python program to count all possible paths 


# from top left to bottom right
  
# Returns count of possible paths to reach cell 
# at row number m and column number n from the 
# topmost leftmost cell (cell at 1, 1)
def numberOfPaths(m, n):
    # Create a 2D table to store
    # results of subproblems
    count = [[0 for x in range(m)] for y in range(n)]
    
    # Count of paths to reach any 
    # cell in first column is 1
    for i in range(m):
        count[i][0] = 1;
    
    # Count of paths to reach any 
    # cell in first column is 1
    for j in range(n):
        count[0][j] = 1;
    
    # Calculate count of paths for other
    # cells in bottom-up 
    # manner using the recursive solution
    for i in range(1, m):
        for j in range(n):             
            count[i][j] = count[i-1][j] + count[i][j-1]
    return count[m-1][n-1]
  
# Driver program to test above function 
m = 3
n = 3
print( numberOfPaths(m, n))
  
# This code is contributed by Aditi Sharma

Output:

Time complexity of the above dynamic programming solution is O(mn).


The space complexity of the above solution is O(mn).
Space Optimization of DP solution.
Above solution is more intuitive but we can also reduce the space by O(n); where n is column
size.
Java

581
Chapter 72. Count all possible paths from top left to bottom right of a mXn matrix

class GFG 
{
    // Returns count of possible paths to reach 
    // cell at row number m and column number n from
    // the topmost leftmost cell (cell at 1, 1)
    static int numberOfPaths(int m, int n)
    {
        // Create a 1D array to store results of subproblems
        int[] dp = new int[n];
        dp[0] = 1;
  
        for (int i = 0; i < m; i++) {
          for (int j = 1; j < n; j++) {
            dp[j] += dp[j - 1];
          }
        }
  
        return dp[n - 1];
    }
   
    // Driver program to test above function
    public static void main(String args[])
    {
        System.out.println(numberOfPaths(3, 3));
    }
}

Output:

This code is contributed by Vivek Singh


Note the count can also be calculated using the formula (m-1 + n-1)!/(m-1)!(n-1)!.
This article is contributed by Hariprasad NG. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : viveksingh14

Source

https://www.geeksforgeeks.org/count-possible-paths-top-left-bottom-right-nxm-matrix/

582
Chapter 73

Count all possible walks from a


source to a destination with
exactly k edges

Count all possible walks from a source to a destination with exactly k edges - GeeksforGeeks
Given a directed graph and two vertices ‘u’ and ‘v’ in it, count all possible walks from ‘u’
to ‘v’ with exactly k edges on the walk.
The graph is given as adjacency matrix representation where value of graph[i][j] as 1 indicates
that there is an edge from vertex i to vertex j and a value 0 indicates no edge from i to j.
For example consider the following graph. Let source ‘u’ be vertex 0, destination ‘v’ be 3
and k be 2. The output should be 2 as there are two walk from 0 to 3 with exactly 2 edges.
The walks are {0, 2, 3} and {0, 1, 3}

A simple solution is to start from u, go to all adjacent vertices and recur for adjacent

583
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

vertices with k as k-1, source as adjacent vertex and destination as v. Following is the
implementation of this simple solution.

C++

// C++ program to count walks from u to v with exactly k edges


#include <iostream>
using namespace std;
  
// Number of vertices in the graph
#define V 4
  
// A naive recursive function to count walks from u to v with k edges
int countwalks(int graph[][V], int u, int v, int k)
{
   // Base cases
   if (k == 0 && u == v)      return 1;
   if (k == 1 && graph[u][v]) return 1;
   if (k <= 0)                return 0;
  
   // Initialize result
   int count = 0;
  
   // Go to all adjacents of u and recur
   for (int i = 0; i < V; i++)
       if (graph[u][i] == 1)  // Check if is adjacent of u
           count += countwalks(graph, i, v, k-1);
  
   return count;
}
  
// driver program to test above function
int main()
{
    /* Let us create the graph shown in above diagram*/
     int graph[V][V] = { {0, 1, 1, 1},
                        {0, 0, 0, 1},
                        {0, 0, 0, 1},
                        {0, 0, 0, 0}
                      };
    int u = 0, v = 3, k = 2;
    cout << countwalks(graph, u, v, k);
    return 0;
}

Java

// Java program to count walks from u to v with exactly k edges

584
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

import java.util.*;
import java.lang.*;
import java.io.*;
  
class KPaths
{
    static final int V = 4; //Number of vertices
  
    // A naive recursive function to count walks from u
    // to v with k edges
    int countwalks(int graph[][], int u, int v, int k)
    {
        // Base cases
        if (k == 0 && u == v)           return 1;
        if (k == 1 && graph[u][v] == 1) return 1;
        if (k <= 0)                     return 0;
  
        // Initialize result
        int count = 0;
  
        // Go to all adjacents of u and recur
        for (int i = 0; i < V; i++)
            if (graph[u][i] == 1)  // Check if is adjacent of u
                count += countwalks(graph, i, v, k-1);
  
        return count;
    }
  
    // Driver method
    public static void main (String[] args) throws java.lang.Exception
    {
        /* Let us create the graph shown in above diagram*/
        int graph[][] =new int[][] { {0, 1, 1, 1},
            {0, 0, 0, 1},
            {0, 0, 0, 1},
            {0, 0, 0, 0}
        };
        int u = 0, v = 3, k = 2;
        KPaths p = new KPaths();
        System.out.println(p.countwalks(graph, u, v, k));
    }
}//Contributed by Aakash Hasija

Python3

# Python3 program to count walks from


# u to v with exactly k edges
  

585
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

# Number of vertices in the graph


V = 4
  
# A naive recursive function to count
# walks from u to v with k edges
def countwalks(graph, u, v, k):
  
    # Base cases
    if (k == 0 and u == v):
        return 1
    if (k == 1 and graph[u][v]):
        return 1
    if (k <= 0):
        return 0
      
    # Initialize result
    count = 0
      
    # Go to all adjacents of u and recur
    for i in range(0, V):
          
        # Check if is adjacent of u
        if (graph[u][i] == 1): 
            count += countwalks(graph, i, v, k-1)
      
    return count
  
# Driver Code
  
# Let us create the graph shown in above diagram
graph = [[0, 1, 1, 1,],
         [0, 0, 0, 1,],
         [0, 0, 0, 1,],
         [0, 0, 0, 0] ]
  
u = 0; v = 3; k = 2
print(countwalks(graph, u, v, k))
  
# This code is contributed by Smitha Dinesh Semwal.

C#

// C# program to count walks from u to


// v with exactly k edges
using System;
  
class GFG {
      

586
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

    // Number of vertices


    static int V = 4;
  
    // A naive recursive function to 
    // count walks from u to v with 
    // k edges
    static int countwalks(int [,]graph, int u,
                                 int v, int k)
    {
          
        // Base cases
        if (k == 0 && u == v)
            return 1;
        if (k == 1 && graph[u,v] == 1)
            return 1;
        if (k <= 0)                    
            return 0;
  
        // Initialize result
        int count = 0;
  
        // Go to all adjacents of u and recur
        for (int i = 0; i < V; i++)
          
            // Check if is adjacent of u
            if (graph[u,i] == 1) 
                count += 
                countwalks(graph, i, v, k-1);
  
        return count;
    }
  
    // Driver method
    public static void Main () 
    {
          
        /* Let us create the graph shown 
        in above diagram*/
        int [,]graph =
           new int[,] { {0, 1, 1, 1},
                        {0, 0, 0, 1},
                        {0, 0, 0, 1},
                        {0, 0, 0, 0} };
                          
        int u = 0, v = 3, k = 2;
          
        Console.Write(
             countwalks(graph, u, v, k));

587
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to count walks from u
// to v with exactly k edges
  
// Number of vertices in the graph
$V = 4;
  
// A naive recursive function to count
// walks from u to v with k edges
function countwalks( $graph, $u, $v, $k)
{
    global $V;
  
    // Base cases
    if ($k == 0 and $u == $v) 
        return 1;
    if ($k == 1 and $graph[$u][$v])
        return 1;
    if ($k <= 0)         
        return 0;
      
    // Initialize result
    $count = 0;
      
    // Go to all adjacents of u and recur
    for ( $i = 0; $i < $V; $i++)
      
        // Check if is adjacent of u
        if ($graph[$u][$i] == 1) 
            $count += countwalks($graph, $i, 
                                $v, $k - 1);
      
    return $count;
}
  
    // Driver Code
    /* Let us create the graph 
       shown in above diagram*/
    $graph = array(array(0, 1, 1, 1),
                   array(0, 0, 0, 1),
                   array(0, 0, 0, 1),

588
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

                   array(0, 0, 0, 0));
    $u = 0; $v = 3; $k = 2;
    echo countwalks($graph, $u, $v, $k);
  
// This code is contributed by anuj_67.
?>

Output:

The worst case time complexity of the above function is O(Vk ) where V is the number of
vertices in the given graph. We can simply analyze the time complexity by drawing recursion
tree. The worst occurs for a complete graph. In worst case, every internal node of recursion
tree would have exactly n children.
We can optimize the above solution using Dynamic Programming. The idea is to build
a 3D table where first dimension is source, second dimension is destination, third dimension
is number of edges from source to destination, and the value is count of walks. Like other
Dynamic Programming problems, we fill the 3D table in bottom up manner.
C++

// C++ program to count walks from u to v with exactly k edges


#include <iostream>
using namespace std;
  
// Number of vertices in the graph
#define V 4
  
// A Dynamic programming based function to count walks from u
// to v with k edges
int countwalks(int graph[][V], int u, int v, int k)
{
    // Table to be filled up using DP. The value count[i][j][e] will
    // store count of possible walks from i to j with exactly k edges
    int count[V][V][k+1];
  
    // Loop for number of edges from 0 to k
    for (int e = 0; e <= k; e++)
    {
        for (int i = 0; i < V; i++)  // for source
        {
            for (int j = 0; j < V; j++) // for destination
            {
                // initialize value
                count[i][j][e] = 0;
  
                // from base cases

589
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

                if (e == 0 && i == j)
                    count[i][j][e] = 1;
                if (e == 1 && graph[i][j])
                    count[i][j][e] = 1;
  
                // go to adjacent only when number of edges is more than 1
                if (e > 1)
                {
                    for (int a = 0; a < V; a++) // adjacent of source i
                        if (graph[i][a])
                            count[i][j][e] += count[a][j][e-1];
                }
           }
        }
    }
    return count[u][v][k];
}
  
// driver program to test above function
int main()
{
    /* Let us create the graph shown in above diagram*/
     int graph[V][V] = { {0, 1, 1, 1},
                        {0, 0, 0, 1},
                        {0, 0, 0, 1},
                        {0, 0, 0, 0}
                      };
    int u = 0, v = 3, k = 2;
    cout << countwalks(graph, u, v, k);
    return 0;
}

Java

// Java program to count walks from u to v with exactly k edges


import java.util.*;
import java.lang.*;
import java.io.*;
  
class KPaths
{
    static final int V = 4; //Number of vertices
  
    // A Dynamic programming based function to count walks from u
    // to v with k edges
    int countwalks(int graph[][], int u, int v, int k)
    {
        // Table to be filled up using DP. The value count[i][j][e]

590
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

        // will/ store count of possible walks from i to j with


        // exactly k edges
        int count[][][] = new int[V][V][k+1];
  
        // Loop for number of edges from 0 to k
        for (int e = 0; e <= k; e++)
        {
            for (int i = 0; i < V; i++)  // for source
            {
                for (int j = 0; j < V; j++) // for destination
                {
                    // initialize value
                    count[i][j][e] = 0;
  
                    // from base cases
                    if (e == 0 && i == j)
                        count[i][j][e] = 1;
                    if (e == 1 && graph[i][j]!=0)
                        count[i][j][e] = 1;
  
                    // go to adjacent only when number of edges
                    // is more than 1
                    if (e > 1)
                    {
                        for (int a = 0; a < V; a++) // adjacent of i
                            if (graph[i][a]!=0)
                                count[i][j][e] += count[a][j][e-1];
                    }
               }
            }
        }
        return count[u][v][k];
    }
  
    // Driver method
    public static void main (String[] args) throws java.lang.Exception
    {
        /* Let us create the graph shown in above diagram*/
        int graph[][] =new int[][] { {0, 1, 1, 1},
                                     {0, 0, 0, 1},
                                     {0, 0, 0, 1},
                                     {0, 0, 0, 0}
                                    };
        int u = 0, v = 3, k = 2;
        KPaths p = new KPaths();
        System.out.println(p.countwalks(graph, u, v, k));
    }
}//Contributed by Aakash Hasija

591
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

C#

// C# program to count walks from u to v 


// with exactly k edges
using System;
  
class GFG {
    static int V = 4; //Number of vertices
  
    // A Dynamic programming based function
    // to count walks from u to v with k edges
    static int countwalks(int [,]graph, int u,
                                 int v, int k)
    {
        // Table to be filled up using DP. The
        // value count[i][j][e] will/ store 
        // count of possible walks from i to 
        // j with exactly k edges
        int [, ,]count = new int[V,V,k+1];
  
        // Loop for number of edges from 0 to k
        for (int e = 0; e <= k; e++)
        {
              
            // for source
            for (int i = 0; i < V; i++) 
            {
                  
                // for destination
                for (int j = 0; j < V; j++) 
                {
                    // initialize value
                    count[i,j,e] = 0;
  
                    // from base cases
                    if (e == 0 && i == j)
                        count[i,j,e] = 1;
                    if (e == 1 && graph[i,j] != 0)
                        count[i,j,e] = 1;
  
                    // go to adjacent only when
                    // number of edges
                    // is more than 1
                    if (e > 1)
                    {
                        // adjacent of i
                        for (int a = 0; a < V; a++)
                            if (graph[i,a]!=0)

592
Chapter 73. Count all possible walks from a source to a destination with exactly k edges

                                count[i,j,e] +=
                                     count[a,j,e-1];
                    }
                }
            }
        }
          
        return count[u,v,k];
    }
  
    // Driver method
    public static void Main () 
    {
        /* Let us create the graph shown in 
        above diagram*/
        int [,]graph = { {0, 1, 1, 1},
                         {0, 0, 0, 1},
                         {0, 0, 0, 1},
                         {0, 0, 0, 0} };
        int u = 0, v = 3, k = 2;
          
        Console.WriteLine(
              countwalks(graph, u, v, k));
    }
}
  
// This is Code Contributed by anuj_67.

Output:

Time complexity of the above DP based solution is O(V3 K) which is much better than the
naive solution.
We can also use Divide and Conquer to solve the above problem in O(V3 Logk) time.
The count of walks of length k from u to v is the [u][v]’th entry in (graph[V][V])k . We
can calculate power of by doing O(Logk) multiplication by using the divide and conquer
technique to calculate power. A multiplication between two matrices of size V x V takes
O(V3 ) time. Therefore overall time complexity of this method is O(V3 Logk).
Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/count-possible-paths-source-destination-exactly-k-edges/

593
Chapter 74

Count all subsequences having


product less than K

Count all subsequences having product less than K - GeeksforGeeks


Given a non negative array, find the number of subsequences having product smaller than
K.
Examples:

Input : [1, 2, 3, 4]
k = 10
Output :11
The subsequences are {1}, {2}, {3}, {4},
{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4},
{1, 2, 3}, {1, 2, 4}

Input : [4, 8, 7, 2]
k = 50
Output : 9

This problem can be solved using dynamic programming where dp[i][j] = number of
subsequences having product less than i using first j terms of the array. Which can be
obtained by : number of subsequences using first j-1 terms + number of subsequences that
can be formed using j-th term.

C++

// CPP program to find number of subarrays having


// product less than k.
#include <bits/stdc++.h>

594
Chapter 74. Count all subsequences having product less than K

using namespace std;


  
// Function to count numbers of such subsequences
// having product less than k.
int productSubSeqCount(vector<int> &arr, int k)
{
    int n = arr.size();
    int dp[k + 1][n + 1];
    memset(dp, 0, sizeof(dp));
  
    for (int i = 1; i <= k; i++) {
        for (int j = 1; j <= n; j++) {
     
            // number of subsequence using j-1 terms
            dp[i][j] = dp[i][j - 1];
    
            // if arr[j-1] > i it will surely make product greater
            // thus it won't contribute then
            if (arr[j - 1] <= i && arr[j - 1] > 0)
  
                // number of subsequence using 1 to j-1 terms
                // and j-th term
                dp[i][j] += dp[i/arr[j-1]][j-1] + 1;
        }
    }
    return dp[k][n];
}
  
// Driver code
int main()
{
    vector<int> A;
    A.push_back(1);
    A.push_back(2);
    A.push_back(3);
    A.push_back(4);
    int k = 10;
    cout << productSubSeqCount(A, k) << endl;
}

Java

// Java program to find number of subarrays 


// having product less than k.
import java.util.*;
class CountSubsequences
{
    // Function to count numbers of such 

595
Chapter 74. Count all subsequences having product less than K

    // subsequences having product less than k.


    public static int productSubSeqCount(ArrayList<Integer> arr,
                                                 int k)
    {
        int n = arr.size();
        int dp[][]=new int[k + 1][n + 1];
          
        for (int i = 1; i <= k; i++) {
            for (int j = 1; j <= n; j++) {
          
                // number of subsequence using j-1 terms
                dp[i][j] = dp[i][j - 1];
          
                // if arr[j-1] > i it will surely make 
                // product greater thus it won't contribute
                // then
                if (arr.get(j-1) <= i && arr.get(j-1) > 0)
      
                    // number of subsequence using 1 to j-1
                    // terms and j-th term
                    dp[i][j] += dp[i/arr.get(j - 1)][j - 1] + 1;
            }
        }
        return dp[k][n];
    }
      
    // Driver code
    public static void main(String args[])
    {
        ArrayList<Integer> A = new ArrayList<Integer>();
        A.add(1);
        A.add(2);
        A.add(3);
        A.add(4);
        int k = 10;
        System.out.println(productSubSeqCount(A, k));
    }
}
  
// This Code is contributed by Danish Kaleem

Python

# Python program to find 


# number of subarrays having 
# product less than k. 
def productSubSeqCount(arr, k):
    n = len(arr)

596
Chapter 74. Count all subsequences having product less than K

    dp = [[0 for i in range(n + 1)]


             for j in range(k + 1)]
    for i in range(1, k + 1):
        for j in range(1, n + 1):
              
            # number of subsequence
            # using j-1 terms 
            dp[i][j] = dp[i][j - 1]
              
            # if arr[j-1] > i it will 
            # surely make product greater
            # thus it won't contribute then 
            if arr[j - 1] <= i and arr[j - 1] > 0:
                  
                # number of subsequence
                # using 1 to j-1 terms
                # and j-th term
                dp[i][j] += dp[i // arr[j - 1]][j - 1] + 1
    return dp[k][n]
  
# Driver code 
A = [1,2,3,4]
k = 10
print(productSubSeqCount(A, k))
  
# This code is contributed 
# by pk_tautolo

Output:

11

Improved By : pk_tautolo

Source

https://www.geeksforgeeks.org/count-subsequences-product-less-k/

597
Chapter 75

Count all triplets whose sum is


equal to a perfect cube

Count all triplets whose sum is equal to a perfect cube - GeeksforGeeks


Given an array of n integers, count all different triplets whose sum is equal to the perfect
cube i.e, for any i, j, k(i < j < k) satisfying the condition that a[i] + a[j] + a[j] = X3 where
X is any integer. 3 � n � 1000, 1 � a[i, j, k] � 5000

Input:
N = 5
2 5 1 20 6
Output:
3
Explanation:
There are only 3 triplets whose total sum is a perfect cube.
Indices Values SUM
0 1 2 2 5 1 8
0 1 3 2 5 20 27
2 3 4 1 20 6 27
Since 8 and 27 are prefect cube of 2 and 3.

Naive appraoch is to iterate over all the possible numbers by using 3 nested loops and
check whether their sum is perfect cube or not. The approach would be very slow as time
complexity can go up to O(n3 ).
An Efficient approach is to use dynamic programming and basic mathematics. According
to given condition sum of any of three positive integer is not greater than 15000. Therefore
there can be only 24(150001/3 ) cubes are possible in the range of 1 to 15000.
Now instead of iterating all triplets we can do much better by the help of above information.
Fixed first two indices i and j such that instead of iterating over all k(j < k � n), we can

598
Chapter 75. Count all triplets whose sum is equal to a perfect cube

iterate over all the 24 possible cubes, and for each one, (let’s say P) check how many
occurrence of P – (a[i] + a[j]) are in a[j+1, j+2, … n].
But if we compute the number of occurance of a number say K in a[j+1, j+2, … n] then
this would again be counted as slow approch and would definitely give TLE. So we have to
think a different approach.
Now here comes to a Dynamic Programming. Since all numbers are smaller than 5000 and
n is at most 1000. Hence we can compute a DP array as,
dp[i][K]:= Number of occurance of K in A[i, i+1, i+2 … n]

C++

// C++ program to calculate all triplets whose


// sum is perfect cube.
#include <bits/stdc++.h>
using namespace std;
  
int dp[1001][15001];
  
// Function to calculate all occurrence of
// a number in a given range
void computeDpArray(int arr[], int n)
{
    for (int i = 0; i < n; ++i) {
        for (int j = 1; j <= 15000; ++j) {
  
            // if i == 0
            // assign 1 to present state
            if (i == 0)
                dp[i][j] = (j == arr[i]);
  
            // else add +1 to current state with
            // previous state
            else
                dp[i][j] = dp[i - 1][j] + (arr[i] == j);
        }
    }
}
  
// Function to calculate triplets whose sum
// is equal to the pefect cube
int countTripletSum(int arr[], int n)
{
    computeDpArray(arr, n);
     
    int ans = 0;  // Initialize answer
    for (int i = 0; i < n - 2; ++i) {
        for (int j = i + 1; j < n - 1; ++j) {
            for (int k = 1; k <= 24; ++k) {

599
Chapter 75. Count all triplets whose sum is equal to a perfect cube

                int cube = k * k * k;
  
                int rem = cube - (arr[i] + arr[j]);
  
                // count all occurrence of third triplet
                // in range from j+1 to n
                if (rem > 0)
                    ans += dp[n - 1][rem] - dp[j][rem];
            }
        }
    }
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { 2, 5, 1, 20, 6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << countTripletSum(arr, n);
  
    return 0;
}

Java

// JAVA Code for Count all triplets whose


// sum is equal to a perfect cube
import java.util.*;
  
class GFG {
      
    public static int dp[][];
      
    // Function to calculate all occurrence of
    // a number in a given range
    public static void computeDpArray(int arr[], int n)
    {
        for (int i = 0; i < n; ++i) {
            for (int j = 1; j <= 15000; ++j) {
       
                // if i == 0
                // assign 1 to present state
                  
                if (i == 0 && j == arr[i])
                    dp[i][j] = 1;
                else if(i==0)
                     dp[i][j] = 0;

600
Chapter 75. Count all triplets whose sum is equal to a perfect cube

  
                // else add +1 to current state 
                // with previous state
                else if(arr[i] == j)
                    dp[i][j] = dp[i - 1][j] + 1;
                else
                    dp[i][j] = dp[i - 1][j];
            }
        }
    }
       
    // Function to calculate triplets whose sum
    // is equal to the pefect cube
    public static int countTripletSum(int arr[], int n)
    {
        computeDpArray(arr, n);
          
        int ans = 0;  // Initialize answer
        for (int i = 0; i < n - 2; ++i) {
            for (int j = i + 1; j < n - 1; ++j) {
                for (int k = 1; k <= 24; ++k) {
                    int cube = k * k * k;
       
                    int rem = cube - (arr[i] + arr[j]);
       
                    // count all occurrence of 
                    // third triplet in range 
                    // from j+1 to n
                    if (rem > 0)
                        ans += dp[n - 1][rem] - dp[j][rem];
                }
            }
        }
        return ans;
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int arr[] = { 2, 5, 1, 20, 6 };
        int n = arr.length;
        dp = new int[1001][15001];
          
        System.out.println(countTripletSum(arr, n));
        
    }
}
      

601
Chapter 75. Count all triplets whose sum is equal to a perfect cube

// This code is contributed by Arnav Kr. Mandal.    

Output:

Time complexity: O(N2 *24)


Auxiliary space: O(107 )

Source

https://www.geeksforgeeks.org/count-triplets-whose-sum-equal-perfect-cube/

602
Chapter 76

Count binary strings with k


times appearing adjacent two
set bits

Count binary strings with k times appearing adjacent two set bits - GeeksforGeeks
Given two integers n and k, count the number of binary strings of length n with k as number
of times adjacent 1’s appear.
Examples:

Input : n = 5, k = 2
Output : 6
Explanation:
Binary strings of length 5 in which k number of times
two adjacent set bits appear.
00111
01110
11100
11011
10111
11101

Input : n = 4, k = 1
Output : 3
Explanation:
Binary strings of length 3 in which k number of times
two adjacent set bits appear.
0011
1100
0110

603
Chapter 76. Count binary strings with k times appearing adjacent two set bits

Lets try writing the recursive function for the above problem statement:
1) n = 1, only two binary strings exist with length 1, not having any adjacent 1’s
String 1 : “0”
String 2 : “1”
2) For all n > 1 and all k, two cases arise
a) Strings ending with 0 : String of length n can be created by appending 0 to all
strings of length n-1 having k times two adjacent 1’s ending with both 0 and 1
(Having 0 at n’th position will not change the count of adjacent 1’s).
b) Strings ending with 1 : String of length n can be created by appending 1 to all strings
of length n-1 having k times adjacent 1’s and ending with 0 and to all strings of
length n-1 having k-1 adjacent 1’s and ending with 1.
Example: let s = 011 i.e. a string ending with 1 having adjacent count as 1. Adding 1 to it,
s = 0111 increase the count of adjacent 1.

Let there be an array dp[i][j][2] where dp[i][j][0]


denotes number of binary strings with length i having
j number of two adjacent 1's and ending with 0.
Similarly dp[i][j][1] denotes the same binary strings
with length i and j adjacent 1's but ending with 1.
Then:
dp[1][0][0] = 1 and dp[1][0][1] = 1
For all other i and j,
dp[i][j][0] = dp[i-1][j][0] + dp[i-1][j][1]
dp[i][j][1] = dp[i-1][j][0] + dp[i-1][j-1][1]

Then, output dp[n][k][0] + dp[n][k][1]

// C++ program to count number of binary strings


// with k times appearing consecutive 1's.
#include<bits/stdc++.h>
using namespace std;
  
int countStrings(int n, int k)
{
    // dp[i][j][0] stores count of binary
    // strings of length i with j consecutive
    // 1's and ending at 0.
    // dp[i][j][1] stores count of binary
    // strings of length i with j consecutive
    // 1's and ending at 1.
    int dp[n+1][k+1][2];
    memset(dp, 0, sizeof(dp));
  
    // If n = 1 and k = 0. 
    dp[1][0][0] = 1;
    dp[1][0][1] = 1;

604
Chapter 76. Count binary strings with k times appearing adjacent two set bits

  
    for (int i=2; i<=n; i++)
    {
        // number of adjacent 1's can not exceed i-1
        for (int j=0; j<i; j++)
        {
            dp[i][j][0] = dp[i-1][j][0] + dp[i-1][j][1];
            dp[i][j][1] = dp[i-1][j][0];
  
            if (j-1 >= 0)
                dp[i][j][1] += dp[i-1][j-1][1];
        }
    }
  
    return dp[n][k][0] + dp[n][k][1];
}
  
// Driver code
int main()
{
    int n=5, k=2;
    cout << countStrings(n, k);
    return 0;
}

Output:

Time Complexity : O(n2 )

Source

https://www.geeksforgeeks.org/count-binary-strings-k-times-appearing-adjacent-two-set-bits/

605
Chapter 77

Count digit groupings of a


number with given constraints

Count digit groupings of a number with given constraints - GeeksforGeeks


We are given a string consisting of digits, we may group these digits into sub-groups (but
maintaining their original order). The task is to count number of groupings such that for
every sub-group except the last one, sum of digits in a sub-group is less than or equal to
sum of the digits in the sub-group immediately on its right.
For example, a valid grouping of digits of number 1119 is (1-11-9). Sum of digits in first
subgroup is 1, next subgroup is 2, and last subgroup is 9. Sum of every subgroup is less
than or equal to its immediate right.

Examples :

Input : "1119"
Output: 7
Sub-groups: [1-119], [1-1-19], [1-11-9], [1-1-1-9],
[11-19] and [111-9].
Note : Here we have included [1119] in the group and
sum of digits is 12 and this group has no
immediate right.

Input : "1234"
Output: 6
Sub-groups : [1234], [1-234], [12-34], [1-2-3-4],
[12-3-4] and [1-2-34]

Let “length” be the length of input number. A recursive solution is to consider every position
from 0 length-1. For every position, recursively count all possible subgroups after it. Below
is C++ implementation of naive recursive solution.

606
Chapter 77. Count digit groupings of a number with given constraints

C++

// C++ program to count number of 


// ways to group digits of a number 
// such that sum of digits in every 
// subgroup is less than or equal to
// its immediate right subgroup.
#include<bits/stdc++.h>
using namespace std;
  
// Function to find the subgroups
int countGroups(int position, 
                int previous_sum, 
                int length, char *num)
{
    // Terminating Condition
    if (position == length)
        return 1;
  
    int res = 0;
      
    // sum of digits
    int sum = 0; 
  
    // Traverse all digits from
    // current position to rest
    // of the length of string
    for (int i = position; i < length; i++)
    {
        sum += (num[i] - '0');
  
        // If forward_sum is greater
        // than the previous sum,
        // then call the method again
        if (sum >= previous_sum)
  
        // Note : We pass current 
        // sum as previous sum
        res += countGroups(i + 1, sum, 
                           length, num);
    }
  
    // Total number of subgroups
    // till current position
    return res;
}
  
// Driver Code

607
Chapter 77. Count digit groupings of a number with given constraints

int main()
{
    char num[] = "1119";
    int len = strlen(num);
    cout << countGroups(0, 0, len, num);
    return 0;
}

Java

// Java program to count number 


// of ways to group digits of  
// a number such that sum of  
// digits in every subgroup is 
// less than or equal to its 
// immediate right subgroup.
import java.io.*;
  
class GFG 
{
  
// Function to find
// the subgroups
static int countGroups(int position, 
                       int previous_sum, 
                       int length, 
                       String num)
{
    // Terminating Condition
    if (position == length)
        return 1;
  
    int res = 0;
      
    // sum of digits
    int sum = 0; 
  
    // Traverse all digits from
    // current position to rest
    // of the length of string
    for (int i = position; i < length; i++)
    {
        sum += (num.charAt(i) - '0');
  
        // If forward_sum is greater
        // than the previous sum,
        // then call the method again
        if (sum >= previous_sum)

608
Chapter 77. Count digit groupings of a number with given constraints

  
        // Note : We pass current 
        // sum as previous sum
        res += countGroups(i + 1, sum, 
                         length, num);
    }
  
    // Total number of subgroups
    // till current position
    return res;
}
  
// Driver Code
public static void main (String[] args)
{
    String num = "1119";
    int len =num .length();
    System.out.println(countGroups(0, 0, 
                                   len, num));
}
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to count number of
// ways to group digits of a number 
// such that sum of digits in every 
// subgroup is less than or equal 
// to its immediate right subgroup.
  
// Function to find the subgroups
function countGroups($position, 
                     $previous_sum, 
                     $length,$num)
{
    // Terminating Condition
    if ($position == $length)
        return 1;
  
    $res = 0;
      
    // sum of digits
    $sum = 0; 
  
    // Traverse all digits from 

609
Chapter 77. Count digit groupings of a number with given constraints

    // current position to rest


    // of the length of string
    for ($i = $position; $i < $length; $i++)
    {
        $sum += ($num[$i] - '0');
  
        // If forward_sum is greater 
        // than the previous sum,
        // then call the method again
        if ($sum >= $previous_sum)
  
        // Note : We pass current
        // sum as previous sum
        $res += countGroups($i + 1, $sum, 
                            $length, $num);
    }
  
    // Total number of subgroups
    // till current position
    return $res;
}
  
// Driver Code
$num = "1119";
$len = strlen($num);
echo countGroups(0, 0, $len, $num);
  
// This code is contributed by ajit
?>

Output :

If we take a closer look at above recursive solution, we notice that there may be overlapping
subproblems. For example, if input number is 12345, then for position = 3 and previ-
ous_sum = 3, we recur two times. Similarly for position 4 and previous_sum = 7, we recur
two times. Therefore the above solution can be optimized using Dynamic Programming.
Below is a Dynamic Programming based solution for this problem.

1. The maximum sum of digits can be 9*length where ‘length’ is length of input num.
2. Create a 2D array int dp[MAX][9*MAX] where MAX is maximum possible length of
input numebr. A value dp[position][previous] is going to store result for ‘position’ and
‘previous_sum’.
3. If current subproblem has been evaluated i.e; dp[position][previous_sum] != -1, then
use this result, else recursively compute its value.

610
Chapter 77. Count digit groupings of a number with given constraints

4. If by including the current position digit in sum i.e; sum = sum + num[position]-‘0’,
sum becomes greater than equal to previous sum, then increment the result and call
the problem for next position in the num.
5. If position == length, then we have been traversed current subgroup successfully and
we return 1;

Below is implementation of above algorithm.


C++

// C++ program to count number of 


// ways to group digits of a number
// such that sum of digits in every 
// subgroup is less than or equal
// to its immediate right subgroup.
#include<bits/stdc++.h>
using namespace std;
  
// Maximum length of 
// input number string
const int MAX = 40;
  
// A memoization table to store 
// results of subproblems length
// of string is 40 and maximum 
// sum will be 9 * 40 = 360.
int dp[MAX][9*MAX + 1];
  
// Function to find the count
// of splits with given condition
int countGroups(int position, 
                int previous_sum, 
                int length, char *num)
{
    // Terminating Condition
    if (position == length)
        return 1;
  
    // If already evaluated for 
    // a given sub problem then
    // return the value
    if (dp[position][previous_sum] != -1)
        return dp[position][previous_sum];
  
    // countGroups for current 
    // sub-group is 0
    dp[position][previous_sum] = 0;
  

611
Chapter 77. Count digit groupings of a number with given constraints

    int res = 0;
      
    // sum of digits
    int sum = 0; 
  
    // Traverse all digits from
    // current position to rest
    // of the length of string
    for (int i = position; i < length; i++)
    {
        sum += (num[i] - '0');
  
        // If forward_sum is greater 
        // than the previous sum,
        // then call the method again
        if (sum >= previous_sum)
  
        // Note : We pass current
        // sum as previous sum
        res += countGroups(i + 1, sum, 
                           length, num);
    }
  
    dp[position][previous_sum] = res;
  
    // total number of subgroups 
    // till current position
    return res;
}
  
// Driver Code
int main()
{
    char num[] = "1119";
    int len = strlen(num);
  
    // Initialize dp table
    memset(dp, -1, sizeof(dp));
  
    cout << countGroups(0, 0, len, num);
    return 0;
}

Output :

612
Chapter 77. Count digit groupings of a number with given constraints

This article is contributed by Shashank Mishra ( Gullu ). This article is reviewed by


team GeeksForGeeks.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
Improved By : jit_t, vt_m

Source

https://www.geeksforgeeks.org/count-groupings-number-sum-digits-every-sub-group-less-equals-immediate-right-su

613
Chapter 78

Count distinct occurrences as a


subsequence

Count distinct occurrences as a subsequence - GeeksforGeeks


Given a two strings S and T, find count of distinct occurrences of T in S as a subsequence.
Examples:

Input : S = banana, T = ban


Output : 3
T appears in S as below three subsequences.
[ban], [ba n], [b an]

Input : S = geeksforgeeks, T = ge
Output : 6
T appears in S as below three subsequences.
[ge], [ ge], [g e], [g e] [g e]
and [ g e]

This problem can be recursively defined as below.

// Returns count of subsequences of S that match T


// m is length of T and n is length of S
subsequenceCount(S, T, n, m)

// An empty string is subsequence of all.


1) If length of T is 0, return 1.

// Else no string can be a sequence of empty S.


2) Else if S is empty, return 0.

614
Chapter 78. Count distinct occurrences as a subsequence

3) Else if last characters of S and T don't match,


remove last character of S and recur for remaining
return subsequenceCount(S, T, n-1, m)

4) Else (Last characters match), the result is sum


of two counts.

// Remove last character of S and recur.


a) subsequenceCount(S, T, n-1, m) +

// Remove last characters of S and T, and recur.


b) subsequenceCount(S, T, n-1, m-1)

Since there are overlapping subproblems in above recurrence result, we can apply dynamic
programming approach to solve above problem. We create a 2D array mat[m+1][n+1]
where m is length of string T and n is length of string S. mat[i][j] denotes the number of
distinct subsequence of substring S(1..i) and substring T(1..j) so mat[m][n] contains our
solution.

C++

/* C/C++ program to count number of times S appears


   as a subsequence in T */
#include <bits/stdc++.h>
using namespace std;
  
int findSubsequenceCount(string S, string T)
{
    int m = T.length(), n = S.length();
  
    // T can't appear as a subsequence in S
    if (m > n)
        return 0;
  
    // mat[i][j] stores the count of occurrences of
    // T(1..i) in S(1..j).
    int mat[m + 1][n + 1];
  
    // Initializing first column with all 0s. An empty
    // string can't have another string as suhsequence
    for (int i = 1; i <= m; i++)
        mat[i][0] = 0;
  
    // Initializing first row with all 1s. An empty
    // string is subsequence of all.
    for (int j = 0; j <= n; j++)

615
Chapter 78. Count distinct occurrences as a subsequence

        mat[0][j] = 1;
  
    // Fill mat[][] in bottom up manner
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            // If last characters don't match, then value
            // is same as the value without last character
            // in S.
            if (T[i - 1] != S[j - 1])
                mat[i][j] = mat[i][j - 1];
  
            // Else value is obtained considering two cases.
            // a) All substrings without last character in S
            // b) All substrings without last characters in
            // both.
            else
                mat[i][j] = mat[i][j - 1] + mat[i - 1][j - 1];
        }
    }
  
    /* uncomment this to print matrix mat
    for (int i = 1; i <= m; i++, cout << endl)
        for (int j = 1; j <= n; j++)
            cout << mat[i][j] << " ";  */
    return mat[m][n];
}
  
// Driver code to check above method
int main()
{
    string T = "ge";
    string S = "geeksforgeeks";
    cout << findSubsequenceCount(S, T) << endl;
    return 0;
}

Java

// Java program to count number of times


// S appears as a subsequence in T
import java.io.*;
  
class GFG {
    static int findSubsequenceCount(String S, String T)
    {
        int m = T.length();
        int n = S.length();
  

616
Chapter 78. Count distinct occurrences as a subsequence

        // T can't appear as a subsequence in S


        if (m > n)
            return 0;
  
        // mat[i][j] stores the count of
        // occurrences of T(1..i) in S(1..j).
        int mat[][] = new int[m + 1][n + 1];
  
        // Initializing first column with
        // all 0s. An emptystring can't have
        // another string as suhsequence
        for (int i = 1; i <= m; i++)
            mat[i][0] = 0;
  
        // Initializing first row with all 1s.
        // An empty string is subsequence of all.
        for (int j = 0; j <= n; j++)
            mat[0][j] = 1;
  
        // Fill mat[][] in bottom up manner
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                // If last characters don't match,
                // then value is same as the value
                // without last character in S.
                if (T.charAt(i - 1) != S.charAt(j - 1))
                    mat[i][j] = mat[i][j - 1];
  
                // Else value is obtained considering two cases.
                // a) All substrings without last character in S
                // b) All substrings without last characters in
                // both.
                else
                    mat[i][j] = mat[i][j - 1] + mat[i - 1][j - 1];
            }
        }
  
        /* uncomment this to print matrix mat
        for (int i = 1; i <= m; i++, cout << endl)
            for (int j = 1; j <= n; j++)
                System.out.println ( mat[i][j] +" "); */
        return mat[m][n];
    }
  
    // Driver code to check above method
    public static void main(String[] args)
    {
        String T = "ge";

617
Chapter 78. Count distinct occurrences as a subsequence

        String S = "geeksforgeeks";
        System.out.println(findSubsequenceCount(S, T));
    }
}
// This code is contributed by vt_m

C#

// C# program to count number of times


// S appears as a subsequence in T
using System;
  
class GFG {
      
    static int findSubsequenceCount(string S, string T)
    {
        int m = T.Length;
        int n = S.Length;
  
        // T can't appear as a subsequence in S
        if (m > n)
            return 0;
  
        // mat[i][j] stores the count of
        // occurrences of T(1..i) in S(1..j).
        int[, ] mat = new int[m + 1, n + 1];
  
        // Initializing first column with
        // all 0s. An emptystring can't have
        // another string as suhsequence
        for (int i = 1; i <= m; i++)
            mat[i, 0] = 0;
  
        // Initializing first row with all 1s.
        // An empty string is subsequence of all.
        for (int j = 0; j <= n; j++)
            mat[0, j] = 1;
  
        // Fill mat[][] in bottom up manner
        for (int i = 1; i <= m; i++) {
              
            for (int j = 1; j <= n; j++) {
                  
                // If last characters don't match,
                // then value is same as the value
                // without last character in S.
                if (T[i - 1] != S[j - 1])
                    mat[i, j] = mat[i, j - 1];

618
Chapter 78. Count distinct occurrences as a subsequence

  
                // Else value is obtained considering two cases.
                // a) All substrings without last character in S
                // b) All substrings without last characters in
                // both.
                else
                    mat[i, j] = mat[i, j - 1] + mat[i - 1, j - 1];
            }
        }
  
        /* uncomment this to print matrix mat
        for (int i = 1; i <= m; i++, cout << endl)
            for (int j = 1; j <= n; j++)
                System.out.println ( mat[i][j] +" "); */
        return mat[m, n];
    }
  
    // Driver code to check above method
    public static void Main()
    {
        string T = "ge";
        string S = "geeksforgeeks";
        Console.WriteLine(findSubsequenceCount(S, T));
    }
}
  
// This code is contributed by vt_m

Output:

Time Complexity : O(m*n)


Auxiliary Space : O(m*n)
Since mat[i][j] accesses elements of current row and previous row only, we can optimize
auxiliary space just by using two rows only reducing space from m*n to 2*n.
Improved By : vt_m

Source

https://www.geeksforgeeks.org/count-distinct-occurrences-as-a-subsequence/

619
Chapter 79

Count even length binary


sequences with same sum of
first and second half bits

Count even length binary sequences with same sum of first and second half bits - Geeks-
forGeeks
Given a number n, find count of all binary sequences of length 2n such that sum of first n
bits is same as sum of last n bits.
Examples:

Input: n = 1
Output: 2
There are 2 sequences of length 2*n, the
sequences are 00 and 11

Input: n = 2
Output: 2
There are 6 sequences of length 2*n, the
sequences are 0101, 0110, 1010, 1001, 0000
and 1111

The idea is to fix first and last bits and then recur for n-1, i.e., remaining 2(n-1) bits. There
are following possibilities when we fix first and last bits.
1) First and last bits are same, remaining n-1 bits on both sides should also have the same
sum.
2) First bit is 1 and last bit is 0, sum of remaining n-1 bits on left side should be 1 less
than the sum n-1 bits on right side.
2) First bit is 0 and last bit is 1, sum of remaining n-1 bits on left side should be 1 more
than the sum n-1 bits on right side.

620
Chapter 79. Count even length binary sequences with same sum of first and second half bits

Based on above facts, we get below recurrence formula.


diff is the expected difference between sum of first half digits and last half digits. Initially
diff is 0.

// When first and last bits are same


// there are two cases, 00 and 11
count(n, diff) = 2*count(n-1, diff) +

// When first bit is 1 and last bit is 0


count(n-1, diff-1) +

// When first bit is 0 and last bit is 1


count(n-1, diff+1)

What should be base cases?


// When n == 1 (2 bit sequences)
1) If n == 1 and diff == 0, return 2
2) If n == 1 and |diff| == 1, return 1

// We can't cover difference of more than n with 2n bits


3) If |diff| > n, return 0

Below is the implementation based of above Naive Recursive Solution.

C++

// A Naive Recursive C++ program to count even


// length binary sequences such that the sum of
// first and second half bits is same
#include<bits/stdc++.h>
using namespace std;
  
// diff is difference between sums first n bits
// and last n bits respectively
int countSeq(int n, int diff)
{
    // We can't cover difference of more
    // than n with 2n bits
    if (abs(diff) > n)
        return 0;
  
    // n == 1, i.e., 2 bit long sequences
    if (n == 1 && diff == 0)
        return 2;
    if (n == 1 && abs(diff) == 1)

621
Chapter 79. Count even length binary sequences with same sum of first and second half bits

        return 1;
  
    int res = // First bit is 0 & last bit is 1
              countSeq(n-1, diff+1) +
  
              // First and last bits are same
              2*countSeq(n-1, diff) +
  
              // First bit is 1 & last bit is 0
              countSeq(n-1, diff-1);
  
    return res;
}
  
// Driver program
int main()
{
    int n = 2;
    cout << "Count of sequences is "
         << countSeq(2, 0);
    return 0;
}

Java

// A Naive Recursive C++ program to 


// count even length binary sequences 
// such that the sum of first and 
// second half bits is same
import java.io.*;
  
class GFG {
  
// diff is difference between sums 
// first n bits and last n bits respectively
static int countSeq(int n, int diff)
{
    // We can't cover difference of more
    // than n with 2n bits
    if (Math.abs(diff) > n)
        return 0;
  
    // n == 1, i.e., 2 bit long sequences
    if (n == 1 && diff == 0)
        return 2;
    if (n == 1 && Math.abs(diff) == 1)
        return 1;
  

622
Chapter 79. Count even length binary sequences with same sum of first and second half bits

    int res = // First bit is 0 & last bit is 1


            countSeq(n-1, diff+1) +
  
            // First and last bits are same
            2*countSeq(n-1, diff) +
  
            // First bit is 1 & last bit is 0
            countSeq(n-1, diff-1);
  
    return res;
}
  
// Driver program
public static void main(String[] args)
{
    int n = 2;
    System.out.println("Count of sequences is " 
                       + countSeq(2, 0));
}
}
  
// This code is contributed by Prerna Saini

Python3

# A Naive Recursive Python 


# program to count even length 
# binary sequences such that 
# the sum of first and second 
# half bits is same
  
# diff is difference between 
# sums first n bits and last 
# n bits respectively
def countSeq(n, diff):
  
    # We can't cover difference
    # of more than n with 2n bits
    if (abs(diff) > n):
        return 0
  
    # n == 1, i.e., 2 
    # bit long sequences
    if (n == 1 and diff == 0):
        return 2
    if (n == 1 and abs(diff) == 1):
        return 1
  

623
Chapter 79. Count even length binary sequences with same sum of first and second half bits

    # First bit is 0 & last bit is 1


    # First and last bits are same
    # First bit is 1 & last bit is 0
    res = (countSeq(n - 1, diff + 1) + 
           2 * countSeq(n - 1, diff) + 
            countSeq(n - 1, diff - 1))     
              
    return res
  
# Driver Code
n = 2;
print("Count of sequences is %d " %
                  (countSeq(2, 0)))
      
# This code is contributed 
# by Shivi_Aggarwal

C#

// A Naive Recursive C# program to 


// count even length binary sequences 
// such that the sum of first and 
// second half bits is same
using System;
  
class GFG {
  
    // diff is difference between sums 
    // first n bits and last n bits 
    // respectively
    static int countSeq(int n, int diff)
    {
        // We can't cover difference 
        // of more than n with 2n bits
        if (Math.Abs(diff) > n)
            return 0;
      
        // n == 1, i.e., 2 bit long 
        // sequences
        if (n == 1 && diff == 0)
            return 2;
        if (n == 1 && Math.Abs(diff) == 1)
            return 1;
      
        // 1. First bit is 0 & last bit is 1
        // 2. First and last bits are same
        // 3. First bit is 1 & last bit is 0
        int res = countSeq(n-1, diff+1) +

624
Chapter 79. Count even length binary sequences with same sum of first and second half bits

                2 * countSeq(n-1, diff) +


                   countSeq(n-1, diff-1);
      
        return res;
    }
      
    // Driver program
    public static void Main()
    {
        Console.Write("Count of sequences is "
                             + countSeq(2, 0));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// A Naive Recursive PHP program 
// to count even length binary 
// sequences such that the sum of
// first and second half bits is same
  
// diff is difference between 
// sums first n bits and last
// n bits respectively
function countSeq($n, $diff)
{
    // We can't cover difference of 
    // more than n with 2n bits
    if (abs($diff) > $n)
        return 0;
  
    // n == 1, i.e., 2
    // bit long sequences
    if ($n == 1 && $diff == 0)
        return 2;
          
    if ($n == 1 && abs($diff) == 1)
        return 1;
  
    $res = // First bit is 0 & last bit is 1
            countSeq($n - 1, $diff + 1) +
  
            // First and last bits are same
            2 * countSeq($n - 1, $diff) +
  

625
Chapter 79. Count even length binary sequences with same sum of first and second half bits

            // First bit is 1 & last bit is 0


            countSeq($n - 1, $diff - 1);
  
    return $res;
}
  
// Driver Code
$n = 2;
echo "Count of sequences is ",
              countSeq($n, 0);
  
// This code is contributed
// by shiv_bhakt.
?>

Output:

Count of sequences is 6

The time complexity of above solution is exponential. If we draw the complete recursion
tree, we can observer that many subproblems are solved again and again. For example,
when we start from n = 4 and diff = 0, we can reach (3, 0) through multiple paths. Since
same suproblems are called again, this problem has Overlapping Subprolems property. So
min square sum problem has both properties (see thisand this) of a Dynamic Program-
ming problem.
Below is a memoization based solution that uses a lookup table to compute the result.

C++

// A memoization based C++ program to count even


// length binary sequences such that the sum of
// first and second half bits is same
#include<bits/stdc++.h>
using namespace std;
#define MAX 1000
  
// A lookup table to store the results of subproblems
int lookup[MAX][MAX];
  
// dif is diference between sums of first n bits
// and last n bits i.e., dif = (Sum of first n bits) -
//                              (Sum of last n bits)
int countSeqUtil(int n, int dif)
{
    // We can't cover diference of more
    // than n with 2n bits
    if (abs(dif) > n)

626
Chapter 79. Count even length binary sequences with same sum of first and second half bits

        return 0;
  
    // n == 1, i.e., 2 bit long sequences
    if (n == 1 && dif == 0)
        return 2;
    if (n == 1 && abs(dif) == 1)
        return 1;
  
    // Check if this subbproblem is already solved
    // n is added to dif to make sure index becomes
    // positive
    if (lookup[n][n+dif] != -1)
        return lookup[n][n+dif];
  
    int res = // First bit is 0 & last bit is 1
              countSeqUtil(n-1, dif+1) +
  
              // First and last bits are same
              2*countSeqUtil(n-1, dif) +
  
              // First bit is 1 & last bit is 0
              countSeqUtil(n-1, dif-1);
  
    // Store result in lookup table and return the result
    return lookup[n][n+dif] = res;
}
  
// A Wrapper over countSeqUtil().  It mainly initializes lookup
// table, then calls countSeqUtil()
int countSeq(int n)
{
    // Initialize all entries of lookup table as not filled
    memset(lookup, -1, sizeof(lookup));
  
    // call countSeqUtil()
    return countSeqUtil(n, 0);
}
  
// Driver program
int main()
{
    int n = 2;
    cout << "Count of sequences is "
         << countSeq(2);
    return 0;
}

Java

627
Chapter 79. Count even length binary sequences with same sum of first and second half bits

// A memoization based C++ program to 


// count even length binary sequences 
// such that the sum of first and 
// second half bits is same
import java.io.*;
  
class GFG {
      
// A lookup table to store the results of 
// subproblems
static int lookup[][] = new int[1000][1000];
  
// dif is diference between sums of first 
// n bits and last n bits i.e., 
// dif = (Sum of first n bits) - (Sum of last n bits)
static int countSeqUtil(int n, int dif)
{
    // We can't cover diference of
    // more than n with 2n bits
    if (Math.abs(dif) > n)
        return 0;
  
    // n == 1, i.e., 2 bit long sequences
    if (n == 1 && dif == 0)
        return 2;
    if (n == 1 && Math.abs(dif) == 1)
        return 1;
  
    // Check if this subbproblem is already
    // solved n is added to dif to make 
    // sure index becomes positive
    if (lookup[n][n+dif] != -1)
        return lookup[n][n+dif];
  
    int res = // First bit is 0 & last bit is 1
            countSeqUtil(n-1, dif+1) +
  
            // First and last bits are same
            2*countSeqUtil(n-1, dif) +
  
            // First bit is 1 & last bit is 0
            countSeqUtil(n-1, dif-1);
  
    // Store result in lookup table 
    // and return the result
    return lookup[n][n+dif] = res;
}
  

628
Chapter 79. Count even length binary sequences with same sum of first and second half bits

// A Wrapper over countSeqUtil(). It mainly 


// initializes lookup table, then calls 
// countSeqUtil()
static int countSeq(int n)
{
    // Initialize all entries of lookup
    // table as not filled 
    // memset(lookup, -1, sizeof(lookup));
    for(int k = 0; k < lookup.length; k++)
    {
        for(int j = 0; j < lookup.length; j++)
        {
        lookup[k][j] = -1;
    }
    } 
      
    // call countSeqUtil()
    return countSeqUtil(n, 0);
}
  
// Driver program
public static void main(String[] args)
{
    int n = 2;
    System.out.println("Count of sequences is " 
                       + countSeq(2));
}
}
  
// This code is contributed by Prerna Saini

Output:

Count of sequences is 6

Worst case time complexity of this solution is O(n2 ) as diff can be maximum n.
Below is O(n) solution for the same.

Number of n-bit strings with 0 ones = nC0


Number of n-bit strings with 1 ones = nC1
...
Number of n-bit strings with k ones = nCk
...
Number of n-bit strings with n ones = nCn

So, we can get required result using below

629
Chapter 79. Count even length binary sequences with same sum of first and second half bits

No. of 2*n bit strings such that first n bits have 0 ones &
last n bits have 0 ones = nC0 * nC0

No. of 2*n bit strings such that first n bits have 1 ones &
last n bits have 1 ones = nC1 * nC1

....

and so on.

Result = nC0*nC0 + nC1*nC1 + ... + nCn*nCn


= &Sum;(nCk)2
0 <= k <= n

Below is the implementation based on above idea.

C++

// A O(n) C++ program to count even length binary sequences


// such that the sum of first and second half bits is same
#include<iostream>
using namespace std;
  
// Returns the count of even length sequences
int countSeq(int n)
{
    int nCr=1, res = 1;
  
    // Calculate SUM ((nCr)^2)
    for (int r = 1; r<=n ; r++)
    {
        // Compute nCr using nC(r-1)
        // nCr/nC(r-1) = (n+1-r)/r;
        nCr = (nCr * (n+1-r))/r;   
  
        res += nCr*nCr;
    }
  
    return res;
}
  
// Driver program
int main()
{
    int n = 2;
    cout << "Count of sequences is "

630
Chapter 79. Count even length binary sequences with same sum of first and second half bits

         << countSeq(n);
    return 0;
}

Java

// Java program to find remaining


// chocolates after k iterations
class GFG
{
// A O(n) C++ program to count
// even length binary sequences
// such that the sum of first
// and second half bits is same
  
// Returns the count of 
// even length sequences
static int countSeq(int n)
{
    int nCr = 1, res = 1;
  
    // Calculate SUM ((nCr)^2)
    for (int r = 1; r <= n ; r++)
    {
        // Compute nCr using nC(r-1)
        // nCr/nC(r-1) = (n+1-r)/r;
        nCr = (nCr * (n + 1 - r)) / r; 
  
        res += nCr * nCr;
    }
  
    return res;
}
  
// Driver code
public static void main(String args[])
{
    int n = 2;
    System.out.print("Count of sequences is ");
    System.out.println(countSeq(n));
}
}
  
// This code is contributed
// by Shivi_Aggarwal 

Python

631
Chapter 79. Count even length binary sequences with same sum of first and second half bits

# A Python program to count 


# even length binary sequences 
# such that the sum of first 
# and second half bits is same 
  
# Returns the count of 
# even length sequences 
def countSeq(n): 
  
    nCr = 1
    res = 1
  
    # Calculate SUM ((nCr)^2) 
    for r in range(1, n + 1): 
      
        # Compute nCr using nC(r-1) 
        # nCr/nC(r-1) = (n+1-r)/r; 
        nCr = (nCr * (n + 1 - r)) / r; 
  
        res += nCr * nCr; 
  
    return res; 
  
# Driver Code
n = 2
print("Count of sequences is"),
print (int(countSeq(n)))
      
# This code is contributed
# by Shivi_Aggarwal 

PHP

<?php
// A Php program to count even 
// length binary sequences 
// such that the sum of first
// and second half bits is same 
  
// Returns the count of
// even length sequences 
function countSeq($n) 

    $nCr = 1; 
    $res = 1; 
  
    // Calculate SUM ((nCr)^2) 
    for ($r = 1; $r <= $n; $r++) 

632
Chapter 79. Count even length binary sequences with same sum of first and second half bits

    { 
        // Compute nCr using nC(r-1) 
        // nCr/nC(r-1) = (n+1-r)/r; 
        $nCr = ($nCr * ($n + 1 - $r)) / $r; 
  
        $res = $res + ($nCr * $nCr); 
    } 
  
    return $res; 

  
// Driver Code 
$n = 2; 
echo ("Count of sequences is ");
echo countSeq($n); 
  
// This code is contributed 
// by Shivi_Aggarwal 
?>

Output:

Count of sequences is 6

Thanks to d_geeks, Saurabh Jain and Mysterious Mind for suggesting above O(n) solution.
This article is contributed by Pawan. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Improved By : nitin mittal, shiv_bhakt, Shivi_Aggarwal

Source

https://www.geeksforgeeks.org/count-even-length-binary-sequences-with-same-sum-of-first-and-second-half-bits/

633
Chapter 80

Count number of binary strings


without consecutive 1’s

Count number of binary strings without consecutive 1’s - GeeksforGeeks


Given a positive integer N, count all possible distinct binary strings of length N such that
there are no consecutive 1’s.
Examples:

Input: N = 2
Output: 3
// The 3 strings are 00, 01, 10

Input: N = 3
Output: 5
// The 5 strings are 000, 001, 010, 100, 101

This problem can be solved using Dynamic Programming. Let a[i] be the number of binary
strings of length i which do not contain any two consecutive 1’s and which end in 0. Similarly,
let b[i] be the number of such strings which end in 1. We can append either 0 or 1 to a string
ending in 0, but we can only append 0 to a string ending in 1. This yields the recurrence
relation:

a[i] = a[i - 1] + b[i - 1]


b[i] = a[i - 1]

The base cases of above recurrence are a[1] = b[1] = 1. The total number of strings of length
i is just a[i] + b[i].

634
Chapter 80. Count number of binary strings without consecutive 1’s

Following is the implementation of above solution. In the following implementation, indexes


start from 0. So a[i] represents the number of binary strings for input length i+1. Similarly,
b[i] represents binary strings for input length i+1.
C++

// C++ program to count all distinct binary strings


// without two consecutive 1's
#include <iostream>
using namespace std;
  
int countStrings(int n)
{
    int a[n], b[n];
    a[0] = b[0] = 1;
    for (int i = 1; i < n; i++)
    {
        a[i] = a[i-1] + b[i-1];
        b[i] = a[i-1];
    }
    return a[n-1] + b[n-1];
}
  
  
// Driver program to test above functions
int main()
{
    cout << countStrings(3) << endl;
    return 0;
}

Java

class Subset_sum
{
    static  int countStrings(int n)
    {
        int a[] = new int [n];
        int b[] = new int [n];
        a[0] = b[0] = 1;
        for (int i = 1; i < n; i++)
        {
            a[i] = a[i-1] + b[i-1];
            b[i] = a[i-1];
        }
        return a[n-1] + b[n-1];
    }
    /* Driver program to test above function */ 

635
Chapter 80. Count number of binary strings without consecutive 1’s

    public static void main (String args[])


    {
          System.out.println(countStrings(3));
    }
}/* This code is contributed by Rajat Mishra */

Python3

# Python program to count


# all distinct binary strings
# without two consecutive 1's
  
def countStrings(n):
  
    a=[0 for i in range(n)]
    b=[0 for i in range(n)]
    a[0] = b[0] = 1
    for i in range(1,n):
        a[i] = a[i-1] + b[i-1]
        b[i] = a[i-1]
      
    return a[n-1] + b[n-1]
  
# Driver program to test
# above functions
  
print(countStrings(3))
  
# This code is contributed
# by Anant Agarwal.

C#

// C# program to count all distinct binary 


// strings without two consecutive 1's
using System;
  
class Subset_sum
{
    static int countStrings(int n)
    {
        int []a = new int [n];
        int []b = new int [n];
        a[0] = b[0] = 1;
        for (int i = 1; i < n; i++)
        {
            a[i] = a[i-1] + b[i-1];

636
Chapter 80. Count number of binary strings without consecutive 1’s

            b[i] = a[i-1];
        }
        return a[n-1] + b[n-1];
    }
      
    // Driver Code
    public static void Main ()
    {
        Console.Write(countStrings(3));
    }
}
  
// This code is contributed by nitin mittal

PHP

<?php
// PHP program to count all distinct
// binary stringswithout two
// consecutive 1's
  
function countStrings($n)
{
    $a[$n] = 0;
    $b[$n] = 0;
    $a[0] = $b[0] = 1;
    for ($i = 1; $i < $n; $i++)
    {
        $a[$i] = $a[$i - 1] + 
                 $b[$i - 1];
        $b[$i] = $a[$i - 1];
    }
    return $a[$n - 1] + 
           $b[$n - 1];
}
  
    // Driver Code
    echo countStrings(3) ;
  
// This code is contributed by nitin mittal
?>

Output:

637
Chapter 80. Count number of binary strings without consecutive 1’s

Source:
courses.csail.mit.edu/6.006/oldquizzes/solutions/q2-f2009-sol.pdf
If we take a closer look at the pattern, we can observe that the count is actually (n+2)’th
Fibonacci number for n >= 1. The Fibonacci Numbersare 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55,
89, 141, ….

n = 1, count = 2 = fib(3)
n = 2, count = 3 = fib(4)
n = 3, count = 5 = fib(5)
n = 4, count = 8 = fib(6)
n = 5, count = 13 = fib(7)
................

Therefore we can count the strings in O(Log n) time also using the method 5 here.
Related Post :
1 to n bit numbers with no consecutive 1s in binary representation.
This article is contributed by Rahul Jain. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal, jit_t

Source

https://www.geeksforgeeks.org/count-number-binary-strings-without-consecutive-1s/

638
Chapter 81

Count number of increasing


subsequences of size k

Count number of increasing subsequences of size k - GeeksforGeeks


Given an array arr[] containing n integers. The problem is to count number of increasing
subsequences in the array of size k.
Examples:

Input : arr[] = {2, 6, 4, 5, 7},


k = 3
Output : 5
The subsequences of size '3' are:
{2, 6, 7}, {2, 4, 5}, {2, 4, 7},
{2, 5, 7} and {4, 5, 7}.

Input : arr[] = {12, 8, 11, 13, 10, 15, 14, 16, 20},
k = 4
Output : 39

Approach: The idea is to use Dynamic Programming by define 2D matrix, say dp[][].
dp[i][j] stores the count of increasing subsequences of size i ending with element arr[j]. So
dp[i][j] can be defined as:

dp[i][j] = 1, where i = 1 and 1 <= j <= n


dp[i][j] = sum(dp[i-1][j]), where 1 < i <= k, i <= j <= n and arr[m] < arr[j] for
(i-1) <= m < j.

C++

639
Chapter 81. Count number of increasing subsequences of size k

// C++ implementation to count number of


// increasing subsequences of size k
#include <bits/stdc++.h>
  
using namespace std;
  
// function to count number of increasing
// subsequences of size k
int numOfIncSubseqOfSizeK(int arr[], int n, int k)
{
    int dp[k][n], sum = 0;
    memset(dp, 0, sizeof(dp));
  
    // count of increasing subsequences of size 1
    // ending at each arr[i]
    for (int i = 0; i < n; i++)
        dp[0][i] = 1;
  
    // building up the matrix dp[][]
    // Here 'l' signifies the size of
    // increassing subsequnce of size (l+1).
    for (int l = 1; l < k; l++) {
  
        // for each increasing subsequence of size 'l'
        // ending with element arr[i]
        for (int i = l; i < n; i++) {
  
            // count of increasing subsequnces of size 'l'
            // ending with element arr[i]
            dp[l][i] = 0;
            for (int j = l - 1; j < i; j++) {
                if (arr[j] < arr[i])
                    dp[l][i] += dp[l - 1][j];
            }
        }
    }
  
    // sum up the count of increasing subsequences of
    // size 'k' ending at each element arr[i]
    for (int i = k - 1; i < n; i++)
        sum += dp[k - 1][i];
  
    // required number of increasing
    // subsequences of size k
    return sum;
}
  
// Driver program to test above

640
Chapter 81. Count number of increasing subsequences of size k

int main()
{
    int arr[] = { 12, 8, 11, 13, 10, 15, 14, 16, 20 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 4;
  
    cout << "Number of Increasing Subsequences of size "
         << k << " = " << numOfIncSubseqOfSizeK(arr, n, k);
  
    return 0;
}

PHP

<?php
// PHP implementation to count 
// number of increasing 
// subsequences of size k
  
// function to count number
// of increasing subsequences
// of size k
function numOfIncSubseqOfSizeK($arr, 
                               $n, $k)
{
    $dp = array(array()); 
    $sum = 0;
    $dp = array_fill(0, $n + 1, false);
  
    // count of increasing 
    // subsequences of size 1
    // ending at each arr[i]
    for ($i = 0; $i < $n; $i++)
        $dp[0][$i] = 1;
  
    // building up the matrix 
    // dp[][]. Here 'l' signifies 
    // the size of increassing 
    // subsequnce of size (l+1).
    for ($l = 1; $l < $k; $l++)
    {
  
        // for each increasing 
        // subsequence of size 'l'
        // ending with element arr[i]
        for ($i = $l; $i < $n; $i++)
        {
  

641
Chapter 81. Count number of increasing subsequences of size k

            // count of increasing 


            // subsequnces of size 'l'
            // ending with element arr[i]
            $dp[$l][$i] = 0;
            for ($j = $l - 1; $j < $i; $j++) 
            {
                if ($arr[$j] < $arr[$i])
                    $dp[$l][$i] += $dp[$l - 1][$j];
            }
        }
    }
  
    // sum up the count of increasing 
    // subsequences of size 'k' ending
    // at each element arr[i]
    for ($i = $k - 1; $i < $n; $i++)
        $sum += $dp[$k - 1][$i];
  
    // required number of increasing
    // subsequences of size k
    return $sum;
}
  
// Driver Code
$arr = array(12, 8, 11, 13, 
             10, 15, 14, 16, 20);
$n = sizeof($arr);
$k = 4;
  
echo "Number of Increasing ". 
     "Subsequences of size ",
                 $k , " = " , 
     numOfIncSubseqOfSizeK($arr, 
                           $n, $k);
  
// This code is contributed 
// by akt_mit
?>

Output:

Number of Increasing Subsequences of size 4 = 39

Time Complexity: O(kn2 ).


Auxiliary Space: O(kn).
Improved By : jit_t

642
Chapter 81. Count number of increasing subsequences of size k

Source

https://www.geeksforgeeks.org/count-number-increasing-subsequences-size-k/

643
Chapter 82

Count number of paths with


at-most k turns

Count number of paths with at-most k turns - GeeksforGeeks


Given a “m x n” matrix, count number of paths to reach bottom right from top left with
maximum k turns allowed.
What is a turn? A movement is considered turn, if we were moving along row and now
move along column. OR we were moving along column and now move along row.

There are two possible scenarios when a turn can occur


at point (i, j):

Turns Right: (i-1, j) -> (i, j) -> (i, j+1)


Down Right

Turns Down: (i, j-1) -> (i, j) -> (i+1, j)


Right Down

Examples:

Input: m = 3, n = 3, k = 2
Output: 4
See below diagram for four paths with
maximum 2 turns.

Input: m = 3, n = 3, k = 1
Output: 2

644
Chapter 82. Count number of paths with at-most k turns

We strongly recommend you to minimize your browser and try this yourself
first.
This problem can be recursively computed using below recursive formula.

countPaths(i, j, k): Count of paths to reach (i,j) from (0, 0)


countPathsDir(i, j, k, 0): Count of paths if we reach (i, j)
along row.
countPathsDir(i, j, k, 1): Count of paths if we reach (i, j)
along column.
The fourth parameter in countPathsDir() indicates direction.

Value of countPaths() can be written as:


countPaths(i, j, k) = countPathsDir(i, j, k, 0) +
countPathsDir(i, j, k, 1)

And value of countPathsDir() can be recursively defined as:

// Base cases

// If current direction is along row


If (d == 0)
// Count paths for two cases
// 1) We reach here through previous row.
// 2) We reach here through previous column, so number of
// turns k reduce by 1.
countPathsDir(i, j, k, d) = countPathsUtil(i, j-1, k, d) +
countPathsUtil(i-1, j, k-1, !d);

// If current direction is along column


Else
// Similar to above
countPathsDir(i, j, k, d) = countPathsUtil(i-1, j, k, d) +
countPathsUtil(i, j-1, k-1, !d);

645
Chapter 82. Count number of paths with at-most k turns

We can solve this problem in Polynomial Time using Dynamic Programming. The idea is to
use a 4 dimensional table dp[m][n][k][d] where m is number of rows, n is number of columns,
k is number of allowed turns and d is direction.
Below is Dynamic Programming based C++ implementation.

// C++ program to count number of paths with maximum


// k turns allowed
#include<bits/stdc++.h>
using namespace std;
#define MAX 100
  
// table to store to store results of subproblems
int dp[MAX][MAX][MAX][2];
  
// Returns count of paths to reach (i, j) from (0, 0)
// using at-most k turns. d is current direction
// d = 0 indicates along row, d = 1 indicates along
// column.
int countPathsUtil(int i, int j, int k, int d)
{
    // If invalid row or column indexes
    if (i < 0 || j < 0)
        return 0;
  
    // If current cell is top left itself
    if (i == 0 && j == 0)
        return 1;
  
    // If 0 turns left
    if (k == 0)
    {
        // If direction is row, then we can reach here 
        // only if direction is row and row is 0.
        if (d == 0 && i == 0) return 1;
  
        // If direction is column, then we can reach here 
        // only if direction is column and column is 0.
        if (d == 1 && j == 0) return 1;
  
        return 0;
    }
  
    // If this subproblem is already evaluated
    if (dp[i][j][k][d] != -1)
        return dp[i][j][k][d];
  
    // If current direction is row, then count paths for two cases
    // 1) We reach here through previous row.

646
Chapter 82. Count number of paths with at-most k turns

    // 2) We reach here through previous column, so number of 


    //    turns k reduce by 1.
    if (d == 0)
      return dp[i][j][k][d] = countPathsUtil(i, j-1, k, d) +
                              countPathsUtil(i-1, j, k-1, !d);
  
    // Similar to above if direction is column
    return dp[i][j][k][d] =  countPathsUtil(i-1, j, k, d) +
                             countPathsUtil(i, j-1, k-1, !d);
}
  
// This function mainly initializes 'dp' array as -1 and calls
// countPathsUtil()
int countPaths(int i, int j, int k)
{
    // If (0, 0) is target itself
    if (i == 0 && j == 0)
          return 1;
  
    // Initialize 'dp' array
    memset(dp, -1, sizeof dp);
  
    // Recur for two cases: moving along row and along column
    return countPathsUtil(i-1, j, k, 1) +  // Moving along row
           countPathsUtil(i, j-1, k, 0); // Moving along column
}
  
// Driver program
int main()
{
    int m = 3, n = 3, k = 2;
    cout << "Number of paths is "
         << countPaths(m-1, n-1, k) << endl;
    return 0;
}

Output:

Number of paths is 4

Time complexity of above solution is O(m*n*k)


Thanks to Gaurav Ahirwar for suggesting this solution.

Source
https://www.geeksforgeeks.org/count-number-of-paths-with-k-turns/

647
Chapter 83

Count number of subsets having


a particular XOR value

Count number of subsets having a particular XOR value - GeeksforGeeks


Given an array arr[] of n numbers and a number K, find the number of subsets of arr[]
having XOR of elements as K
Examples :

Input: arr[] = {6, 9, 4, 2}, k = 6


Output: 2
The subsets are {4, 2} and {6}

Input: arr[] = {1, 2, 3, 4, 5}, k = 4


Output: 4
The subsets are {1, 5}, {4}, {1, 2, 3, 4}
and {2, 3, 5}

Brute Force approach O(2n ): One naive approach is to generate all the 2n subsets and
count all the subsets having XOR value K, but this approach will not be efficient for large
values of n.
Dynamic Programming Approach O(n*m):
We define a number m such that m = pow(2,(log2(max(arr))+1)) – 1. This number is
actually the maximum value any XOR subset will acquire. We get this number by counting
bits in largest number. We create a 2D array dp[n+1][m+1], such that dp[i][j] equals to
the number of subsets having XOR value j from subsets of arr[0…i-1].
We fill the dp array as following:

1. We initialize all values of dp[i][j] as 0.


2. Set value of dp[0][0] = 1 since XOR of an empty set is 0.

648
Chapter 83. Count number of subsets having a particular XOR value

3. Iterate over all the values of arr[i] from left to right and for each arr[i], iterate over
all the possible values of XOR i.e from 0 to m (both inclusive) and fill the dp array
asfollowing:
for i = 1 to n:
for j = 0 to m:
dp[i][j] = dp[i-1][j] + dp[i-1][j^arr[i-1]]
This can be explained as, if there is a subset arr[0…i-2] with XOR value j, then there
also exists a subset arr[0…i-1] with XOR value j. also if there exists a subset arr[0….i-2]
with XOR value j^arr[i] then clearly there exist a subset arr[0…i-1] with XOR value j,
as j ^ arr[i-1] ^ arr[i-1] = j.
4. Counting the number of subsets with XOR value k: Since dp[i][j] is the number of
subsets having j as XOR value from the subsets of arr[0..i-1], then the number of
subsets from set arr[0..n] having XOR value as K will be dp[n][K]

C/C++

// arr dynamic programming solution to finding the number


// of subsets having xor of their elements as k
#include<bits/stdc++.h>
using namespace std;
  
// Returns count of subsets of arr[] with XOR value equals
// to k.
int subsetXOR(int arr[], int n, int k)
{
    // Find maximum element in arr[]
    int max_ele = arr[0];
    for (int i=1; i<n; i++)
       if (arr[i] > max_ele)
           max_ele = arr[i];
  
    // Maximum possible XOR value
    int m = (1 << (int)(log2(max_ele) + 1) ) - 1;
  
    // The value of dp[i][j] is the number of subsets having
    // XOR of their elements as j from the set arr[0...i-1]
    int dp[n+1][m+1];
  
    // Initializing all the values of dp[i][j] as 0
    for (int i=0; i<=n; i++)
        for (int j=0; j<=m; j++)
            dp[i][j] = 0;
  
    // The xor of empty subset is 0
    dp[0][0] = 1;
  
    // Fill the dp table
    for (int i=1; i<=n; i++)

649
Chapter 83. Count number of subsets having a particular XOR value

        for (int j=0; j<=m; j++)


            dp[i][j] = dp[i-1][j] + dp[i-1][j^arr[i-1]];
  
    //  The answer is the number of subset from set
    //  arr[0..n-1] having XOR of elements as k
    return dp[n][k];
}
  
// Driver program to test above function
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int k = 4;
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Count of subsets is " << subsetXOR(arr, n, k);
    return 0;
}

PHP

<?php
// PHP arr dynamic programming 
// solution to finding the number 
// of subsets having xor of their 
// elements as k
  
// Returns count of subsets of 
// arr[] with XOR value equals to k.
function subsetXOR($arr, $n, $k)
{
    // Find maximum element in arr[]
    $max_ele = $arr[0];
    for ($i = 1; $i < $n; $i++)
    if ($arr[$i] > $max_ele)
        $max_ele = $arr[$i];
  
    // Maximum possible XOR value
    $m = (1 << (int)(log($max_ele, 
                    2) + 1) ) - 1;
  
    // The value of dp[i][j] is the
    // number of subsets having
    // XOR of their elements as j 
    // from the set arr[0...i-1]
      
    // Initializing all the 
    // values of dp[i][j] as 0
    for ($i = 0; $i <= $n; $i++)

650
Chapter 83. Count number of subsets having a particular XOR value

        for ($j = 0; $j <= $m; $j++)


            $dp[$i][$j] = 0;
  
    // The xor of empty subset is 0
    $dp[0][0] = 1;
  
    // Fill the dp table
    for ($i = 1; $i <= $n; $i++)
        for ( $j = 0; $j <= $m; $j++)
            $dp[$i][$j] = $dp[$i - 1][$j] + 
                          $dp[$i - 1][$j ^ 
                          $arr[$i - 1]];
  
    // The answer is the number 
    // of subset from set arr[0..n-1] 
    // having XOR of elements as k
    return $dp[$n][$k];
}
  
// Driver Code
$arr = array (1, 2, 3, 4, 5);
$k = 4;
$n = sizeof($arr);
echo "Count of subsets is " , 
     subsetXOR($arr, $n, $k);
  
// This code is contributed by ajit
?>

Output :

Count of subsets is 4

This article is contributed by Pranay Pandey. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : jit_t

Source

https://www.geeksforgeeks.org/count-number-of-subsets-having-a-particular-xor-value/

651
Chapter 84

Count number of ways to cover


a distance

Count number of ways to cover a distance - GeeksforGeeks


Given a distance ‘dist, count total number of ways to cover the distance with 1, 2 and 3 steps.

Examples :

Input: n = 3
Output: 4
Below are the four ways
1 step + 1 step + 1 step
1 step + 2 step
2 step + 1 step
3 step

Input: n = 4
Output: 7

C++

// A naive recursive C++ program to count number of ways to cover


// a distance with 1, 2 and 3 steps
#include<iostream>
using namespace std;
  
// Returns count of ways to cover 'dist'
int printCountRec(int dist)
{
    // Base cases

652
Chapter 84. Count number of ways to cover a distance

    if (dist<0)      return 0;


    if (dist==0)  return 1;
  
    // Recur for all previous 3 and add the results
    return printCountRec(dist-1) +
           printCountRec(dist-2) +
           printCountRec(dist-3);
}
  
// driver program
int main()
{
    int dist = 4;
    cout << printCountRec(dist);
    return 0;
}

Java

// A naive recursive Java program to count number


// of ways to cover a distance with 1, 2 and 3 steps
import java.io.*;
  
class GFG 
{
    // Function returns count of ways to cover 'dist'
    static int printCountRec(int dist)
    {
        // Base cases
        if (dist<0)    
            return 0;
        if (dist==0)    
            return 1;
   
        // Recur for all previous 3 and add the results
        return printCountRec(dist-1) + 
               printCountRec(dist-2) +
               printCountRec(dist-3);
    }
      
    // driver program
    public static void main (String[] args) 
    {
        int dist = 4;
        System.out.println(printCountRec(dist));
    }
}
  

653
Chapter 84. Count number of ways to cover a distance

// This code is contributed by Pramod Kumar

Python3

# A naive recursive Python3 program 


# to count number of ways to cover
# a distance with 1, 2 and 3 steps
  
# Returns count of ways to 
# cover 'dist'
def printCountRec(dist):
      
    # Base cases
    if dist < 0:
        return 0
          
    if dist == 0:
        return 1
  
    # Recur for all previous 3 and       
   # add the results
    return (printCountRec(dist-1) +
            printCountRec(dist-2) +
            printCountRec(dist-3))
  
# Driver code
dist = 4
print(printCountRec(dist))
  
# This code is contributed by Anant Agarwal.

C#

// A naive recursive C# program to 


// count number of ways to cover a
// distance with 1, 2 and 3 steps
using System;
  
class GFG {
      
    // Function returns count of 
    // ways to cover 'dist'
    static int printCountRec(int dist)
    {
        // Base cases
        if (dist < 0) 
            return 0;

654
Chapter 84. Count number of ways to cover a distance

        if (dist == 0) 


            return 1;
  
        // Recur for all previous 3 
        // and add the results
        return printCountRec(dist - 1) + 
               printCountRec(dist - 2) +
               printCountRec(dist - 3);
    }
      
    // Driver Code
    public static void Main () 
    {
        int dist = 4;
        Console.WriteLine(printCountRec(dist));
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// A naive recursive PHP program to
// count number of ways to cover
// a distance with 1, 2 and 3 steps
  
// Returns count of ways to cover 'dist'
function printCountRec( $dist)
{
      
    // Base cases
    if ($dist<0) return 0;
    if ($dist==0) return 1;
  
    // Recur for all previous 3 
    // and add the results
    return printCountRec($dist - 1) +
           printCountRec($dist - 2) +
           printCountRec($dist - 3);
}
  
    // Driver Code
    $dist = 4;
    echo printCountRec($dist);
  
// This code is contributed by anuj_67.
?>

655
Chapter 84. Count number of ways to cover a distance

Output:

The time complexity of above solution is exponential, a close upper bound is O(3n ). If we
draw the complete recursion tree, we can observer that many subproblems are solved again
and again. For example, when we start from n = 6, we can reach 4 by subtracting one 2
times and by subtracting 2 one times. So the subproblem for 4 is called twice.
Since same suproblems are called again, this problem has Overlapping Subprolems property.
So min square sum problem has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, recomputations of same
subproblems can be avoided by constructing a temporary array count[] in bottom up manner.
Below is the implementation of above idea :
C++

// A Dynamic Programming based C++ program to count number of ways


// to cover a distance with 1, 2 and 3 steps
#include<iostream>
using namespace std;
  
int printCountDP(int dist)
{
    int count[dist+1];
  
    // Initialize base values. There is one way to cover 0 and 1
    // distances and two ways to cover 2 distance
    count[0]  = 1,  count[1] = 1,  count[2] = 2;
  
    // Fill the count array in bottom up manner
    for (int i=3; i<=dist; i++)
       count[i] = count[i-1] + count[i-2] + count[i-3];
  
    return count[dist];
}
  
// driver program
int main()
{
    int dist = 4;
    cout << printCountDP(dist);
    return 0;
}

Java

// A Dynamic Programming based Java program 

656
Chapter 84. Count number of ways to cover a distance

// to count number of ways to cover a distance 


// with 1, 2 and 3 steps
import java.io.*;
  
class GFG 
{
    // Function returns count of ways to cover 'dist'
    static int printCountDP(int dist)
    {
        int[] count = new int[dist+1];
   
        // Initialize base values. There is one way to 
        // cover 0 and 1 distances and two ways to 
        // cover 2 distance
        count[0] = 1;
        count[1] = 1;
        count[2] = 2;
   
        // Fill the count array in bottom up manner
        for (int i=3; i<=dist; i++)
            count[i] = count[i-1] + count[i-2] + count[i-3];
   
        return count[dist];
    }
      
    // driver program
    public static void main (String[] args) 
    {
        int dist = 4;
        System.out.println(printCountDP(dist));
    }
}
  
// This code is contributed by Pramod Kumar

Python3

# A Dynamic Programming based on Python3


# program to count number of ways to 
# cover a distance with 1, 2 and 3 steps
  
def printCountDP(dist):
    count = [0] * (dist + 1)
      
    # Initialize base values. There is
    # one way to cover 0 and 1 distances
    # and two ways to cover 2 distance
    count[0] = 1

657
Chapter 84. Count number of ways to cover a distance

    count[1] = 1
    count[2] = 2
      
    # Fill the count array in bottom
    # up manner
    for i in range(3, dist + 1):
        count[i] = (count[i-1] + 
                   count[i-2] + count[i-3])
          
    return count[dist];
  
# driver program
dist = 4;
print( printCountDP(dist))
  
# This code is contributed by Sam007.

C#

// A Dynamic Programming based C# program 


// to count number of ways to cover a distance 
// with 1, 2 and 3 steps
using System;
  
class GFG {
      
    // Function returns count of ways 
    // to cover 'dist'
    static int printCountDP(int dist)
    {
        int[] count = new int[dist + 1];
  
        // Initialize base values. There is one
        // way to cover 0 and 1 distances 
        // and two ways to cover 2 distance 
        count[0] = 1;
        count[1] = 1;
        count[2] = 2;
  
        // Fill the count array 
        // in bottom up manner
        for (int i = 3; i <= dist; i++)
            count[i] = count[i - 1] + 
                       count[i - 2] + 
                       count[i - 3];
  
        return count[dist];
    }

658
Chapter 84. Count number of ways to cover a distance

      
    // Driver Code
    public static void Main () 
    {
        int dist = 4;
        Console.WriteLine(printCountDP(dist));
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// A Dynamic Programming based PHP program
// to count number of ways to cover a 
// distance with 1, 2 and 3 steps
  
function printCountDP( $dist)
{
    $count = array();
  
    // Initialize base values. There is
    // one way to cover 0 and 1 distances
    // and two ways to cover 2 distance
    $count[0] = 1; $count[1] = 1; 
    $count[2] = 2;
  
    // Fill the count array 
    // in bottom up manner
    for ( $i = 3; $i <= $dist; $i++)
    $count[$i] = $count[$i - 1] + 
                 $count[$i - 2] + 
                 $count[$i - 3];
  
    return $count[$dist];
}
  
// Driver Code
$dist = 4;
echo printCountDP($dist);
  
// This code is contributed by anuj_67.
?>

Output :

659
Chapter 84. Count number of ways to cover a distance

This article is contributed by Vignesh Venkatesan. Please write comments if you find any-
thing incorrect, or you want to share more information about the topic discussed above
Improved By : Sam007, vt_m

Source

https://www.geeksforgeeks.org/count-number-of-ways-to-cover-a-distance/

660
Chapter 85

Count number of ways to fill a


“n x 4” grid using “1 x 4” tiles

Count number of ways to fill a ”n x 4” grid using ”1 x 4” tiles - GeeksforGeeks


Given a number n, count number of ways to fill a n x 4 grid using 1 x 4 tiles.
Examples:

Input : n = 1
Output : 1

Input : n = 2
Output : 1
We can only place both tiles horizontally

Input : n = 3
Output : 1
We can only place all tiles horizontally.

Input : n = 4
Output : 2
The two ways are :
1) Place all tiles horizontally
2) Place all tiles vertically.

Input : n = 5
Output : 3
We can fill a 5 x 4 grid in following ways :
1) Place all 5 tiles horizontally
2) Place first 4 vertically and 1 horizontally.
3) Place first 1 horizontally and 4 horizontally.

661
Chapter 85. Count number of ways to fill a “n x 4” grid using “1 x 4” tiles

This problem is mainly an extension of this tiling problem


Let “count(n)” be the count of ways to place tiles on a “n x 4” grid, following two
cases arise when we place the first tile.

1. Place the first tile horizontally : If we place first tile horizontally, the problem
reduces to “count(n-1)”
2. Place the first tile vertically : If we place first tile vertically, then we must place
3 more tiles vertically. So the problem reduces to “count(n-4)”

Therefore, count(n) can be written as below.

count(n) = 1 if n = 1 or n = 2 or n = 3
count(n) = 2 if n = 4
count(n) = count(n-1) + count(n-4)

This recurrence is similar to Fibonacci Numbers and can be solved using Dynamic program-
ming.

662
Chapter 85. Count number of ways to fill a “n x 4” grid using “1 x 4” tiles

C/C++

// C++ program to count of ways to place 1 x 4 tiles


// on n x 4 grid.
#include<iostream>
using namespace std;
  
// Returns count of count of ways to place 1 x 4 tiles
// on n x 4 grid.
int count(int n)
{
    // Create a table to store results of subproblems
    // dp[i] stores count of ways for i x 4 grid.
    int dp[n+1];
    dp[0] = 0;
  
    // Fill the table from d[1] to dp[n]
    for (int i=1; i<=n; i++)
    {
        // Base cases
        if (i >= 1 && i <= 3)
            dp[i] = 1;
        else if (i==4)
            dp[i] = 2 ;
  
        else 
            // dp(i-1) : Place first tile horizontally
            // dp(n-4) : Place first tile vertically
            //           which means 3 more tiles have
            //           to be placed vertically.
            dp[i] = dp[i-1] + dp[i-4];
    }
  
    return dp[n];
}
  
// Driver program to test above
int main()
{
    int n = 5;
    cout << "Count of ways is " << count(n);
    return 0;
}

Java

// Java program to count of ways to place 1 x 4 tiles

663
Chapter 85. Count number of ways to fill a “n x 4” grid using “1 x 4” tiles

// on n x 4 grid
import java.io.*;
  
class Grid 

    // Function that count the number of ways to place 1 x 4 tiles
    // on n x 4 grid.
    static int count(int n)
    {
        // Create a table to store results of sub-problems
        // dp[i] stores count of ways for i x 4 grid.
        int[] dp = new int[n+1];
        dp[0] = 0;
        // Fill the table from d[1] to dp[n]
        for(int i=1;i<=n;i++)
        {
            // Base cases
            if (i >= 1 && i <= 3)
                dp[i] = 1;
            else if (i==4)
                dp[i] = 2 ;
  
            else
            {
                    // dp(i-1) : Place first tile horizontally
                    // dp(i-4) : Place first tile vertically
                    //         which means 3 more tiles have
                    //         to be placed vertically.
                    dp[i] = dp[i-1] + dp[i-4];
            }
        }
        return dp[n];
    }
      
    // Driver program
    public static void main (String[] args)
    {
        int n = 5;
        System.out.println("Count of ways is: " + count(n));
    }
}
  
// Contributed by Pramod Kumar

Python

# Python program to count of ways to place 1 x 4 tiles


# on n x 4 grid.

664
Chapter 85. Count number of ways to fill a “n x 4” grid using “1 x 4” tiles

  
# Returns count of count of ways to place 1 x 4 tiles
# on n x 4 grid.
def count(n):
  
    # Create a table to store results of subproblems
    # dp[i] stores count of ways for i x 4 grid.
    dp = [0 for _ in range(n+1)]
  
    # Fill the table from d[1] to dp[n]
    for i in range(1,n+1):
  
        # Base cases
        if i <= 3:
            dp[i] = 1
        elif i == 4:
            dp[i] = 2
        else:
            # dp(i-1) : Place first tile horizontally
            # dp(n-4) : Place first tile vertically
            #           which means 3 more tiles have
            #           to be placed vertically.
            dp[i] = dp[i-1] + dp[i-4]
  
    return dp[n]
  
# Driver code to test above
n = 5
print ("Count of ways is"),
print (count(n))

C#

// C# program to count of ways 


// to place 1 x 4 tiles on
// n x 4 grid
using System;
  
class GFG
{
      
    // Function that count the number 
    // of ways to place 1 x 4 tiles
    // on n x 4 grid.
    static int count(int n)
    {
          
        // Create a table to store results

665
Chapter 85. Count number of ways to fill a “n x 4” grid using “1 x 4” tiles

        // of sub-problems dp[i] stores


        // count of ways for i x 4 grid.
        int[] dp = new int[n + 1];
        dp[0] = 0;
          
        // Fill the table from d[1]
        // to dp[n]
        for(int i = 1; i <= n; i++)
        {
              
            // Base cases
            if (i >= 1 && i <= 3)
                dp[i] = 1;
            else if (i == 4)
                dp[i] = 2 ;
  
            else
            {
                  
                // dp(i-1) : Place first tile
                // horizontally dp(i-4) : 
                // Place first tile vertically
                // which means 3 more tiles have
                // to be placed vertically.
                dp[i] = dp[i - 1] + 
                        dp[i - 4];
            }
        }
        return dp[n];
    }
      
    // Driver Code
    public static void Main ()
    {
        int n = 5;
        Console.WriteLine("Count of ways is: "
                           + count(n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program to count of ways to 
// place 1 x 4 tiles on n x 4 grid.
  

666
Chapter 85. Count number of ways to fill a “n x 4” grid using “1 x 4” tiles

// Returns count of count of ways 


// to place 1 x 4 tiles
// on n x 4 grid.
function countt($n)
{
      
    // Create a table to store
    // results of subproblems
    // dp[i] stores count of 
    // ways for i x 4 grid.
    $dp[$n + 1] = 0;
    $dp[0] = 0;
  
    // Fill the table
    // from d[1] to dp[n]
    for ($i = 1; $i <= $n; $i++)
    {
          
        // Base cases
        if ($i >= 1 && $i <= 3)
            $dp[$i] = 1;
        else if ($i == 4)
            $dp[$i] = 2 ;
  
        else
            // dp(i-1) : Place first tile horizontally
            // dp(n-4) : Place first tile vertically
            //             which means 3 more tiles have
            //             to be placed vertically.
            $dp[$i] = $dp[$i - 1] + $dp[$i - 4];
    }
  
    return $dp[$n];
}
  
    // Driver Code
    $n = 5;
    echo "Count of ways is " , countt($n);
  
// This code is contributed by nitin mittal.
?>

Output :

Count of ways is 3

Time Complexity : O(n)


Auxiliary Space : O(n)

667
Chapter 85. Count number of ways to fill a “n x 4” grid using “1 x 4” tiles

This article is contributed by Rajat Jha. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : Sam007, nitin mittal

Source

https://www.geeksforgeeks.org/count-number-of-ways-to-fill-a-n-x-4-grid-using-1-x-4-tiles/

668
Chapter 86

Count number of ways to jump


to reach end

Count number of ways to jump to reach end - GeeksforGeeks


Given an array of numbers where each element represents the max number of jumps that
can be made forward from that element. For each array element, count number of ways
jumps can be made from that element to reach the end of the array. If an element is 0,
then move cannot be made through that element. The element that cannot reach to the
end should have a count “-1”.
Examples:

Input : {3, 2, 0, 1}
Output : 2 1 -1 0
For 3 number of steps or jumps that
can be taken are 1, 2 or 3. The different ways are:
3 -> 2 -> 1
3 -> 1

For 2 number of steps or jumps that


can be taken are 1, or 2. The different ways are:
2 -> 1

For 0 number of steps or jumps that


can be taken are 0.
One cannot move forward from this point.

For 1 number of steps or jumps that


can be taken are 1. But the element is at
the end so no jump is required.

669
Chapter 86. Count number of ways to jump to reach end

Input : {1, 3, 5, 8, 9, 1, 0, 7, 6, 8, 9}
Output : 52 52 28 16 8 -1 -1 4 2 1 0

This problem is a variation of Minimum number of jumps to reach end(Method 3). Here we
need to count all ways to reach end from every cell.
The solution is a modified version of the solution to the problem of Minimum number of
jumps to reach end(Method 3).
This problem aims to count the different ways to jump from each element so as to reach to
the end. For each element the count is being calculated by adding the counts of all those
forward elements that can reach to the end and to which the current element could reach +
1(if the element can directly reach to the end).
Algorithm:

countWays(arr, n)
Initialize array count_jump[n] = {0}

count_jump[n-1] = 0
for i = n-2 to 0
if arr[i] >= (n-i-1)
count_jump[i]++
for j=i+1; j < n-1 && j <= arr[i]+i; i++
if count_jump[j] != -1
count_jump[i] += count_jump[j]
if count_jump[i] == 0
count_jump[i] = -1

for i = 0 to n-1
print count_jump[i]

C++

// C++ implementation to count number


// of ways to jump to reach end
#include <bits/stdc++.h>
using namespace std;
  
// function to count ways to jump to
// reach end for each array element
void countWaysToJump(int arr[], int n)
{
    // count_jump[i] store number of ways
    // arr[i] can reach to the end
    int count_jump[n];
    memset(count_jump, 0, sizeof(count_jump));
  

670
Chapter 86. Count number of ways to jump to reach end

    // Last element does not require to jump.


    // Count ways to jump for remaining
    // elements
    for (int i=n-2; i>=0; i--)
    {
        // if the element can directly
        // jump to the end
        if (arr[i] >= n - i - 1)
            count_jump[i]++;
  
        // add the count of all the elements
        // that can reach to end and arr[i] can
        // reach to them
        for (int j=i+1; j < n-1 && j <= arr[i] + i; j++)
  
            // if element can reach to end then add
            // its count to count_jump[i]
            if (count_jump[j] != -1)
                 count_jump[i] += count_jump[j];
  
        // if arr[i] cannot reach to the end
        if (count_jump[i] == 0)
            count_jump[i] = -1;
    }
  
    // print count_jump for each
    // array element
    for (int ai=0; i<n; i++)
        cout << count_jump[i] << " ";
}
  
// Driver program to test above
int main()
{
    int arr[] = {1, 3, 5, 8, 9, 1, 0, 7, 6, 8, 9};
    int n = sizeof(arr) / sizeof(arr[0]);
    countWaysToJump(arr, n);
    return 0;
}

Java

// Java implementation to count number


// of ways to jump to reach end
import java.util.Arrays;
  
class GFG {
      

671
Chapter 86. Count number of ways to jump to reach end

    // function to count ways to jump to


    // reach end for each array element
    static void countWaysToJump(int arr[], int n)
    {
          
        // count_jump[i] store number of ways
        // arr[i] can reach to the end
        int count_jump[] = new int[n];
        Arrays.fill(count_jump, 0);
      
        // Last element does not require to jump.
        // Count ways to jump for remaining
        // elements
        for (int i = n-2; i >= 0; i--)
        {
              
            // if the element can directly
            // jump to the end
            if (arr[i] >= n - i - 1)
                count_jump[i]++;
      
            // add the count of all the elements
            // that can reach to end and arr[i] can
            // reach to them
            for (int j = i+1; j < n-1 && j <= arr[i] + i; j++)
      
                // if element can reach to end then add
                // its count to count_jump[i]
                if (count_jump[j] != -1)
                    count_jump[i] += count_jump[j];
      
            // if arr[i] cannot reach to the end
            if (count_jump[i] == 0)
                count_jump[i] = -1;
        }
      
        // print count_jump for each
        // array element
        for (int i = 0; i < n; i++)
            System.out.print(count_jump[i] + " ");
    }
      
    //driver code
    public static void main (String[] args)
    {
          
        int arr[] = {1, 3, 5, 8, 9, 1, 0, 7, 6, 8, 9};
        int n = arr.length;

672
Chapter 86. Count number of ways to jump to reach end

          
        countWaysToJump(arr, n);
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python3 implementation to count 


# number of ways to jump to reach end
  
# Function to count ways to jump to
# reach end for each array element
def countWaysToJump(arr, n):
  
    # count_jump[i] store number of ways
    # arr[i] can reach to the end
    count_jump = [0 for i in range(n)]
  
    # Last element does not require 
    # to jump. Count ways to jump for 
    # remaining elements
    for i in range(n - 2, -1, -1):
      
        # if the element can directly
        # jump to the end
        if (arr[i] >= n - i - 1):
            count_jump[i] += 1
  
        # Add the count of all the elements
        # that can reach to end and arr[i] 
        # can reach to them
        j = i + 1
        while(j < n-1 and j <= arr[i] + i):
  
            # if element can reach to end then 
            # add its count to count_jump[i]
            if (count_jump[j] != -1):
                count_jump[i] += count_jump[j]
            j += 1
              
        # if arr[i] cannot reach to the end
        if (count_jump[i] == 0):
            count_jump[i] = -1
      
  
    # print count_jump for each

673
Chapter 86. Count number of ways to jump to reach end

    # array element


    for i in range(n):
        print(count_jump[i], end = " ")
  
# Driver code
arr = [1, 3, 5, 8, 9, 1, 0, 7, 6, 8, 9]
n = len(arr)
countWaysToJump(arr, n)
  
# This code is contributed by Anant Agarwal.

Output:

52 52 28 16 8 -1 -1 4 2 1 0

Time Complexity: O(n2 ) in worst case.

Source

https://www.geeksforgeeks.org/count-number-ways-jump-reach-end/

674
Chapter 87

Count number of ways to


partition a set into k subsets

Count number of ways to partition a set into k subsets - GeeksforGeeks


Given two numbers n and k where n represents number of elements in a set, find number of
ways to partition the set into k subsets.
Example:

Input: n = 3, k = 2
Output: 3
Explanation: Let the set be {1, 2, 3}, we can partition
it into 2 subsets in following ways
{{1,2}, {3}}, {{1}, {2,3}}, {{1,3}, {2}}

Input: n = 3, k = 1
Output: 1
Explanation: There is only one way {{1, 2, 3}}

We strongly recommend you to minimize your browser and try this yourself
first.
Let S(n, k) be total number of partitions of n elements into k sets. Value of S(n, k) can be
defined recursively as,

S(n, k) = k*S(n-1, k) + S(n-1, k-1)

S(n, k) is called Stirling numbers of the second kind

How does above recursive formula work?

675
Chapter 87. Count number of ways to partition a set into k subsets

When we add a (n+1)’th element to k partitions, there are two possibilities.


1) It is added as a single element set to existing partitions, i.e, S(n, k-1)
2) It is added to all sets of every partition, i.e., k*S(n, k)
Therefore S(n+1, k) = k*S(n, k) + S(n, k-1) which means S(n, k) = k*S(n-1, k) + S(n-1,
k-1)
Below is recursive solution based on above formula.

C++

// A C++ program to count number of partitions


// of a set with n elements into k subsets
#include<iostream>
using namespace std;
  
// Returns count of different partitions of n
// elements in k subsets
int countP(int n, int k)
{
  // Base cases
  if (n == 0 || k == 0 || k > n)
     return 0;
  if (k == 1 || k == n)
      return 1;
  
  // S(n+1, k) = k*S(n, k) + S(n, k-1)
  return  k*countP(n-1, k) + countP(n-1, k-1);
}
  
// Driver program
int main()
{
   cout <<  countP(3, 2);
   return 0;
}

Java

// Java  program to count number 


// of partitions of a set with 
// n elements into k subsets
import java.io.*;
  
class GFG
{
    // Returns count of different 
    // partitions of n elements in

676
Chapter 87. Count number of ways to partition a set into k subsets

    // k subsets
    public static int countP(int n, int k)
    {
       // Base cases
       if (n == 0 || k == 0 || k > n)
          return 0;
       if (k == 1 || k == n)
          return 1;
  
       // S(n+1, k) = k*S(n, k) + S(n, k-1)
       return (k * countP(n - 1, k) 
              + countP(n - 1, k - 1));
    }
  
    // Driver program
    public static void main(String args[])
    {
       System.out.println(countP(3, 2));
  
    }
}
  
//This code is contributed by Anshika Goyal.

C#

// C# program to count number 


// of partitions of a set with 
// n elements into k subsets
using System;
  
class GFG {
      
    // Returns count of different 
    // partitions of n elements in
    // k subsets
    public static int countP(int n, int k)
    {
          
        // Base cases
        if (n == 0 || k == 0 || k > n)
            return 0;
        if (k == 1 || k == n)
            return 1;
      
        // S(n+1, k) = k*S(n, k) + S(n, k-1)
        return (k * countP(n - 1, k) 
                + countP(n - 1, k - 1));

677
Chapter 87. Count number of ways to partition a set into k subsets

    }
  
    // Driver program
    public static void Main()
    {
        Console.WriteLine(countP(3, 2));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// A PHP program to count
// number of partitions of 
// a set with n elements 
// into k subsets
  
// Returns count of different
// partitions of n elements 
// in k subsets
function countP($n, $k)
{
    // Base cases
    if ($n == 0 || $k == 0 || $k > $n)
        return 0;
    if ($k == 1 || $k == $n)
        return 1;
      
    // S(n+1, k) = k*S(n, k) 
    // + S(n, k-1)
    return $k * countP($n - 1, $k) + 
            countP($n - 1, $k - 1);
}
  
    // Driver Code
    echo countP(3, 2);
  
// This code is contributed by aj_36
?>

Output:

The time complexity of above recursive solution is exponential. The solution can be op-
timized as there are overlapping subproblems. For example, below is recursion tree of
countP(10,7). The subproblem countP(8,6) or CP(8,6) is called multiple times.

678
Chapter 87. Count number of ways to partition a set into k subsets

CP() represents countP()

CP(10,7)
/ \
CP(9,7) CP(9,6)
/ \ / \
CP(8,7) CP(8,6) CP(8,6) CP(8,5)
/ \ / \ / \ / \

Partial Recursion Tree for countP(10, 7)


to highlight overlapping subproblems.

So this problem has both properties (see this and this) of a dynamic programming problem.
Like other typical Dynamic Programming(DP) problems, recomputations of same subprob-
lems can be avoided by constructing a temporary array dp[][] in bottom up manner using
the above recursive formula.
Below is C++ implementation of Dynamic Programming Solution.

// A Dynamic Programming based C++ program to count


// number of partitions of a set with n elements
// into k subsets
#include<iostream>
using namespace std;
  
// Returns count of different partitions of n
// elements in k subsets
int countP(int n, int k)
{
  // Table to store results of subproblems
  int dp[n+1][k+1];
  
  // Base cases
  for (int i=0; i<=n; i++)
     dp[i][0] = 0;
  for (int i=0; i<=k; i++)
     dp[0][k] = 0;
  
  // Fill rest of the entries in dp[][]
  // in bottom up manner
  for (int i=1; i<=n; i++)
     for (int j=1; j<=i; j++)
       if (j == 1 || i == j)
          dp[i][j] = 1;
       else
          dp[i][j] = j*dp[i-1][j] + dp[i-1][j-1];
  

679
Chapter 87. Count number of ways to partition a set into k subsets

  return dp[n][k];
}
  
// Driver program
int main()
{
   cout <<  countP(5, 2);
   return 0;
}

Output:

15

Time Complexity: O(n x k)


Auxiliary Space: O(n x k)
Similar Article: Bell Numbers
This article is contributed by Rajeev Agrawal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : jit_t, vt_m

Source

https://www.geeksforgeeks.org/count-number-of-ways-to-partition-a-set-into-k-subsets/

680
Chapter 88

Count number of ways to reach


a given score in a game

Count number of ways to reach a given score in a game - GeeksforGeeks


Consider a game where a player can score 3 or 5 or 10 points in a move. Given a total score
n, find number of ways to reach the given score.
Examples:

Input: n = 20
Output: 4
There are following 4 ways to reach 20
(10, 10)
(5, 5, 10)
(5, 5, 5, 5)
(3, 3, 3, 3, 3, 5)

Input: n = 13
Output: 2
There are following 2 ways to reach 13
(3, 5, 5)
(3, 10)

This problem is a variation of coin change problem and can be solved in O(n) time and O(n)
auxiliary space.
The idea is to create a table of size n+1 to store counts of all scores from 0 to n. For every
possible move (3, 5 and 10), increment values in table.

C++

681
Chapter 88. Count number of ways to reach a given score in a game

// A C++ program to count number of 


// possible ways to a given score
// can be reached in a game where a 
// move can earn 3 or 5 or 10
#include <iostream>
using namespace std;
  
// Returns number of ways
// to reach score n
int count(int n)
{
    // table[i] will store count 
    // of solutions for value i.
    int table[n + 1], i;
  
    // Initialize all table
    // values as 0
    for(int j = 0; j < n + 1; j++)
            table[j] = 0;
  
    // Base case (If given value is 0)
    table[0] = 1;
  
    // One by one consider given 3 moves 
    // and update the table[] values after
    // the index greater than or equal to 
    // the value of the picked move
    for (i = 3; i <= n; i++)
    table[i] += table[i - 3];
      
    for (i = 5; i <= n; i++)
    table[i] += table[i - 5];
      
    for (i = 10; i <= n; i++)
    table[i] += table[i - 10];
  
    return table[n];
}
  
// Driver Code
int main(void)
{
    int n = 20;
    cout << "Count for " << n 
         << " is " << count(n) << endl;
  
    n = 13;
    cout <<"Count for "<< n<< " is " 

682
Chapter 88. Count number of ways to reach a given score in a game

         << count(n) << endl;


    return 0;
}
  
// This code is contributed 
// by Shivi_Aggarwal 

// A C program to count number of possible ways to a given score


// can be reached in a game where a move can earn 3 or 5 or 10
#include <stdio.h>
  
// Returns number of ways to reach score n
int count(int n)
{
    // table[i] will store count of solutions for
    // value i.
    int table[n+1], i;
  
    // Initialize all table values as 0
    memset(table, 0, sizeof(table));
  
    // Base case (If given value is 0)
    table[0] = 1;
  
    // One by one consider given 3 moves and update the table[]
    // values after the index greater than or equal to the
    // value of the picked move
    for (i=3; i<=n; i++)
       table[i] += table[i-3];
    for (i=5; i<=n; i++)
       table[i] += table[i-5];
    for (i=10; i<=n; i++)
       table[i] += table[i-10];
  
    return table[n];
}
  
  
// Driver program
int main(void)
{
    int n = 20;
    printf("Count for %d is %d\n", n, count(n));
  
    n = 13;
    printf("Count for %d is %d", n, count(n));

683
Chapter 88. Count number of ways to reach a given score in a game

    return 0;
}

Java

// Java program to count number of 


// possible ways to a given score
// can be reached in a game where 
// a move can earn 3 or 5 or 10
import java.util.Arrays;
  
class GFG
{
    // Returns number of ways to reach score n
    static int count(int n)
    {
        // table[i] will store count of solutions for
        // value i.
        int table[] = new int[n + 1], i;
      
        // Initialize all table values as 0
        Arrays.fill(table, 0);
      
        // Base case (If given value is 0)
        table[0] = 1;
      
        // One by one consider given 3 
        // moves and update the table[]
        // values after the index greater 
        // than or equal to the value of 
        // the picked move
        for (i = 3; i <= n; i++)
            table[i] += table[i - 3];
        for (i = 5; i <= n; i++)
            table[i] += table[i - 5];
        for (i = 10; i <= n; i++)
            table[i] += table[i - 10];
      
        return table[n];
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int n = 20;
        System.out.println("Count for "+n+" is "+count(n));
      
        n = 13;

684
Chapter 88. Count number of ways to reach a given score in a game

        System.out.println("Count for "+n+" is "+count(n));


    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python program to count number of possible ways to a given


# score can be reached in a game where a move can earn 3 or
# 5 or 10.
  
# Returns number of ways to reach score n.
def count(n):
  
    # table[i] will store count of solutions for value i.
    # Initialize all table values as 0.
    table = [0 for i in range(n+1)]
  
    # Base case (If given value is 0)
    table[0] = 1
  
    # One by one consider given 3 moves and update the
    # table[] values after the index greater than or equal
    # to the value of the picked move.
    for i in range(3, n+1):
        table[i] += table[i-3]
    for i in range(5, n+1):
        table[i] += table[i-5]
    for i in range(10, n+1):
        table[i] += table[i-10]
  
    return table[n]
  
# Driver Program
n = 20
print('Count for', n, 'is', count(n))
  
n = 13
print('Count for', n, 'is', count(n))
  
# This code is contributed by Soumen Ghosh

C#

// C# program to count number of 


// possible ways to a given score

685
Chapter 88. Count number of ways to reach a given score in a game

// can be reached in a game where 


// a move can earn 3 or 5 or 10
using System;
  
class GFG {
      
    // Returns number of ways to reach 
    // score n
    static int count(int n)
    {
          
        // table[i] will store count
        // of solutions for value i.
        int []table = new int[n + 1];
      
        // Initialize all table values
        // as 0
        for(int j = 0; j < n+1; j++)
            table[j] = 0;
          
        // Base case (If given value is 0)
        table[0] = 1;
      
        // One by one consider given 3 
        // moves and update the table[]
        // values after the index greater 
        // than or equal to the value of 
        // the picked move
        for (int i = 3; i <= n; i++)
            table[i] += table[i - 3];
        for (int i = 5; i <= n; i++)
            table[i] += table[i - 5];
        for (int i = 10; i <= n; i++)
            table[i] += table[i - 10];
      
        return table[n];
    }
      
    // Driver code
    public static void Main () 
    {
        int n = 20;
        Console.WriteLine("Count for "
             + n + " is " + count(n));
      
        n = 13;
        Console.Write("Count for "
            + n + " is " + count(n));

686
Chapter 88. Count number of ways to reach a given score in a game

    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to count number of 
// possible ways to a given score 
// can be reached in a game where 
// a move can earn 3 or 5 or 10 
// Returns number of ways to reach
// score n 
function counts($n) 

    // table[i] will store count 
    // of solutions for value i. 
  
    // Initialize all table 
    // values as 0 
    for($j = 0; $j < $n + 1; $j++) 
            $table[$j] = 0; 
  
    // Base case (If given value is 0) 
    $table[0] = 1; 
  
    // One by one consider given 3 moves
    // and update the table[] values after
    // the index greater than or equal to 
    // the value of the picked move 
    for ($i = 3; $i <= $n; $i++) 
    $table[$i] += $table[$i - 3]; 
      
    for ($i = 5; $i <= $n; $i++) 
    $table[$i] += $table[$i - 5]; 
      
    for ($i = 10; $i <= $n; $i++) 
    $table[$i] += $table[$i - 10]; 
  
    return $table[$n]; 

  
// Driver Code 
$n = 20; 
echo "Count for ";
echo($n);
echo (" is "); 

687
Chapter 88. Count number of ways to reach a given score in a game

echo counts($n); 
  
$n = 13;
echo ("\n") ;
echo "Count for ";
echo($n);
echo (" is " ); 
echo counts($n); 
  
// This code is contributed 
// by Shivi_Aggarwal 
?>

Output:

Count for 20 is 4
Count for 13 is 2

Exercise: How to count score when (10, 5, 5), (5, 5, 10) and (5, 10, 5) are considered
as different sequences of moves. Similarly, (5, 3, 3), (3, 5, 3) and (3, 3, 5) are considered
different.
This article is contributed by Rajeev Arora. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal, Shivi_Aggarwal

Source

https://www.geeksforgeeks.org/count-number-ways-reach-given-score-game/

688
Chapter 89

Count number of ways to reach


destination in a Maze

Count number of ways to reach destination in a Maze - GeeksforGeeks


Given a maze with obstacles, count number of paths to reach rightmost-bottommost cell
from topmost-leftmost cell. A cell in given maze has value -1 if it is a blockage or dead end,
else 0.
From a given cell, we are allowed to move to cells (i+1, j) and (i, j+1) only.
Examples:

Input: maze[R][C] = {{0, 0, 0, 0},


{0, -1, 0, 0},
{-1, 0, 0, 0},
{0, 0, 0, 0}};
Output: 4
There are four possible paths as shown in
below diagram.

This problem is an extension of below problem.


Backtracking | Set 2 (Rat in a Maze)
In this post a different solution is discussed that can be used to solve the above Rat in a
Maze problem also.
The idea is to modify the given grid[][] so that grid[i][j] contains count of paths to
reach (i, j) from (0, 0) if (i, j) is not a blockage, else grid[i][j] remains -1.

We can recursively compute grid[i][j] using below

689
Chapter 89. Count number of ways to reach destination in a Maze

formula and finally return grid[R-1][C-1]

// If current cell is a blockage


if (maze[i][j] == -1)
maze[i][j] = -1; // Do not change

// If we can reach maze[i][j] from maze[i-1][j]


// then increment count.
else if (maze[i-1][j] > 0)
maze[i][j] = (maze[i][j] + maze[i-1][j]);

// If we can reach maze[i][j] from maze[i][j-1]


// then increment count.
else if (maze[i][j-1] > 0)
maze[i][j] = (maze[i][j] + maze[i][j-1]);

Below is the implementation of above idea.

C++

// C++ program to count number of paths in a maze


// with obstacles.
#include<bits/stdc++.h>
using namespace std;
#define R 4
#define C 4
  
// Returns count of possible paths in a maze[R][C]
// from (0,0) to (R-1,C-1)
int countPaths(int maze[][C])
{
    // If the initial cell is blocked, there is no
    // way of moving anywhere
    if (maze[0][0]==-1)
        return 0;
  
    // Initializing the leftmost column
    for (int i=0; i<R; i++)
    {
        if (maze[i][0] == 0)
            maze[i][0] = 1;
  
        // If we encounter a blocked cell in leftmost
        // row, there is no way of visiting any cell
        // directly below it.
        else
            break;

690
Chapter 89. Count number of ways to reach destination in a Maze

    }
  
    // Similarly initialize the topmost row
    for (int i=1; i<C; i++)
    {
        if (maze[0][i] == 0)
            maze[0][i] = 1;
  
        // If we encounter a blocked cell in bottommost
        // row, there is no way of visiting any cell
        // directly below it.
        else
            break;
    }
  
    // The only difference is that if a cell is -1,
    // simply ignore it else recursively compute
    // count value maze[i][j]
    for (int i=1; i<R; i++)
    {
        for (int j=1; j<C; j++)
        {
            // If blockage is found, ignore this cell 
            if (maze[i][j] == -1)
                continue;
  
            // If we can reach maze[i][j] from maze[i-1][j]
            // then increment count.
            if (maze[i-1][j] > 0)
                maze[i][j] = (maze[i][j] + maze[i-1][j]);
  
            // If we can reach maze[i][j] from maze[i][j-1]
            // then increment count.
            if (maze[i][j-1] > 0)
                maze[i][j] = (maze[i][j] + maze[i][j-1]);
        }
    }
  
    // If the final cell is blocked, output 0, otherwise
    // the answer
    return (maze[R-1][C-1] > 0)? maze[R-1][C-1] : 0;
}
  
// Driver code
int main()
{
    int maze[R][C] =  {{0,  0, 0, 0},
                       {0, -1, 0, 0},

691
Chapter 89. Count number of ways to reach destination in a Maze

                       {-1, 0, 0, 0},
                       {0,  0, 0, 0}};
    cout << countPaths(maze);
    return 0;
}

Java

// java program to count number of paths in a maze


// with obstacles.
import java.io.*;
  
class GFG 
{
    static int R = 4;
    static int C = 4;
      
    // Returns count of possible paths in 
    // a maze[R][C] from (0,0) to (R-1,C-1)
    static int countPaths(int maze[][])
    {
        // If the initial cell is blocked, 
        // there is no way of moving anywhere
        if (maze[0][0]==-1)
            return 0;
      
        // Initializing the leftmost column
        for (int i = 0; i < R; i++)
        {
            if (maze[i][0] == 0)
                maze[i][0] = 1;
      
            // If we encounter a blocked cell 
            // in leftmost row, there is no way 
            // of visiting any cell directly below it.
            else
                break;
        }
      
        // Similarly initialize the topmost row
        for (int i =1 ; i< C ; i++)
        {
            if (maze[0][i] == 0)
                maze[0][i] = 1;
      
            // If we encounter a blocked cell in 
            // bottommost row, there is no way of 
            // visiting any cell directly below it.

692
Chapter 89. Count number of ways to reach destination in a Maze

            else
                break;
        }
      
        // The only difference is that if a cell 
        // is -1, simply ignore it else recursively 
        // compute count value maze[i][j]
        for (int i = 1; i < R; i++)
        {
            for (int j = 1; j <C ; j++)
            {
                // If blockage is found, 
                // ignore this cell 
                if (maze[i][j] == -1)
                    continue;
      
                // If we can reach maze[i][j] from 
                // maze[i-1][j] then increment count.
                if (maze[i - 1][j] > 0)
                    maze[i][j] = (maze[i][j] + 
                                 maze[i - 1][j]);
      
                // If we can reach maze[i][j] from
                //  maze[i][j-1] then increment count.
                if (maze[i][j - 1] > 0)
                    maze[i][j] = (maze[i][j] + 
                                  maze[i][j - 1]);
            }
        }
      
        // If the final cell is blocked, 
        // output 0, otherwise the answer
        return (maze[R - 1][C - 1] > 0) ? 
                maze[R - 1][C - 1] : 0;
    }
      
    // Driver code
  
    public static void main (String[] args) 
    {
        int maze[][] = {{0, 0, 0, 0},
                       {0, -1, 0, 0},
                       {-1, 0, 0, 0},
                       {0, 0, 0, 0}};
        System.out.println (countPaths(maze));
      
    }
  

693
Chapter 89. Count number of ways to reach destination in a Maze

}
  
// This code is contributed by vt_m

C#

// C# program to count number of paths in a maze


// with obstacles.
using System;
  
class GFG {
      
    static int R = 4;
    static int C = 4;
      
    // Returns count of possible paths in 
    // a maze[R][C] from (0,0) to (R-1,C-1)
    static int countPaths(int [,]maze)
    {
          
        // If the initial cell is blocked, 
        // there is no way of moving anywhere
        if (maze[0,0]==-1)
            return 0;
      
        // Initializing the leftmost column
        for (int i = 0; i < R; i++)
        {
            if (maze[i,0] == 0)
                maze[i,0] = 1;
      
            // If we encounter a blocked cell 
            // in leftmost row, there is no way 
            // of visiting any cell directly below it.
            else
                break;
        }
      
        // Similarly initialize the topmost row
        for (int i =1 ; i< C ; i++)
        {
            if (maze[0,i] == 0)
                maze[0,i] = 1;
      
            // If we encounter a blocked cell in 
            // bottommost row, there is no way of 
            // visiting any cell directly below it.
            else

694
Chapter 89. Count number of ways to reach destination in a Maze

                break;
        }
      
        // The only difference is that if a cell 
        // is -1, simply ignore it else recursively 
        // compute count value maze[i][j]
        for (int i = 1; i < R; i++)
        {
            for (int j = 1; j <C ; j++)
            {
                // If blockage is found, 
                // ignore this cell 
                if (maze[i,j] == -1)
                    continue;
      
                // If we can reach maze[i][j] from 
                // maze[i-1][j] then increment count.
                if (maze[i - 1,j] > 0)
                    maze[i,j] = (maze[i,j] + 
                                maze[i - 1,j]);
      
                // If we can reach maze[i][j] from
                // maze[i][j-1] then increment count.
                if (maze[i,j - 1] > 0)
                    maze[i,j] = (maze[i,j] + 
                                maze[i,j - 1]);
            }
        }
      
        // If the final cell is blocked, 
        // output 0, otherwise the answer
        return (maze[R - 1,C - 1] > 0) ? 
                maze[R - 1,C - 1] : 0;
    }
      
    // Driver code
    public static void Main () 
    {
        int [,]maze = { {0, 0, 0, 0},
                        {0, -1, 0, 0},
                        {-1, 0, 0, 0},
                        {0, 0, 0, 0}};
                          
        Console.Write (countPaths(maze));
    }
  
}
  

695
Chapter 89. Count number of ways to reach destination in a Maze

// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to count number
// of paths in a maze with obstacles.
  
$R = 4;
$C = 4;
  
// Returns count of possible 
// paths in a maze[R][C]
// from (0,0) to (R-1,C-1)
function countPaths( $maze)
{
    global $R, $C;
      
    // If the initial cell is
    // blocked, there is no
    // way of moving anywhere
    if ($maze[0][0] == - 1)
        return 0;
  
    // Initializing the 
    // leftmost column
    for ( $i = 0; $i < $R; $i++)
    {
        if ($maze[$i][0] == 0)
            $maze[$i][0] = 1;
  
        // If we encounter a blocked
        // cell in leftmost row, 
        // there is no way of 
        // visiting any cell
        // directly below it.
        else
            break;
    }
  
    // Similarly initialize 
    // the topmost row
    for($i = 1; $i < $C; $i++)
    {
        if ($maze[0][$i] == 0)
            $maze[0][$i] = 1;
  
        // If we encounter a blocked

696
Chapter 89. Count number of ways to reach destination in a Maze

        // cell in bottommost row, 


        // there is no way of 
        // visiting any cell
        // directly below it.
        else
            break;
    }
  
    // The only difference is 
    // that if a cell is -1,
    // simply ignore it else
    // recursively compute
    // count value maze[i][j]
    for($i = 1; $i < $R; $i++)
    {
        for($j = 1; $j < $C; $j++)
        {
              
            // If blockage is found, 
            // ignore this cell 
            if ($maze[$i][$j] == -1)
                continue;
  
            // If we can reach maze[i][j] 
            // from maze[i-1][j]
            // then increment count.
            if ($maze[$i - 1][$j] > 0)
                $maze[$i][$j] = ($maze[$i][$j] + 
                           $maze[$i - 1][$j]);
  
            // If we can reach maze[i][j]
            // from maze[i][j-1]
            // then increment count.
            if ($maze[$i][$j - 1] > 0)
                $maze[$i][$j] = ($maze[$i][$j] + 
                             $maze[$i][$j - 1]);
        }
    }
  
    // If the final cell is 
    // blocked, output 0, 
    // otherwise the answer
    return ($maze[$R - 1][$C - 1] > 0) ?
            $maze[$R - 1][$C - 1] : 0;
}
  
    // Driver Code
    $maze = array(array(0, 0, 0, 0),

697
Chapter 89. Count number of ways to reach destination in a Maze

                  array(0, -1, 0, 0),


                  array(-1, 0, 0, 0),
                  array(0, 0, 0, 0));
    echo countPaths($maze);
  
// This code is contributed by anuj_67.
?>

Output:

Time Complexity : O(R x C)


Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/count-number-ways-reach-destination-maze/

698
Chapter 90

Count of AP (Arithmetic
Progression) Subsequences in an
array

Count of AP (Arithmetic Progression) Subsequences in an array - GeeksforGeeks


Given an array of n positive integers. The task is to count the number of Arithmetic
Progression subsequence in the array. Note: Empty sequence or single element sequence is
Arithmetic Progression. 1 <= arr[i] <= 1000000. Examples:

Input : arr[] = { 1, 2, 3 }
Output : 8
Arithmetic Progression subsequence from the
given array are: {}, { 1 }, { 2 }, { 3 }, { 1, 2 },
{ 2, 3 }, { 1, 3 }, { 1, 2, 3 }.

Input : arr[] = { 10, 20, 30, 45 }


Output : 12

Input : arr[] = { 1, 2, 3, 4, 5 }
Output : 23

Since empty sequence and single element sequence is also arithmetic progression, so we
initialize the answer with n(number of element in the array) + 1.
Now, we need to find the arithmetic progression subsequence of length greater than or equal
to 2. Let minimum and maximum of the array be minarr and maxarr respectively. Observe,
in all the arithmetic progression subsequences, the range of common difference will be from
(minarr – maxarr) to (maxarr – minarr). Now, for each common difference, say d, calculate
the subsequence of length greater than or equal to 2 using dynamic programming.
Let dp[i] be the number of subsequence that end with arr[i] and have common difference of

699
Chapter 90. Count of AP (Arithmetic Progression) Subsequences in an array

d. So,

The number of subsequence of length greater than or equal to 2 with common difference d
is sum of dp[i] – 1, 0 <= i = 2 with difference d. To speed up, store the sum of dp[j] with
arr[j] + d = arr[i] and j < i. Below is implementation of above idea :
C++

// C++ program to find number of AP


// subsequences in the given array
#include<bits/stdc++.h>
#define MAX 1000001
using namespace std;
  
int numofAP(int a[], int n)
{
    // initializing the minimum value and
    // maximum value of the array.
    int minarr = INT_MAX, maxarr = INT_MIN;
  
    // Finding the minimum and maximum
    // value of the array.
    for (int i = 0; i < n; i++)
    {
        minarr = min(minarr, a[i]);
        maxarr = max(maxarr, a[i]);
    }
  
    // dp[i] is going to store count of APs ending
    // with arr[i].
    // sum[j] is going to store sun of all dp[]'s
    // with j as an AP element.
    int dp[n], sum[MAX];
  
    // Initialize answer with n + 1 as single elements
    // and empty array are also DP.
    int ans = n + 1;
  
    // Traversing with all common difference.
    for (int d=(minarr-maxarr); d<=(maxarr-minarr); d++)
    {

700
Chapter 90. Count of AP (Arithmetic Progression) Subsequences in an array

        memset(sum, 0, sizeof sum);


  
        // Traversing all the element of the array.
        for (int i = 0; i < n; i++)
        {
            // Initialize dp[i] = 1.
            dp[i] = 1;
  
            // Adding counts of APs with given differences
            // and a[i] is last element.  
            // We consider all APs where an array element
            // is previous element of AP with a particular 
            // difference
            if (a[i] - d >= 1 && a[i] - d <= 1000000)
                dp[i] += sum[a[i] - d];
  
            ans += dp[i] - 1;
            sum[a[i]] += dp[i];
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    int arr[] = { 1, 2, 3 };
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << numofAP(arr, n) << endl;
    return 0;
}

Java

// Java program to find number of AP


// subsequences in the given array
import java.util.Arrays;
  
class GFG {
      
    static final int MAX = 1000001;
  
    static int numofAP(int a[], int n)
    {
          
        // initializing the minimum value and
        // maximum value of the array.

701
Chapter 90. Count of AP (Arithmetic Progression) Subsequences in an array

        int minarr = +2147483647;


        int maxarr = -2147483648;
  
        // Finding the minimum and maximum
        // value of the array.
        for (int i = 0; i < n; i++) {
            minarr = Math.min(minarr, a[i]);
            maxarr = Math.max(maxarr, a[i]);
        }
  
        // dp[i] is going to store count of 
        // APs ending with arr[i].
        // sum[j] is going to store sun of 
        // all dp[]'s with j as an AP element.
        int dp[] = new int[n];
        int sum[] = new int[MAX];
  
        // Initialize answer with n + 1 as 
        // single elements and empty array 
        // are also DP.
        int ans = n + 1;
  
        // Traversing with all common 
        // difference.
        for (int d = (minarr - maxarr); 
                d <= (maxarr - minarr); d++) 
        {
            Arrays.fill(sum, 0);
  
            // Traversing all the element 
            // of the array.
            for (int i = 0; i < n; i++) {
                  
                // Initialize dp[i] = 1.
                dp[i] = 1;
  
                // Adding counts of APs with
                // given differences and a[i] 
                // is last element.
                // We consider all APs where 
                // an array element is previous 
                // element of AP with a particular
                // difference
                if (a[i] - d >= 1 && 
                             a[i] - d <= 1000000)
                    dp[i] += sum[a[i] - d];
  
                ans += dp[i] - 1;

702
Chapter 90. Count of AP (Arithmetic Progression) Subsequences in an array

                sum[a[i]] += dp[i];
            }
        }
  
        return ans;
    }
      
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 1, 2, 3 };
        int n = arr.length;
          
        System.out.println(numofAP(arr, n));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python program to find number of AP


# subsequences in the given array
  
MAX = 1000001
  
def numofAP(a, n):
  
    # initializing the minimum value and
    # maximum value of the array.
    minarr = +2147483647
    maxarr = -2147483648
  
    # Finding the minimum and 
    # maximum value of the array.
    for i in range(n):
        minarr = min(minarr, a[i])
        maxarr = max(maxarr, a[i])
      
  
    # dp[i] is going to store count of APs ending
    # with arr[i].
    # sum[j] is going to store sun of all dp[]'s
    # with j as an AP element.
    dp = [0 for i in range(n + 1)]
      
  
    # Initialize answer with n + 1 as single 

703
Chapter 90. Count of AP (Arithmetic Progression) Subsequences in an array

    # elements and empty array are also DP.


    ans = n + 1
  
    # Traversing with all common difference.
    for d in range((minarr - maxarr), (maxarr - minarr) + 1):
        sum = [0 for i in range(MAX + 1)]
          
        # Traversing all the element of the array.
        for i in range(n):
          
            # Initialize dp[i] = 1.
            dp[i] = 1
  
            # Adding counts of APs with given differences
            # and a[i] is last element. 
            # We consider all APs where an array element
            # is previous element of AP with a particular 
            # difference
            if (a[i] - d >= 1 and a[i] - d <= 1000000):
                dp[i] += sum[a[i] - d]
  
            ans += dp[i] - 1
            sum[a[i]] += dp[i]
  
    return ans
  
# Driver code
arr = [ 1, 2, 3 ]
n = len(arr)
  
print(numofAP(arr, n))
  
# This code is contributed by Anant Agarwal.

C#

// C# program to find number of AP


// subsequences in the given array
using System;
  
class GFG {
      
    static int MAX = 1000001;
  
    // Function to find number of AP
    // subsequences in the given array
    static int numofAP(int []a, int n)
    {

704
Chapter 90. Count of AP (Arithmetic Progression) Subsequences in an array

          
        // initializing the minimum value and
        // maximum value of the array.
        int minarr = +2147483647;
        int maxarr = -2147483648;
        int i;
          
        // Finding the minimum and maximum
        // value of the array.
        for (i = 0; i < n; i++) 
        {
            minarr = Math.Min(minarr, a[i]);
            maxarr = Math.Max(maxarr, a[i]);
        }
  
        // dp[i] is going to store count of 
        // APs ending with arr[i].
        // sum[j] is going to store sun of 
        // all dp[]'s with j as an AP element.
        int []dp = new int[n];
        int []sum = new int[MAX];
  
        // Initialize answer with n + 1 as 
        // single elements and empty array 
        // are also DP.
        int ans = n + 1;
  
        // Traversing with all common 
        // difference.
        for (int d = (minarr - maxarr); 
                 d <= (maxarr - minarr); d++) 
        {
              
            for(i = 0; i < MAX; i++)
            sum[i]= 0;
          
            // Traversing all the element 
            // of the array.
            for ( i = 0; i < n; i++)
            {
                  
                // Initialize dp[i] = 1.
                dp[i] = 1;
  
                // Adding counts of APs with
                // given differences and a[i] 
                // is last element.
                // We consider all APs where 

705
Chapter 90. Count of AP (Arithmetic Progression) Subsequences in an array

                // an array element is previous 


                // element of AP with a particular
                // difference
                if (a[i] - d >= 1 && 
                    a[i] - d <= 1000000)
                    dp[i] += sum[a[i] - d];
  
                ans += dp[i] - 1;
                sum[a[i]] += dp[i];
            }
        }
  
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int []arr = {1, 2, 3};
        int n = arr.Length;
          
        Console.WriteLine(numofAP(arr, n));
    }
}
  
// This code is contributed by vt_m.

Output :

Improved By : vt_m

Source

https://www.geeksforgeeks.org/count-arithmetic-progression-subsequences-array/

706
Chapter 91

Count of Palindromic substrings


in an Index range

Count of Palindromic substrings in an Index range - GeeksforGeeks


Given a string str of small alphabetic characters other than this we will be given many
substrings of this string in form of index tuples. We need to find out the count of the
palindromic substrings in given substring range.
Examples:

Input : String str = "xyaabax"


Range1 = (3, 5)
Range2 = (2, 3)
Output : 4
3
For Range1, substring is "aba"
Count of palindromic substring in "aba" is
four : "a", "b", "aba", "a"
For Range2, substring is "aa"
Count of palindromic substring in "aa" is
3 : "a", "a", "aa"

Prerequisite :Count All Palindrome Sub-Strings in a String


We can solve this problem using dynamic programming. First we will make a 2D array
isPalin, isPalin[i][j] will be 1 if string(i..j) is a palindrome otherwise it will be 0. After
constructing isPalin we will construct another 2D array dp, dp[i][j] will tell the count of
palindromic substring in string(i..j)
Now we can write the relation among isPalin and dp values as shown below,

707
Chapter 91. Count of Palindromic substrings in an Index range

// isPalin[i][j] will be 1 if ith and jth characters


// are equal and mid substring str(i+1..j-1) is also
// a palindrome
isPalin[i][j] = (str[i] == str[j]) and
(isPalin[i + 1][j – 1])

// Similar to set theory we can write the relation among


// dp values as,
// dp[i][j] will be addition of number of palindromes from
// i to j-1 and i+1 to j subtracting palindromes from i+1
// to j-1 because they are counted twice once in dp[i][j-1]
// and then in dp[i + 1][j] plus 1 if str(i..j) is also a
// palindrome
dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1] +
isPalin[i][j];

Total time complexity of solution will be O(length ^ 2) for constructing dp array then O(1)
per query.

C/C++

// C++ program to query number of palindromic


// substrings of a string in a range
#include <bits/stdc++.h>
using namespace std;
#define M 50
  
// Utility method to construct the dp array
void constructDP(int dp[M][M], string str)
{
    int l = str.length();
  
    // declare 2D array isPalin, isPalin[i][j] will
    // be 1 if str(i..j) is palindrome
    int isPalin[l + 1][l + 1];
  
    // initialize dp and isPalin array by zeros
    for (int i = 0; i <= l; i++) {
        for (int j = 0; j <= l; j++) {
            isPalin[i][j] = dp[i][j] = 0;
        }
    }
  
    // loop for starting index of range
    for (int i = l - 1; i >= 0; i--) {
  

708
Chapter 91. Count of Palindromic substrings in an Index range

        // initialize value for one character strings as 1


        isPalin[i][i] = 1;
        dp[i][i] = 1;
  
        // loop for ending index of range
        for (int j = i + 1; j < l; j++) {
  
            /* isPalin[i][j] will be 1 if ith and
               jth characters are equal and mid
               substring str(i+1..j-1) is also a
               palindrome             */
            isPalin[i][j] = (str[i] == str[j] && (i + 1 > j - 1 || isPalin[i + 1][j - 1]));
  
            /* dp[i][j] will be addition of number
               of palindromes from i to j-1 and i+1
               to j subtracting palindromes from i+1
               to j-1 (as counted twice) plus 1 if
               str(i..j) is also a palindrome */
            dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1] + isPalin[i][j];
        }
    }
}
  
// method returns count of palindromic substring in range (l, r)
int countOfPalindromeInRange(int dp[M][M], int l, int r)
{
    return dp[l][r];
}
  
// Driver code to test above methods
int main()
{
    string str = "xyaabax";
  
    int dp[M][M];
    constructDP(dp, str);
  
    int l = 3;
    int r = 5;
  
    cout << countOfPalindromeInRange(dp, l, r);
    return 0;
}

Java

// Java program  to query number of palindromic


// substrings of a string in a range

709
Chapter 91. Count of Palindromic substrings in an Index range

import java.io.*;
  
class GFG {
    // Function to construct the dp array
    static void constructDp(int dp[][], String str)
    {
        int l = str.length();
  
        // declare 2D array isPalin, isPalin[i][j] will
        // be 1 if str(i..j) is palindrome
        int[][] isPalin = new int[l + 1][l + 1];
  
        // initialize dp and isPalin array by zeros
        for (int i = 0; i <= l; i++) {
            for (int j = 0; j <= l; j++) {
                isPalin[i][j] = dp[i][j] = 0;
            }
        }
  
        // loop for starting index of range
        for (int i = l - 1; i >= 0; i--) {
            // initialize value for one character strings as 1
            isPalin[i][i] = 1;
            dp[i][i] = 1;
  
            // loop for ending index of range
            for (int j = i + 1; j < l; j++) {
                /* isPalin[i][j] will be 1 if ith and
                jth characters are equal and mid
                substring str(i+1..j-1) is also a
                palindrome             */
                isPalin[i][j] = (str.charAt(i) == str.charAt(j) && (i + 1 > j - 1 || (isPalin[i +
  
                /* dp[i][j] will be addition of number
                of palindromes from i to j-1 and i+1
                to j subtracting palindromes from i+1
                to j-1 (as counted twice) plus 1 if
                str(i..j) is also a palindrome */
                dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1] + isPalin[i][j];
            }
        }
    }
  
    // method returns count of palindromic substring in range (l, r)
    static int countOfPalindromeInRange(int dp[][], int l, int r)
    {
        return dp[l][r];
    }

710
Chapter 91. Count of Palindromic substrings in an Index range

  
    // driver program
    public static void main(String args[])
    {
        int MAX = 50;
        String str = "xyaabax";
        int[][] dp = new int[MAX][MAX];
        constructDp(dp, str);
  
        int l = 3;
        int r = 5;
        System.out.println(countOfPalindromeInRange(dp, l, r));
    }
}
  
// Contributed by Pramod Kumar

C#

// C# program to query number of palindromic


// substrings of a string in a range
using System;
  
class GFG {
      
    // Function to construct the dp array
    static void constructDp(int[, ] dp, string str)
    {
        int l = str.Length;
  
        // declare 2D array isPalin, isPalin[i][j]
        // will be 1 if str(i..j) is palindrome
        int[, ] isPalin = new int[l + 1, l + 1];
  
        // initialize dp and isPalin array by zeros
        for (int i = 0; i <= l; i++) {
            for (int j = 0; j <= l; j++) {
                isPalin[i, j] = dp[i, j] = 0;
            }
        }
  
        // loop for starting index of range
        for (int i = l - 1; i >= 0; i--) {
              
            // initialize value for one 
            // character strings as 1
            isPalin[i, i] = 1;
            dp[i, i] = 1;

711
Chapter 91. Count of Palindromic substrings in an Index range

  
            // loop for ending index of range
            for (int j = i + 1; j < l; j++) {
                  
                /* isPalin[i][j] will be 1 if ith and
                jth characters are equal and mid
                substring str(i+1..j-1) is also a
                palindrome*/
                isPalin[i, j] = (str[i] == str[j] && (i + 1 > j - 1 || 
                                (isPalin[i + 1, j - 1]) != 0)) ? 1 : 0;
  
                /* dp[i][j] will be addition of number
                of palindromes from i to j-1 and i+1
                to j subtracting palindromes from i+1
                to j-1 (as counted twice) plus 1 if
                str(i..j) is also a palindrome */
                dp[i, j] = dp[i, j - 1] + dp[i + 1, j] - 
                           dp[i + 1, j - 1] + isPalin[i, j];
            }
        }
    }
  
    // method returns count of palindromic
    // substring in range (l, r)
    static int countOfPalindromeInRange(int[, ] dp,
                                      int l, int r)
    {
        return dp[l, r];
    }
  
    // driver program
    public static void Main()
    {
        int MAX = 50;
        string str = "xyaabax";
        int[, ] dp = new int[MAX, MAX];
        constructDp(dp, str);
  
        int l = 3;
        int r = 5;
        Console.WriteLine(countOfPalindromeInRange(dp, l, r));
    }
}
  
// This code is contributed by vt_m.

Output:

712
Chapter 91. Count of Palindromic substrings in an Index range

Improved By : vt_m

Source

https://www.geeksforgeeks.org/count-of-palindromic-substrings-in-an-index-range/

713
Chapter 92

Count of arrays having


consecutive element with
different values

Count of arrays having consecutive element with different values - GeeksforGeeks


Given three positive integers n, k and x. The task is to count the number of different array
that can be formed of size n such that each element is between 1 to k and two consecutive
element are different. Also, the first and last elements of each array should be 1 and x
respectively.
Examples :

Input : n = 4, k = 3, x = 2
Output : 3

The idea is to use Dynamic Programming and combinatorics to solve the problem.
First of all, notice that the answer is same for all x from 2 to k. It can easily be proved.
This will be useful later on.
Let the state f(i) denote the number of ways to fill the range [1, i] of array A such that A1
= 1 and Ai � 1.
Therefore, if x � 1, the answer to the problem is f(n)/(k – 1), because f(n) is the number
of way where An is filled with a number from 2 to k, and the answer are equal for all such
values An , so the answer for an individual value is f(n)/(k – 1).
Otherwise, if x = 1, the answer is f(n – 1), because An – 1 � 1, and the only number we can
fill An with is x = 1.
Now, the main problem is how to calculate f(i). Consider all numbers that Ai – 1 can be.
We know that it must lie in [1, k].

714
Chapter 92. Count of arrays having consecutive element with different values

• If Ai – 1 � 1, then there are (k – 2)f(i – 1) ways to fill in the rest of the array, because
Ai cannot be 1 or Ai – 1 (so we multiply with (k – 2)), and for the range [1, i – 1],
there are, recursively, f(i – 1) ways.
• If Ai – 1 = 1, then there are (k – 1)f(i – 2) ways to fill in the rest of the array, because
Ai – 1 = 1 means Ai – 2 � 1 which means there are f(i – 2)ways to fill in the range [1, i
– 2] and the only value that Ai cannot be 1, so we have (k – 1) choices for Ai .

By combining the above, we get

f(i) = (k - 1) * f(i - 2) + (k - 2) * f(i - 1)

This will help us to use dynamic programming using f(i).


Below is the implementation of this approach:

C++

// CPP Program to find count of arrays.


#include <bits/stdc++.h>
#define MAXN 109
using namespace std;
  
// Return the number of arrays with given constartints.
int countarray(int n, int k, int x)
{
    int dp[MAXN] = { 0 };
  
    // Initalising dp[0] and dp[1].
    dp[0] = 0;
    dp[1] = 1;
  
    // Computing f(i) for each 2 <= i <= n.
    for (int i = 2; i < n; i++)
        dp[i] = (k - 2) * dp[i - 1] +
                (k - 1) * dp[i - 2];
  
    return (x == 1 ? (k - 1) * dp[n - 2] : dp[n - 1]);
}
  
// Driven Program
int main()
{
    int n = 4, k = 3, x = 2;
    cout << countarray(n, k, x) << endl;
    return 0;
}

Java

715
Chapter 92. Count of arrays having consecutive element with different values

// Java program to find count of arrays.


import java.util.*;
  
class Counting
{
    static int MAXN = 109;
  
    public static int countarray(int n, int k, 
                                       int x)
    {
        int[] dp = new int[109];
  
        // Initalising dp[0] and dp[1].
        dp[0] = 0;
        dp[1] = 1;
  
        // Computing f(i) for each 2 <= i <= n.
        for (int i = 2; i < n; i++)
            dp[i] = (k - 2) * dp[i - 1] +
                (k - 1) * dp[i - 2];
  
        return (x == 1 ? (k - 1) * dp[n - 2] : 
                                  dp[n - 1]);
    }
      
    // driver code
    public static void main(String[] args)
    {
        int n = 4, k = 3, x = 2;
        System.out.println(countarray(n, k, x));
    }
}
  
  
// This code is contributed by rishabh_jain

Python3

# Python3 code to find count of arrays.


  
# Return the number of lists with 
# given constraints.
def countarray( n , k , x ):
      
    dp = list()
      
    # Initalising dp[0] and dp[1]
    dp.append(0)

716
Chapter 92. Count of arrays having consecutive element with different values

    dp.append(1)
      
    # Computing f(i) for each 2 <= i <= n.
    i = 2
    while i < n:
        dp.append( (k - 2) * dp[i - 1] +
                   (k - 1) * dp[i - 2])
        i = i + 1
      
    return ( (k - 1) * dp[n - 2] if x == 1 else dp[n - 1])
  
# Driven code
n = 4
k = 3
x = 2
print(countarray(n, k, x))
  
# This code is contributed by "Sharad_Bhardwaj".

C#

// C# program to find count of arrays.


using System;
  
class GFG
{
// static int MAXN = 109;
  
    public static int countarray(int n, int k, 
                                    int x)
    {
        int[] dp = new int[109];
  
        // Initalising dp[0] and dp[1].
        dp[0] = 0;
        dp[1] = 1;
  
        // Computing f(i) for each 2 <= i <= n.
        for (int i = 2; i < n; i++)
            dp[i] = (k - 2) * dp[i - 1] +
                    (k - 1) * dp[i - 2];
  
        return (x == 1 ? (k - 1) * dp[n - 2] : 
                                   dp[n - 1]);
    }
      
    // Driver code
    public static void Main()

717
Chapter 92. Count of arrays having consecutive element with different values

    {
        int n = 4, k = 3, x = 2;
        Console.WriteLine(countarray(n, k, x));
    }
}
  
  
// This code is contributed by vt_m

PHP

<?php
// PHP Program to find 
// count of arrays.
  
$MAXN = 109;
  
// Return the number of arrays
// with given constartints.
function countarray($n, $k, $x)
{
    $dp = array( 0 );
  
    // Initalising dp[0] and dp[1].
    $dp[0] = 0;
    $dp[1] = 1;
  
    // Computing f(i) for 
    // each 2 <= i <= n.
    for ( $i = 2; $i < $n; $i++)
        $dp[$i] = ($k - 2) * $dp[$i - 1] +
                  ($k - 1) * $dp[$i - 2];
  
    return ($x == 1 ? ($k - 1) * 
            $dp[$n - 2] : $dp[$n - 1]);
}
  
// Driven Code
$n = 4; $k = 3; $x = 2;
echo countarray($n, $k, $x) ;
  
// This code is contributed by anuj_67.
?>

Output :

Improved By : vt_m

718
Chapter 92. Count of arrays having consecutive element with different values

Source

https://www.geeksforgeeks.org/count-arrays-consecutive-element-different-values/

719
Chapter 93

Count of arrays in which all


adjacent elements are such that
one of them divide the another

Count of arrays in which all adjacent elements are such that one of them divide the another
- GeeksforGeeks
Given two positive integer n and n. The task is to find the number of arrays of size n that
can be formed such that :

1. Each element is in range [1, m]


2. All adjacent element are such that one of them divide the another i.e element Ai
divides Ai + 1 or Ai + 1 divides Ai + 2 .

Examples:

Input : n = 3, m = 3.
Output : 17
{1,1,1}, {1,1,2}, {1,1,3}, {1,2,1},
{1,2,2}, {1,3,1}, {1,3,3}, {2,1,1},
{2,1,2}, {2,1,3}, {2,2,1}, {2,2,2},
{3,1,1}, {3,1,2}, {3,1,3}, {3,3,1},
{3,3,3} are possible arrays.

Input : n = 1, m = 10.
Output : 10

We try to find number of possible values at each index of the array. First, at index 0 all
values are possible from 1 to m. Now observe for each index, we can reach either to its

720
Chapter 93. Count of arrays in which all adjacent elements are such that one of them
divide the another

multiple or its factor. So, precompute that and store it for all the elements. Hence for each
position i, ending with integer x, we can go to next position i + 1, with the array ending in
integer with multiple of x or factor of x. Also, multiple of x or factor of x must be less than
m.
So, we define an 2D array dp[i][j], which is number of possible array (divisible adjacent
element) of size i with j as its first index element.

1 <= i <= m, dp[1][m] = 1.


for 1 <= j <= m and 2 <= i <= n
dp[i][j] = dp[i-1][j] + number of factor
of previous element less than m
+ number of multiples of previous
element less than m.

Below is the C++ implementation of this approach:

// C++ program to count number of arrays


// of size n such that every element is
// in range [1, m] and adjacen are
// divisible
#include <bits/stdc++.h>
#define  MAX 1000
using namespace std;
  
int numofArray(int n, int m)
{
    int dp[MAX][MAX];
  
    // For storing factors.
    vector<int> di[MAX];
  
    // For storing multiples.
    vector<int> mu[MAX];
  
    memset(dp, 0, sizeof dp);
    memset(di, 0, sizeof di);
    memset(mu, 0, sizeof mu);
  
    // calculating the factors and multiples
    // of elements [1...m].
    for (int i = 1; i <= m; i++)
    {
        for (int j = 2*i; j <= m; j += i)
        {
            di[j].push_back(i);
            mu[i].push_back(j);

721
Chapter 93. Count of arrays in which all adjacent elements are such that one of them
divide the another

        }
        di[i].push_back(i);
    }
  
    // Initalising for size 1 array for
    // each i <= m.
    for (int i = 1; i <= m; i++)
        dp[1][i] = 1;
  
    // Calculating the number of array possible
    // of size i and starting with j.
    for (int i = 2; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            dp[i][j] = 0;
  
            // For all previous possible values.
            // Adding number of factors.
            for (auto x:di[j])
                dp[i][j] += dp[i-1][x];
  
            // Adding number of multiple.
            for (auto x:mu[j])
                dp[i][j] += dp[i-1][x];
        }
    }
  
    // Calculating the total count of array
    // which start from [1...m].
    int ans = 0;
    for (int i = 1; i <= m; i++)
    {
        ans += dp[n][i];
        di[i].clear();
        mu[i].clear();
    }
  
    return ans;
}
  
// Driven Program
int main()
{
    int n = 3, m = 3;
    cout << numofArray(n, m) << "\n";
    return 0;
}

722
Chapter 93. Count of arrays in which all adjacent elements are such that one of them
divide the another

Output:

17

Time Complexity: O(N*M).

Source

https://www.geeksforgeeks.org/count-arrays-adjacent-elements-one-divide-another/

723
Chapter 94

Count of different ways to


express N as the sum of 1, 3
and 4

Count of different ways to express N as the sum of 1, 3 and 4 - GeeksforGeeks


Given N, count the number of ways to express N as sum of 1, 3 and 4.
Examples:

Input : N = 4
Output : 4
Explanation: 1+1+1+1
1+3
3+1
4

Input : N = 5
Output : 6
Explanation: 1 + 1 + 1 + 1 + 1
1 + 4
4 + 1
1 + 1 + 3
1 + 3 + 1
3 + 1 + 1

Approach : Divide the problem into sub-problems for solving it. Let DP[n] be the be the
number of ways to write N as the sum of 1, 3, and 4. Consider one possible solution with n
= x1 + x2 + x3 + … xn. If the last number is 1, then sum of the remaining numbers is n-1.
So the number that ends with 1 is equal to DP[n-1]. Taking other cases into account where
the last number is 3 and 4. The final recurrence would be:

724
Chapter 94. Count of different ways to express N as the sum of 1, 3 and 4

DPn = DPn-1 + DPn-3 + DPn-4

Base case :
DP[0] = DP[1] = DP[2] = 1 and DP[3] = 2

C++

// CPP program to illustrate the number of


// ways to represent N as sum of 1, 3 and 4.
#include <bits/stdc++.h>
using namespace std;
  
// function to count the number of
// ways to represent n as sum of 1, 3 and 4
int countWays(int n)
{
    int DP[n + 1];
  
    // base cases
    DP[0] = DP[1] = DP[2] = 1;
    DP[3] = 2;
  
    // iterate for all values from 4 to n
    for (int i = 4; i <= n; i++) 
        DP[i] = DP[i - 1] + DP[i - 3] + DP[i - 4];
      
    return DP[n];
}
  
// driver code
int main()
{
    int n = 10;
    cout << countWays(n);
    return 0;
}

Java

// Java program to illustrate 


// the number of ways to represent 
// N as sum of 1, 3 and 4.
  
class GFG {
  

725
Chapter 94. Count of different ways to express N as the sum of 1, 3 and 4

    // Function to count the 


    // number of ways to represent 
    // n as sum of 1, 3 and 4
    static int countWays(int n)
    {
        int DP[] = new int[n + 1];
  
        // base cases
        DP[0] = DP[1] = DP[2] = 1;
        DP[3] = 2;
  
        // iterate for all values from 4 to n
        for (int i = 4; i <= n; i++)
            DP[i] = DP[i - 1] + DP[i - 3] 
                    + DP[i - 4];
  
        return DP[n];
    }
  
    // driver code
    public static void main(String[] args)
    {
        int n = 10;
        System.out.println(countWays(n));
    }
}
  
// This code is contributed 
// by prerna saini.

Python3

# Python program to illustrate the number of


# ways to represent N as sum of 1, 3 and 4.
  
# Function to count the number of
# ways to represent n as sum of 1, 3 and 4
def countWays(n):
  
    DP = [0 for i in range(0, n + 1)]
      
    # base cases
    DP[0] = DP[1] = DP[2] = 1
    DP[3] = 2
  
    # Iterate for all values from 4 to n
    for i in range(4, n + 1):
        DP[i] = DP[i - 1] + DP[i - 3] + DP[i - 4]

726
Chapter 94. Count of different ways to express N as the sum of 1, 3 and 4

      
    return DP[n]
  
      
# Driver code 
n = 10
print (countWays(n))
  
# This code is contributed by Gitanjali.

C#

// C# program to illustrate 
// the number of ways to represent 
// N as sum of 1, 3 and 4.
using System;
  
class GFG {
  
    // Function to count the 
    // number of ways to represent 
    // n as sum of 1, 3 and 4
    static int countWays(int n)
    {
        int []DP = new int[n + 1];
  
        // base cases
        DP[0] = DP[1] = DP[2] = 1;
        DP[3] = 2;
  
        // iterate for all values from 4 to n
        for (int i = 4; i <= n; i++)
            DP[i] = DP[i - 1] + DP[i - 3] 
                    + DP[i - 4];
  
        return DP[n];
    }
  
    // Driver code
    public static void Main()
    {
        int n = 10;
        Console.WriteLine(countWays(n));
    }
}
  
// This code is contributed 
// by vt_m.

727
Chapter 94. Count of different ways to express N as the sum of 1, 3 and 4

PHP

<?php
// PHP program to illustrate 
// the number of ways to 
// represent N as sum of 
// 1, 3 and 4.
  
// function to count the 
// number of ways to 
// represent n as sum of
// 1, 3 and 4
function countWays($n)
{
    $DP = array();
  
    // base cases
    $DP[0] = $DP[1] = $DP[2] = 1;
    $DP[3] = 2;
  
    // iterate for all 
    // values from 4 to n
    for ($i = 4; $i <= $n; $i++) 
        $DP[$i] = $DP[$i - 1] + 
                  $DP[$i - 3] + 
                  $DP[$i - 4];
      
    return $DP[$n];
}
  
// Driver Code
$n = 10;
echo countWays($n);
  
// This code is contributed
// by Sam007
?>

Output:

64

Time Complexity : O(n)


Auxiliary Space : O(n)
Improved By : Sam007

728
Chapter 94. Count of different ways to express N as the sum of 1, 3 and 4

Source

https://www.geeksforgeeks.org/count-ofdifferent-ways-express-n-sum-1-3-4/

729
Chapter 95

Count of n digit numbers whose


sum of digits equals to given
sum

Count of n digit numbers whose sum of digits equals to given sum - GeeksforGeeks
Given two integers ‘n’ and ‘sum’, find count of all n digit numbers with sum of digits as
‘sum’. Leading 0’s are not counted as digits.
1 <= n <= 100 and
1 <= sum <= 500
Example:

Input: n = 2, sum = 2
Output: 2
Explanation: Numbers are 11 and 20

Input: n = 2, sum = 5
Output: 5
Explanation: Numbers are 14, 23, 32, 41 and 50

Input: n = 3, sum = 6
Output: 21

The idea is simple, we subtract all values from 0 to 9 from given sum and recur for sum
minus that digit. Below is recursive formula.

countRec(n, sum) = �countRec(n-1, sum-x)


where 0 =< x = 0

730
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

One important observation is, leading 0's must be


handled explicitly as they are not counted as digits.
So our final count can be written as below.
finalCount(n, sum) = �countRec(n-1, sum-x)
where 1 =< x = 0

Below is a simple recursive solution based on above recursive formula.

C++

// A C++ program using recursive to count numbers 


// with sum of digits as given 'sum'
#include<bits/stdc++.h>
using namespace std;
  
// Recursive function to count 'n' digit numbers
// with sum of digits as 'sum'. This function
// considers leading 0's also as digits, that is
// why not directly called
unsigned long long int countRec(int n, int sum)
{
    // Base case
    if (n == 0)
    return sum == 0;
  
    if (sum == 0)
    return 1;
  
    // Initialize answer
    unsigned long long int ans = 0;
  
    // Traverse through every digit and count
    // numbers beginning with it using recursion
    for (int i=0; i<=9; i++)
    if (sum-i >= 0)
        ans += countRec(n-1, sum-i);
  
    return ans;
}
  
// This is mainly a wrapper over countRec. It
// explicitly handles leading digit and calls
// countRec() for remaining digits.
unsigned long long int finalCount(int n, int sum)
{
    // Initialize final answer

731
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

    unsigned long long int ans = 0;


  
    // Traverse through every digit from 1 to
    // 9 and count numbers beginning with it
    for (int i = 1; i <= 9; i++)
    if (sum-i >= 0)
        ans += countRec(n-1, sum-i);
  
    return ans;
}
  
// Driver program
int main()
{
    int n = 2, sum = 5;
    cout << finalCount(n, sum);
    return 0;
}

Java

// A java program using recursive to count numbers 


// with sum of digits as given 'sum'
class sum_dig
{
    // Recursive function to count 'n' digit numbers
    // with sum of digits as 'sum'. This function
    // considers leading 0's also as digits, that is
    // why not directly called
    static int countRec(int n, int sum)
    {
        // Base case
        if (n == 0)
        return sum == 0 ?1:0;
  
            if (sum == 0)
            return 1;
      
        // Initialize answer
        int ans = 0;
      
        // Traverse through every digit and count
        // numbers beginning with it using recursion
        for (int i=0; i<=9; i++)
        if (sum-i >= 0)
            ans += countRec(n-1, sum-i);
      
        return ans;

732
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

    }
      
    // This is mainly a wrapper over countRec. It
    // explicitly handles leading digit and calls
    // countRec() for remaining digits.
    static int finalCount(int n, int sum)
    {
        // Initialize final answer
        int ans = 0;
      
        // Traverse through every digit from 1 to
        // 9 and count numbers beginning with it
        for (int i = 1; i <= 9; i++)
        if (sum-i >= 0)
            ans += countRec(n-1, sum-i);
      
        return ans;
    }
  
    /* Driver program to test above function */
    public static void main (String args[])
    {
        int n = 2, sum = 5;
        System.out.println(finalCount(n, sum));
    }
}/* This code is contributed by Rajat Mishra */

Python 3

# A python 3 program using recursive to count numbers 


# with sum of digits as given 'sum'
  
# Recursive function to count 'n' digit 
# numbers with sum of digits as 'sum' 
# This function considers leading 0's 
# also as digits, that is why not 
# directly called
def countRec(n, sum) :
      
    # Base case
    if (n == 0) :
        return (sum == 0)
  
    if (sum == 0) :
        return 1
  
    # Initialize answer
    ans = 0

733
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

  
    # Traverse through every digit and 
    # count numbers beginning with it
    # using recursion
    for i in range(0, 10) :
        if (sum-i >= 0) :
            ans = ans + countRec(n-1, sum-i)
  
    return ans
      
      
# This is mainly a wrapper over countRec. It
# explicitly handles leading digit and calls
# countRec() for remaining digits.
def finalCount(n, sum) :
      
    # Initialize final answer
    ans = 0
  
    # Traverse through every digit from 1 to
    # 9 and count numbers beginning with it
    for i in range(1, 10) :
        if (sum-i >= 0) :
            ans = ans + countRec(n-1, sum-i)
  
    return ans
  
  
# Driver program
n = 2
sum = 5
print(finalCount(n, sum))
  
  
# This code is contributed by Nikita tiwari.

C#

// A C# program using recursive to count numbers 


// with sum of digits as given 'sum'
using System;
class GFG {
      
    // Recursive function to 
    // count 'n' digit numbers
    // with sum of digits as 
    // 'sum'. This function
    // considers leading 0's 

734
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

    // also as digits, that is


    // why not directly called
    static int countRec(int n, int sum)
    {
          
        // Base case
        if (n == 0)
        return sum == 0 ? 1 : 0;
  
            if (sum == 0)
            return 1;
      
        // Initialize answer
        int ans = 0;
      
        // Traverse through every
        // digit and count numbers 
        // beginning with it using
        // recursion
        for (int i = 0; i <= 9; i++)
        if (sum - i >= 0)
            ans += countRec(n - 1, sum - i);
      
        return ans;
    }
      
    // This is mainly a 
    // wrapper over countRec. It
    // explicitly handles leading
    // digit and calls countRec() 
    // for remaining digits.
    static int finalCount(int n, int sum)
    {
          
        // Initialize final answer
        int ans = 0;
      
        // Traverse through every 
        // digit from 1 to 9 and 
        // count numbers beginning
        // with it
        for (int i = 1; i <= 9; i++)
        if (sum - i >= 0)
            ans += countRec(n - 1, sum - i);
      
        return ans;
    }
  

735
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

    // Driver Code


    public static void Main ()
    {
        int n = 2, sum = 5;
        Console.Write(finalCount(n, sum));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// A PHP program using recursive to count numbers 
// with sum of digits as given 'sum'
  
// Recursive function to count 'n' digit numbers
// with sum of digits as 'sum'. This function
// considers leading 0's also as digits, that is
// why not directly called
function countRec($n, $sum)
{
      
    // Base case
    if ($n == 0)
    return $sum == 0;
  
    if ($sum == 0)
    return 1;
  
    // Initialize answer
    $ans = 0;
  
    // Traverse through every 
    // digit and count
    // numbers beginning with
    // it using recursion
    for ($i = 0; $i <= 9; $i++)
    if ($sum-$i >= 0)
        $ans += countRec($n-1, $sum-$i);
  
    return $ans;
}
  
// This is mainly a wrapper
// over countRec. It
// explicitly handles leading
// digit and calls

736
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

// countRec() for remaining digits.


function finalCount($n, $sum)
{
      
    // Initialize final answer
    $ans = 0;
  
    // Traverse through every
    // digit from 1 to
    // 9 and count numbers
    // beginning with it
    for ($i = 1; $i <= 9; $i++)
    if ($sum - $i >= 0)
        $ans += countRec($n - 1, $sum - $i);
  
    return $ans;
}
  
    // Driver Code
    $n = 2; 
    $sum = 5;
    echo finalCount($n, $sum);
      
// This code is contributed by ajit
?>

Output:

The time complexity of above solution is exponential. If we draw the complete recursion
tree, we can observer that many subproblems are solved again and again. For example, if
we start with n = 3 and sum = 10, we can reach n = 1, sum = 8, by considering digit
sequences 1,1 or 2, 0.
Since same suproblems are called again, this problem has Overlapping Subprolems property.
So min square sum problem has both properties (see thisand this) of a dynamic programming
problem.
Below is Memoization based the implementation.

C++

// A C++ memoization based recursive program to count 


// numbers with sum of n as given 'sum'
#include<bits/stdc++.h>
using namespace std;
  

737
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

// A lookup table used for memoization


unsigned long long int lookup[101][501];
  
// Memoizatiob based implementation of recursive
// function
unsigned long long int countRec(int n, int sum)
{
    // Base case
    if (n == 0)
    return sum == 0;
  
    // If this subproblem is already evaluated,
    // return the evaluated value
    if (lookup[n][sum] != -1)
    return lookup[n][sum];
  
    // Initialize answer
    unsigned long long int ans = 0;
  
    // Traverse through every digit and
    // recursively count numbers beginning
    // with it
    for (int i=0; i<10; i++)
    if (sum-i >= 0)
        ans += countRec(n-1, sum-i);
  
    return lookup[n][sum] = ans;
}
  
// This is mainly a wrapper over countRec. It
// explicitly handles leading digit and calls
// countRec() for remaining n.
unsigned long long int finalCount(int n, int sum)
{
    // Initialize all entries of lookup table
    memset(lookup, -1, sizeof lookup);
  
    // Initialize final answer
    unsigned long long int ans = 0;
  
    // Traverse through every digit from 1 to
    // 9 and count numbers beginning with it
    for (int i = 1; i <= 9; i++)
    if (sum-i >= 0)
        ans += countRec(n-1, sum-i);
    return ans;
}
  

738
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

// Driver program
int main()
{
    int n = 3, sum = 5;
    cout << finalCount(n, sum);
    return 0;
}

Java

// A java memoization based recursive program to count 


// numbers with sum of n as given 'sum'
class sum_dig
{
    // A lookup table used for memoization
    static int lookup[][] = new int[101][501];
      
    // Memoizatiob based implementation of recursive
    // function
    static int countRec(int n, int sum)
    {
        // Base case
        if (n == 0)
        return sum == 0 ? 1 : 0;
      
        // If this subproblem is already evaluated,
        // return the evaluated value
        if (lookup[n][sum] != -1)
        return lookup[n][sum];
      
        // Initialize answer
        int ans = 0;
      
        // Traverse through every digit and
        // recursively count numbers beginning
        // with it
        for (int i=0; i<10; i++)
        if (sum-i >= 0)
            ans += countRec(n-1, sum-i);
      
        return lookup[n][sum] = ans;
    }
      
    // This is mainly a wrapper over countRec. It
    // explicitly handles leading digit and calls
    // countRec() for remaining n.
    static int finalCount(int n, int sum)
    {

739
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

        // Initialize all entries of lookup table


        for(int i = 0; i <= 100; ++i){
            for(int j = 0; j <= 500; ++j){
                lookup[i][j] = -1;
            }
        }
      
        // Initialize final answer
        int ans = 0;
      
        // Traverse through every digit from 1 to
        // 9 and count numbers beginning with it
        for (int i = 1; i <= 9; i++)
        if (sum-i >= 0)
            ans += countRec(n-1, sum-i);
        return ans;
    }
  
    /* Driver program to test above function */
    public static void main (String args[])
    {
        int n = 3, sum = 5;
        System.out.println(finalCount(n, sum));
    }
}/* This code is contributed by Rajat Mishra */

Output:

15

Thanks to Gaurav Ahirwar for suggesting above solution.


Another Method
We can easily count n digit numbers whose sum of digit equals to given sum by iterating all
n digits and checking if current n digit number’s sum is equal to given sum, if it is then we
will start increment number by 9 until it reaches to number whose sum of digit’s is greater
than given sum, then again we will increment by 1 until we found another number with
given sum.
Java

// Java program to Count of n digit numbers 


// whose sum of digits equals to given sum
  
public class GFG {
  
    public static void main(String[] args) {
          

740
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

        int n = 3;
        int sum = 5;     
        findCount(n,sum);
          
    }
      
    private static void findCount(int n, int sum) {
          
        //in case n = 2 start is 10 and end is (100-1) = 99
        int start = (int) Math.pow(10, n-1);
        int end = (int) Math.pow(10, n)-1; 
      
        int count = 0;
        int i = start;
          
                while(i < end) {
              
            int cur = 0;
            int temp = i;
              
            while( temp != 0) {
                cur += temp % 10;
                temp = temp / 10;
            }
              
            if(cur == sum) {             
                count++;             
                i += 9;         
            }else
                i++;
              
        }     
        System.out.println(count);
  
        /* This code is contributed by Anshuman */
    }
}

Output:

15

Time Complexity: O(sum)


Space Complexity: O(1)
Improved By : jit_t, nitin mittal, Anshuman Kaushik

741
Chapter 95. Count of n digit numbers whose sum of digits equals to given sum

Source

https://www.geeksforgeeks.org/count-of-n-digit-numbers-whose-sum-of-digits-equals-to-given-sum/

742
Chapter 96

Count of possible hexagonal


walks

Count of possible hexagonal walks - GeeksforGeeks


We are given an infinite two dimensional plane made of hexagons connected together. We
can visualize this plane as a honeycomb. Element X is present on one of the cells / hexagon.
We are given N steps, the task is to calculate number of such hexagonal paths possible in
which element X has to perform a walk of N steps and return back to the original hexagon,

where
Examples :

Input : 1
Output : Number of walks possible is/are 0
Explanation :
0 because using just one step we can move to
any of the adjacent cells but we cannot trace
back to the original hexagon.

Input : 2
Output : Number of walks possible is/are 6

Input : 4
Output : Number of walks possible is/are 90

Approach :

• A hexagonal walk can be defined as walking through adjacent hexagons and returning
to the original cell. We know the fact that a hexagon contains six sides i.e. a hexagon
is surrounded by six hexagons. Now, we have to count number of ways we take N
steps and come back to the original hexagon.

743
Chapter 96. Count of possible hexagonal walks

• Now, let us suppose the original hexagon (where element X was initially present) to
be the origin. We need all possible ways we can take (N-k) steps such that we have
some steps which would trace back to our original hexagon. We can visualize this
hexagon and it’s related coordinate system from the picture below.

• Now, let’s assume, our element X was present at 0:0 of the given picture. Thus, we
can travel in six possible directions from a hexagon. Now, using the directions above
we memorize all possible movements such that we trace back to the original 0:0 index.
For memorizing we use a 3D array and we preprocess our answer for a given number
of steps and then query accordingly.

Below is the implementation of above approach :

C++

// C++ implementation of counting

744
Chapter 96. Count of possible hexagonal walks

// number of possible hexagonal walks


#include <iostream>
using namespace std;
  
int depth = 16;
int ways[16][16][16];
int stepNum;
  
void preprocess(int list[])
{
    // We initialize our origin with 1
    ways[0][8][8] = 1;
  
    // For each N = 1 to 14, we traverse in all possible
    // direction. Using this 3D array we calculate the 
    // number of ways at each step and the total ways 
    // for a given step shall be found at 
    // ways[step number][8][8] because all the steps 
    // after that will be used to trace back to the 
    // original point index 0:0 according to the image.
    for (int N = 1; N <= 14; N++) 
    {
        for (int i = 1; i <= depth; i++) 
        {
            for (int j = 1; j <= depth; j++) 
            {
                ways[N][i][j] = ways[N - 1][i][j + 1] 
                                + ways[N - 1][i][j - 1]
                                + ways[N - 1][i + 1][j] 
                                + ways[N - 1][i - 1][j]
                                + ways[N - 1][i + 1][j - 1] 
                                + ways[N - 1][i - 1][j + 1];
            }
        }
  
        // This array stores the number of ways
        // possible for a given step
        list[N] = ways[N][8][8];
    }
}
  
// Driver function
int main()
{
    int list[15];
   
   // Preprocessing all possible ways
    preprocess(list);

745
Chapter 96. Count of possible hexagonal walks

    int steps = 4;
    cout << "Number of walks possible is/are " 
         << list[steps] << endl;
    return 0;
}

Java

// Java implementation of counting


// number of possible hexagonal walks
import java.util.*;
  
class GFG {
      
    static int depth = 14;
    static int ways[][][] = new int[16][16][16];
    static int stepNum;
       
    static void preprocess(int list[])
    {
          
        // We initialize our origin with 1
        ways[0][8][8] = 1;
       
        // For each N = 1 to 14, we traverse in 
        // all possible direction. Using this 3D
        // array we calculate the number of ways
        // at each step and the total ways for a
        // given step shall be found at ways[step
        // number][8][8] because all the steps
        // after that will be used to trace back
        // to the original point index 0:0 
        // according to the image.
        for (int N = 1; N <= 14; N++) 
        {
            for (int i = 1; i < depth; i++) 
            {
                for (int j = 1; j < depth; j++) 
                {
                    ways[N][i][j] = 
                            ways[N - 1][i][j + 1] 
                          + ways[N - 1][i][j - 1]
                          + ways[N - 1][i + 1][j] 
                          + ways[N - 1][i - 1][j]
                      + ways[N - 1][i + 1][j - 1] 
                     + ways[N - 1][i - 1][j + 1];
                }
            }

746
Chapter 96. Count of possible hexagonal walks

       
            // This array stores the number of
            // ways possible for a given step
            list[N] = ways[N][8][8];
        }
    }
       
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
         int list[] = new int[15];
            
           // Preprocessing all possible ways
            preprocess(list);
            int steps = 4;
            System.out.println( "Number of walks"
                           + " possible is/are "+
                                   list[steps] );
    }
}

C#

// C# implementation of counting
// number of possible hexagonal walks
using System;
  
class GFG {
      
    static int depth = 14;
    static int [, ,]ways = new int[16,16,16];
    // static int stepNum;
      
    static void preprocess(int []list)
    {
          
        // We initialize our origin with 1
        ways[0,8,8] = 1;
      
        // For each N = 1 to 14, we traverse in 
        // all possible direction. Using this 3D
        // array we calculate the number of ways
        // at each step and the total ways for a
        // given step shall be found at ways[step
        // number][8][8] because all the steps
        // after that will be used to trace back
        // to the original point index 0:0 

747
Chapter 96. Count of possible hexagonal walks

        // according to the image.


        for (int N = 1; N <= 14; N++) 
        {
            for (int i = 1; i < depth; i++) 
            {
                for (int j = 1; j < depth; j++) 
                {
                    ways[N,i,j] = 
                            ways[N - 1,i,j + 1] 
                        + ways[N - 1,i,j - 1]
                        + ways[N - 1,i + 1,j] 
                        + ways[N - 1,i - 1,j]
                    + ways[N - 1,i + 1,j - 1] 
                    + ways[N - 1,i - 1,j + 1];
                }
            }
      
            // This array stores the number of
            // ways possible for a given step
            list[N] = ways[N,8,8];
        }
    }
      
      
    /* Driver program to test above function */
    public static void Main() 
    {
        int []list = new int[15];
          
            // Preprocessing all possible ways
            preprocess(list);
            int steps = 4;
            Console.WriteLine( "Number of walks"
                        + " possible is/are "+
                                list[steps] );
    }
}
  
// This code is contributed by anuj_67.

Output :

Number of walks possible is/are 90

The time complexity of the above code is and the space complexity is

748
Chapter 96. Count of possible hexagonal walks

also similar due to the 3D array used.


Improved By : vt_m

Source

https://www.geeksforgeeks.org/count-possible-hexagonal-walks/

749
Chapter 97

Count of strings that can be


formed using a, b and c under
given constraints

Count of strings that can be formed using a, b and c under given constraints - GeeksforGeeks
Given a length n, count the number of strings of length n that can be made using ‘a’, ‘b’
and ‘c’ with at-most one ‘b’ and two ‘c’s allowed.
Examples :

Input : n = 3
Output : 19
Below strings follow given constraints:
aaa aab aac aba abc aca acb acc baa
bac bca bcc caa cab cac cba cbc cca ccb

Input : n = 4
Output : 39

Asked in Google Interview


A simple solution is to recursively count all possible combination of string that can be
mode up to latter ‘a’, ‘b’, and ‘c’.
Below is implementation of above idea
C++

// C++ program to count number of strings


// of n characters with
#include<bits/stdc++.h>

750
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

using namespace std;


  
// n is total number of characters.
// bCount and cCount are counts of 'b'
// and 'c' respectively.
int countStr(int n, int bCount, int cCount)
{
    // Base cases
    if (bCount < 0 || cCount < 0) return 0;
    if (n == 0) return 1;
    if (bCount == 0 && cCount == 0) return 1;
  
    // Three cases, we choose, a or b or c
    // In all three cases n decreases by 1.
    int res = countStr(n-1, bCount, cCount);
    res += countStr(n-1, bCount-1, cCount);
    res += countStr(n-1, bCount, cCount-1);
  
    return res;
}
  
// Driver code
int main()
{
    int n = 3;  // Total number of characters
    cout << countStr(n, 1, 2);
    return 0;
}

Java

// Java program to count number 


// of strings of n characters with
import java.io.*;
  
class GFG 
{
      
// n is total number of characters.
// bCount and cCount are counts of 'b'
// and 'c' respectively.
static int countStr(int n, 
                    int bCount, 
                    int cCount)
{
    // Base cases
    if (bCount < 0 || cCount < 0) return 0;
    if (n == 0) return 1;

751
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

    if (bCount == 0 && cCount == 0) return 1;


  
    // Three cases, we choose, a or b or c
    // In all three cases n decreases by 1.
    int res = countStr(n - 1, bCount, cCount);
    res += countStr(n - 1, bCount - 1, cCount);
    res += countStr(n - 1, bCount, cCount - 1);
  
    return res;
}
  
// Driver code
public static void main (String[] args)
{
    int n = 3; // Total number of characters
    System.out.println(countStr(n, 1, 2));
}
}
  
// This code is contributed by akt_mit

C#

// C# program to count number 


// of strings of n characters 
// with a, b and c under given
// constraints
using System;
  
class GFG
{
      
// n is total number of 
// characters. bCount and
// cCount are counts of 
// 'b' and 'c' respectively.
static int countStr(int n, 
                    int bCount, 
                    int cCount)
{
    // Base cases
    if (bCount < 0 || cCount < 0) 
        return 0;
    if (n == 0) return 1;
    if (bCount == 0 && cCount == 0) 
        return 1;
  
    // Three cases, we choose, 

752
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

    // a or b or c. In all three


    // cases n decreases by 1.
    int res = countStr(n - 1, 
                       bCount, cCount);
    res += countStr(n - 1, 
                    bCount - 1, cCount);
    res += countStr(n - 1, 
                    bCount, cCount - 1);
  
    return res;
}
  
// Driver code
static public void Main ()
{
    // Total number 
    // of characters
    int n = 3; 
    Console.WriteLine(countStr(n, 1, 2));
}
}
  
// This code is contributed by aj_36

PHP

<?php
// PHP program to count number of 
// strings of n characters with
  
// n is total number of characters.
// bCount and cCount are counts 
// of 'b' and 'c' respectively.
function countStr($n, $bCount, 
                      $cCount)
{
    // Base cases
    if ($bCount < 0 || 
        $cCount < 0)
        return 0;
    if ($n == 0)
    return 1;
    if ($bCount == 0 && 
        $cCount == 0) 
        return 1;
  
    // Three cases, we choose,
    // a or b or c. In all three 

753
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

    // cases n decreases by 1.


    $res = countStr($n - 1, 
                    $bCount, 
                    $cCount);
    $res += countStr($n - 1, 
                     $bCount - 1, 
                     $cCount);
    $res += countStr($n - 1, 
                     $bCount, 
                     $cCount - 1);
  
    return $res;
}
  
// Driver code
$n = 3; // Total number 
        // of characters
echo countStr($n, 1, 2);
      
// This code is contributed by ajit
?>

Output :

19

Time complexity of above solution is exponential.

Efficient Solution
If we drown a recursion tree of above code, we can notice that same values appear multiple
times. So we store results which are used later if repeated.
C++

// C++ program to count number of strings


// of n characters with
#include<bits/stdc++.h>
using namespace std;
  
// n is total number of characters.
// bCount and cCount are counts of 'b'
// and 'c' respectively.
int countStrUtil(int dp[][2][3], int n, int bCount=1,
                 int cCount=2)
{
    // Base cases
    if (bCount < 0 || cCount < 0) return 0;

754
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

    if (n == 0) return 1;
    if (bCount == 0 && cCount == 0) return 1;
  
    // if we had saw this combination previously
    if (dp[n][bCount][cCount] != -1)
        return dp[n][bCount][cCount];
  
    // Three cases, we choose, a or b or c
    // In all three cases n decreases by 1.
    int res = countStrUtil(dp, n-1, bCount, cCount);
    res += countStrUtil(dp, n-1, bCount-1, cCount);
    res += countStrUtil(dp, n-1, bCount, cCount-1);
  
    return (dp[n][bCount][cCount] = res);
}
  
// A wrapper over countStrUtil()
int countStr(int n)
{
    int dp[n+1][2][3];
    memset(dp, -1, sizeof(dp));
    return countStrUtil(dp, n);
}
  
// Driver code
int main()
{
    int n = 3; // Total number of characters
    cout << countStr(n);
    return 0;
}

Output :

19

Time Complexity : O(n)


Auxiliary Space : O(n)
Thanks to Mr. Lazy for suggesting above solutions.
A solution that works in O(1) time :
C++

// A O(1) CPP program to find number of strings


// that can be made under given constraints.
#include<bits/stdc++.h>

755
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

using namespace std;


int countStr(int n)
{
    return 1+(n*2)+(n*((n*n)-1)/2);
}
  
// Driver code 
int main()
{
  int n = 3;
  cout << countStr(n);
  return 0;

Java

// A O(1) Java program to 


// find number of strings
// that can be made under
// given constraints.
import java.io.*;
  
class GFG
{
    static int countStr(int n)
    {
    return 1 + (n * 2) + 
           (n * ((n * n) - 1) / 2);
    }
  
// Driver code 
public static void main (String[] args)
{
    int n = 3;
    System.out.println( countStr(n));
}
}
  
// This code is contributed by ajit

C#

// A O(1) C# program to 


// find number of strings
// that can be made under
// given constraints.
using System;

756
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

  
class GFG
{
    static int countStr(int n)
    {
    return 1 + (n * 2) + 
          (n * ((n * n) - 1) / 2);
    }
  
// Driver code 
static public void Main ()
{
    int n = 3;
    Console.WriteLine(countStr(n));
}
}
  
// This code is contributed by m_kit

PHP

<?php
// A O(1) PHP program to find 
// number of strings that can 
// be made under given constraints.
function countStr($n)
{
    return 1 + ($n * 2) + ($n * 
              (($n * $n) - 1) / 2);
}
  
// Driver code 
$n = 3;
echo countStr($n);
  
// This code is contributed by aj_36
?>

Output :

19

Time Complexity : O(1)


Auxiliary Space : O(1)
Thanks to Niharika Sahai for providing above solution.

757
Chapter 97. Count of strings that can be formed using a, b and c under given constraints

Reference :
https://careercup.appspot.com/question?id=5717453712654336
Improved By : jit_t

Source

https://www.geeksforgeeks.org/count-strings-can-formed-using-b-c-given-constraints/

758
Chapter 98

Count of strings where adjacent


characters are of difference one

Count of strings where adjacent characters are of difference one - GeeksforGeeks


iven a number n, count number of strings of length n such that every string has adjacent
characters with difference between ASCII values as 1.
Examples:

Input : N = 1
Output : Total strings are 26
Explanation : For N=1, strings
are a, b, c,, ...., x, y, z

Input : N = 2
Output : Total strings are 50
Explanation : For N = 2, strings
are ab, ba, bc, cb, .., yx, yz, zy

For strings starting with character ‘A’ and length ‘i’, we consider all strings of length ‘i-1’
and starting with character ‘B’
For strings starting with character ‘G’ and length ‘i’, we consider all strings of length ‘i-1’
and starting with character ‘H’ and all strings of length ‘i-1’ and starting with ‘F’.
We take the base case for n = 1, and set result for all 26 characters as 1. This simply means
when 1 character string is consider all alphabets from a-z are taken only once.
For N = 2,

759
Chapter 98. Count of strings where adjacent characters are of difference one

For N = 3,

Conclusion : For N = n

760
Chapter 98. Count of strings where adjacent characters are of difference one

countAdjacent(n)
dp[i][j] finally stores count of strings
of length i and starting with
character j.

Initialize dp[n+1][27] as 0
Initialize dp[1][j] = 1 where j = 0 to 25
for i = 2 to n
for j = 0 to 25
if (j = 0)
dp[i][j] = dp[i-1][j+1];
else
dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1];
Sum of n-th row from 0 to 25 is the result.

// CPP Program to count strings with adjacent


// characters.
#include <bits/stdc++.h>
using namespace std;
  
int countStrs(int n)
{
    long int dp[n + 1][27];
  
    // Initializing arr[n+1][27] to 0
    memset(dp, 0, sizeof(dp));
  
    // Initialing 1st row all 1 from 0 to 25
    for (int i = 0; i <= 25; i++)
        dp[1][i] = 1;
  
    // Begin evaluating from i=2 since 1st row is set
    for (int i = 2; i <= n; i++) {
        for (int j = 0; j <= 25; j++)
  
            // j=0 is 'A' which can make strings 
            // of length i using strings of length 
            // i-1 and starting with 'B'
            if (j == 0) 
                dp[i][j] = dp[i - 1][j + 1];
            else
                dp[i][j] = (dp[i - 1][j - 1] +
                            dp[i - 1][j + 1]);
    }
  
    // Our result is sum of last row.
    long int sum = 0;
    for (int i = 0; i <= 25; i++)

761
Chapter 98. Count of strings where adjacent characters are of difference one

        sum = (sum + dp[n][i]);


    return sum;
}
  
// Driver's Code
int main()
{
    int n = 3;
    cout << "Total strings are : " << countStrs(n);
    return 0;
}

Output:

Total strings are : 98

Source

https://www.geeksforgeeks.org/count-strings-adjacent-characters-difference-one/

762
Chapter 99

Count of subarrays whose


maximum element is greater
than k

Count of subarrays whose maximum element is greater than k - GeeksforGeeks


Given an array of n elements and an integer k. The task is to find the count of subarray
which has maximum element greater than K.
Examples :

Input : arr[] = {1, 2, 3} and k = 2.


Output : 3
All the possible subarrays of arr[] are
{ 1 }, { 2 }, { 3 }, { 1, 2 }, { 2, 3 },
{ 1, 2, 3 }.
Their maximum elements are 1, 2, 3, 2, 3, 3.
There are only 3 maximum elements > 2.

The idea is to approach problem by counting subarrays whose maximum element is less than
or equal to k as counting such subarrays is easier. To find the number of subarray whose
maximum element is less than or equal to k, remove all the element which is greater than
K and find the number of subarray with the left elements.
Once we find above count, we can subtract it from n*(n+1)/2 to get our required result.
Observe, there can be n*(n+1)/2 possible number of subarray of any array of size n. So,
finding the number of subarray whose maximum element is less than or equal to K and
substracting it from n*(n+1)/2 gets us the answer.
Below is the implementation of this approach:

C++

763
Chapter 99. Count of subarrays whose maximum element is greater than k

// C++ program to count number of subarrays


// whose maximum element is greater than K.
#include <bits/stdc++.h>
using namespace std;
  
// Return number of subarrays whose maximum
// element is less than or equal to K.
int countSubarray(int arr[], int n, int k)
{
    // To store count of subarrays with all
    // elements less than or equal to k.
    int s = 0;
  
    // Traversing the array.
    int i = 0;
    while (i < n) {
        // If element is greater than k, ignore.
        if (arr[i] > k) {
            i++;
            continue;
        }
  
        // Counting the subarray length whose
        // each element is less than equal to k.
        int count = 0;
        while (i < n && arr[i] <= k) {
            i++;
            count++;
        }
  
        // Suming number of subarray whose
        // maximum element is less than equal to k.
        s += ((count * (count + 1)) / 2);
    }
  
    return (n * (n + 1) / 2 - s);
}
  
// Driven Program
int main()
{
    int arr[] = { 1, 2, 3 };
    int k = 2;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << countSubarray(arr, n, k);
    return 0;
}

764
Chapter 99. Count of subarrays whose maximum element is greater than k

Java

// Java program to count number of subarrays


// whose maximum element is greater than K.
import java.util.*;
  
class GFG {
  
    // Return number of subarrays whose maximum
    // element is less than or equal to K.
    static int countSubarray(int arr[], int n, int k)
    {
  
        // To store count of subarrays with all
        // elements less than or equal to k.
        int s = 0;
  
        // Traversing the array.
        int i = 0;
        while (i < n) {
  
            // If element is greater than k, ignore.
            if (arr[i] > k) {
                i++;
                continue;
            }
  
            // Counting the subarray length whose
            // each element is less than equal to k.
            int count = 0;
            while (i < n && arr[i] <= k) {
                i++;
                count++;
            }
  
            // Suming number of subarray whose
            // maximum element is less than equal to k.
            s += ((count * (count + 1)) / 2);
        }
  
        return (n * (n + 1) / 2 - s);
    }
  
    // Driver code
    public static void main(String[] args)
    {
  
        int arr[] = { 1, 2, 3 };

765
Chapter 99. Count of subarrays whose maximum element is greater than k

        int k = 2;
        int n = arr.length;
        System.out.print(countSubarray(arr, n, k));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python program to count


# number of subarrays
# whose maximum element
# is greater than K.
  
# Return number of
# subarrays whose maximum
# element is less than or equal to K.
def countSubarray(arr, n, k):
  
    # To store count of
    # subarrays with all
    # elements less than
    # or equal to k.
    s = 0
   
    # Traversing the array.
    i = 0
    while (i < n):
      
        # If element is greater
        # than k, ignore.
        if (arr[i] > k):
          
            i = i + 1
            continue
          
        # Counting the subarray
        # length whose
        # each element is less
        # than equal to k.
        count = 0
        while (i < n and arr[i] <= k):
          
            i = i + 1
            count = count + 1
          
   

766
Chapter 99. Count of subarrays whose maximum element is greater than k

        # Suming number of subarray whose


        # maximum element is less
        # than equal to k.
        s = s + ((count*(count + 1))//2)
      
   
    return (n*(n + 1)//2 - s)
      
# Driver code
  
arr = [1, 2, 3]
k = 2
n = len(arr)
  
print(countSubarray(arr, n, k))
  
# This code is contributed
# by Anant Agarwal.

C#

// C# program to count number of subarrays


// whose maximum element is greater than K.
using System;
  
class GFG {
  
    // Return number of subarrays whose maximum
    // element is less than or equal to K.
    static int countSubarray(int[] arr, int n, int k)
    {
        // To store count of subarrays with all
        // elements less than or equal to k.
        int s = 0;
  
        // Traversing the array.
        int i = 0;
        while (i < n) {
  
            // If element is greater than k, ignore.
            if (arr[i] > k) {
                i++;
                continue;
            }
  
            // Counting the subarray length whose
            // each element is less than equal to k.
            int count = 0;

767
Chapter 99. Count of subarrays whose maximum element is greater than k

            while (i < n && arr[i] <= k) {


                i++;
                count++;
            }
  
            // Suming number of subarray whose
            // maximum element is less than equal to k.
            s += ((count * (count + 1)) / 2);
        }
  
        return (n * (n + 1) / 2 - s);
    }
  
    // Driver code
    public static void Main()
    {
        int[] arr = {1, 2, 3};
        int k = 2;
        int n = arr.Length;
        Console.WriteLine(countSubarray(arr, n, k));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to count number of subarrays
// whose maximum element is greater than K.
  
// Return number of subarrays whose maximum
// element is less than or equal to K.
function countSubarray( $arr, $n, $k)
{
      
    // To store count of subarrays with all
    // elements less than or equal to k.
    $s = 0;
  
    // Traversing the array.
    $i = 0;
    while ($i < $n) {
          
        // If element is greater than k,
        // ignore.
        if ($arr[$i] > $k) {
            $i++;

768
Chapter 99. Count of subarrays whose maximum element is greater than k

            continue;
        }
  
        // Counting the subarray length 
        // whose each element is less
        // than equal to k.
        $count = 0;
        while ($i < $n and $arr[$i] <= $k) {
            $i++;
            $count++;
        }
  
        // Suming number of subarray whose
        // maximum element is less than
        // equal to k.
        $s += (($count * ($count + 1)) / 2);
    }
  
    return ($n * ($n + 1) / 2 - $s);
}
  
// Driven Program
    $arr = array( 1, 2, 3 );
    $k = 2;
    $n = count($arr);
    echo countSubarray($arr, $n, $k);
  
// This code is contributed by anuj_67.
?>

Output:

Time Complexity: O(n).


Improved By : vt_m

Source

https://www.geeksforgeeks.org/count-subarrays-whose-maximum-element-greater-k/

769
Chapter 100

Count possible ways to


construct buildings

Count possible ways to construct buildings - GeeksforGeeks


Given an input number of sections and each section has 2 plots on either sides of the road.
Find all possible ways to construct buildings in the plots such that there is a space between
any 2 buildings.
Example :

N = 1
Output = 4
Place a building on one side.
Place a building on other side
Do not place any building.
Place a building on both sides.

N = 3
Output = 25
3 sections, which means possible ways for one side are
BSS, BSB, SSS, SBS, SSB where B represents a building
and S represents an empty space
Total possible ways are 25, because a way to place on
one side can correspond to any of 5 ways on other side.

N = 4
Output = 64

We strongly recommend to minimize your browser and try this yourself first
We can simplify the problem to first calculate for one side only. If we know the result for
one side, we can always do square of the result and get result for two sides.

770
Chapter 100. Count possible ways to construct buildings

A new building can be placed on a section if section just before it has space. A space can
be placed anywhere (it doesn’t matter whether the previous section has a building or not).

Let countB(i) be count of possible ways with i sections


ending with a building.
countS(i) be count of possible ways with i sections
ending with a space.

// A space can be added after a building or after a space.


countS(N) = countB(N-1) + countS(N-1)

// A building can only be added after a space.


countB[N] = countS(N-1)

// Result for one side is sum of the above two counts.


result1(N) = countS(N) + countB(N)

// Result for two sides is square of result1(N)


result2(N) = result1(N) * result1(N)

Below is the implementation of above idea.


C++

// C++ program to count all possible way to construct buildings


#include<iostream>
using namespace std;
  
// Returns count of possible ways for N sections
int countWays(int N)
{
    // Base case
    if (N == 1)
        return 4;  // 2 for one side and 4 for two sides
  
    // countB is count of ways with a building at the end
    // countS is count of ways with a space at the end
    // prev_countB and prev_countS are previous values of
    // countB and countS respectively.
  
    // Initialize countB and countS for one side
    int countB=1, countS=1, prev_countB, prev_countS;
  
    // Use the above recursive formula for calculating
    // countB and countS using previous values
    for (int i=2; i<=N; i++)
    {

771
Chapter 100. Count possible ways to construct buildings

        prev_countB = countB;
        prev_countS = countS;
  
        countS = prev_countB + prev_countS;
        countB = prev_countS;
    }
  
    // Result for one side is sum of ways ending with building
    // and ending with space
    int result = countS + countB;
  
    // Result for 2 sides is square of result for one side
    return (result*result);
}
  
// Driver program
int main()
{
    int N = 3;
    cout << "Count of ways for " << N
         << " sections is " << countWays(N);
    return 0;
}

Java

class Building
{
    // Returns count of possible ways for N sections
    static int countWays(int N)
    {
        // Base case
        if (N == 1)
            return 4;  // 2 for one side and 4 for two sides
       
        // countB is count of ways with a building at the end
        // countS is count of ways with a space at the end
        // prev_countB and prev_countS are previous values of
        // countB and countS respectively.
       
        // Initialize countB and countS for one side
        int countB=1, countS=1, prev_countB, prev_countS;
       
        // Use the above recursive formula for calculating
        // countB and countS using previous values
        for (int i=2; i<=N; i++)
        {
            prev_countB = countB;

772
Chapter 100. Count possible ways to construct buildings

            prev_countS = countS;
       
            countS = prev_countB + prev_countS;
            countB = prev_countS;
        }
       
        // Result for one side is sum of ways ending with building
        // and ending with space
        int result = countS + countB;
       
        // Result for 2 sides is square of result for one side
        return (result*result);
    }
  
  
    public static void main(String args[])
    {
        int N = 3;
        System.out.println("Count of ways for "+ N+" sections is "
                                                        +countWays(N));
    }
  
}/* This code is contributed by Rajat Mishra */

C#

// C# program to count all 


// possible way to construct
// buildings
using System;
  
class GFG
{
    // Returns count of possible
    // ways for N sections
    static int countWays(int N)
    {
        // Base case
        if (N == 1)
          
            // 2 for one side and 
            // 4 for two sides
            return 4; 
      
        // countB is count of ways 
        // with a building at the 
        // end, countS is count of
        // ways with a space at the 

773
Chapter 100. Count possible ways to construct buildings

        // end, prev_countB and 


        // prev_countS are previous 
        // values of countB and countS 
        // respectively.
      
        // Initialize countB and 
        // countS for one side
        int countB = 1, countS = 1, 
            prev_countB, prev_countS;
      
        // Use the above recursive 
        // formula for calculating
        // countB and countS using 
        // previous values
        for (int i = 2; i <= N; i++)
        {
            prev_countB = countB;
            prev_countS = countS;
      
            countS = prev_countB + 
                     prev_countS;
            countB = prev_countS;
        }
      
        // Result for one side is sum 
        // of ways ending with building
        // and ending with space
        int result = countS + countB;
      
        // Result for 2 sides is
        // square of result for
        // one side
        return (result * result);
    }
  
    // Driver Code
    public static void Main()
    {
        int N = 3;
        Console.Write(countWays(N));
    }
  
}
  
// This code is contributed by nitin mittal.

PHP

774
Chapter 100. Count possible ways to construct buildings

<?php
// PHP program to count all possible
// way to construct buildings
  
// Returns count of possible
// ways for N sections
function countWays( $N)
{
      
    // Base case
    if ($N == 1)
      
        // 2 for one side and 
        // 4 for two sides
        return 4; 
  
    // countB is count of ways
    // with a building at the end
    // countS is count of ways 
    // with a space at the end
    // prev_countB and prev_countS 
    // are previous values of
    // countB and countS respectively.
  
    // Initialize countB and 
    // countS for one side
    $countB = 1; $countS = 1; 
    $prev_countB; $prev_countS;
  
    // Use the above recursive 
    // formula for calculating
    // countB and countS using 
    // previous values
    for ($i = 2; $i <= $N; $i++)
    {
        $prev_countB = $countB;
        $prev_countS = $countS;
  
        $countS = $prev_countB + 
                  $prev_countS;
        $countB = $prev_countS;
    }
  
    // Result for one side is 
    // sum of ways ending with 
    // building and ending with
    // space
    $result = $countS + $countB;

775
Chapter 100. Count possible ways to construct buildings

  
    // Result for 2 sides is square
    // of result for one side
    return ($result*$result);
}
  
    // Driver Code
    $N = 3;
    echo "Count of ways for " , $N
          , " sections is " , countWays($N);
  
// This code is contributed by anuj_67.
?>

Output :

Count of ways for 3 sections is 25

Time complexity: O(N)


Auxiliary Space: O(1)
Algorithmic Paradigm: Dynamic Programming
Optimized Solution:
Note that the above solution can be further optimized. If we take closer look at the results,
for different values, we can notice that the results for two sides are squares of Fibonacci
Numbers.
N = 1, result = 4 [result for one side = 2]
N = 2, result = 9 [result for one side = 3]
N = 3, result = 25 [result for one side = 5]
N = 4, result = 64 [result for one side = 8]
N = 5, result = 169 [result for one side = 13]
…………………….
…………………….
In general, we can say

result(N) = fib(N+2)2

fib(N) is a function that returns N'th


Fibonacci Number.

Therefore, we can use O(LogN) implementation of Fibonacci Numbers to find number of


ways in O(logN) time.

776
Chapter 100. Count possible ways to construct buildings

This article is contributed by GOPINATH. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/count-possible-ways-to-construct-buildings/

777
Chapter 101

Count the number of ways to


tile the floor of size n x m using
1 x m size tiles

Count the number of ways to tile the floor of size n x m using 1 x m size tiles - GeeksforGeeks
Given a floor of size n x m and tiles of size 1 x m. The problem is to count the number
of ways to tile the given floor using 1 x m tiles. A tile can either be placed horizontally or
vertically.
Both n and m are positive integers and 2 < = m.
Examples:

Input : n = 2, m = 3
Output : 1
Only one combination to place
two tiles of size 1 x 3 horizontally
on the floor of size 2 x 3.

Input : n = 4, m = 4
Output : 2
1st combination:
All tiles are placed horizontally
2nd combination:
All tiles are placed vertically.

This problem is mainly a more generalized approach to the Tiling Problem.


Approach: For a given value of n and m, the number of ways to tile the floor can be
obtained from the following relation.

778
Chapter 101. Count the number of ways to tile the floor of size n x m using 1 x m size tiles

| 1, 1 < = n < m
count(n) = | 2, n = m
| count(n-1) + count(n-m), m < n

C++

// C++ implementation to count number of ways to


// tile a floor of size n x m using 1 x m tiles
#include <bits/stdc++.h>
  
using namespace std;
  
// function to count the total number of ways
int countWays(int n, int m)
{
  
    // table to store values
    // of subproblems
    int count[n + 1];
    count[0] = 0;
  
    // Fill the table upto value n
    for (int i = 1; i <= n; i++) {
        // recurrence relation
        if (i > m)
            count[i] = count[i - 1] + count[i - m];
  
        // base cases
        else if (i < m)
            count[i] = 1;
  
        // i = = m
        else
            count[i] = 2;
    }
  
    // required number of ways
    return count[n];
}
  
// Driver program to test above
int main()
{
    int n = 7, m = 4;
    cout << "Number of ways = "
         << countWays(n, m);

779
Chapter 101. Count the number of ways to tile the floor of size n x m using 1 x m size tiles

    return 0;
}

Java

// Java implementation to count number


// of ways to tile a floor of size
// n x m using 1 x m tiles
import java.io.*;
  
class GFG {
    // function to count the total number of ways
    static int countWays(int n, int m)
    {
        // table to store values
        // of subproblems
        int count[] = new int[n + 1];
        count[0] = 0;
  
        // Fill the table upto value n
        int i;
        for (i = 1; i <= n; i++) {
            // recurrence relation
            if (i > m)
                count[i] = count[i - 1] + count[i - m];
  
            // base cases
            else if (i < m)
                count[i] = 1;
  
            // i = = m
            else
                count[i] = 2;
        }
  
        // required number of ways
        return count[n];
    }
  
    // Driver program
    public static void main(String[] args)
    {
        int n = 7;
        int m = 4;
        System.out.println("Number of ways = "
                           + countWays(n, m));
    }
}

780
Chapter 101. Count the number of ways to tile the floor of size n x m using 1 x m size tiles

  
// This code is contributed by vt_m.

Python3

# Python implementation to
# count number of ways to 
# tile a floor of size n x m
# using 1 x m tiles
  
def countWays(n, m):
      
    # table to store values
    # of subproblems
    count =[]
    for i in range(n + 2):
        count.append(0)
    count[0] = 0
      
    # Fill the table upto value n
    for i in range(1, n + 1):
      
        # recurrence relation
        if (i > m):
            count[i] = count[i-1] + count[i-m]
          
        # base cases 
        elif (i < m): 
            count[i] = 1
  
        # i = = m 
        else:
            count[i] = 2
      
      
    # required number of ways
    return count[n]
  
  
# Driver code
  
n = 7
m = 4
  
print("Number of ways = ", countWays(n, m))
  
# This code is contributed
# by Anant Agarwal.

781
Chapter 101. Count the number of ways to tile the floor of size n x m using 1 x m size tiles

C#

// C# implementation to count number


// of ways to tile a floor of size
// n x m using 1 x m tiles
using System;
  
class GFG {
  
    // function to count the total
    // number of ways
    static int countWays(int n, int m)
    {
  
        // table to store values
        // of subproblems
        int[] count = new int[n + 1];
        count[0] = 0;
  
        // Fill the table upto value n
        int i;
        for (i = 1; i <= n; i++) {
            // recurrence relation
            if (i > m)
                count[i] = count[i - 1]
                           + count[i - m];
  
            // base cases
            else if (i < m)
                count[i] = 1;
  
            // i = = m
            else
                count[i] = 2;
        }
  
        // required number of ways
        return count[n];
    }
  
    // Driver program
    public static void Main()
    {
        int n = 7;
        int m = 4;
  
        Console.Write("Number of ways = "
                      + countWays(n, m));

782
Chapter 101. Count the number of ways to tile the floor of size n x m using 1 x m size tiles

    }
}
  
// This code is contributed by parashar.

PHP

<?php
// PHP implementation to count 
// number of ways to tile a 
// floor of size n x m using 
// 1 x m tiles
  
// function to count the 
// total number of ways
function countWays($n, $m)
{
      
    // table to store values
    // of subproblems
    $count[0] = 0;
      
    // Fill the table 
    // upto value n
    for ($i = 1; $i <= $n; $i++)
    {
          
        // recurrence relation
        if ($i > $m)
            $count[$i] = $count[$i - 1] + 
                         $count[$i - $m];
          
        // base cases 
        else if ($i < $m) 
            $count[$i] = 1;
  
        // i = = m 
        else
            $count[$i] = 2;
    }
      
    // required number of ways
    return $count[$n];
}
  
    // Driver Code
    $n = 7;
    $m = 4;

783
Chapter 101. Count the number of ways to tile the floor of size n x m using 1 x m size tiles

    echo "Number of ways = ", countWays($n, $m);


  
// This code is contributed by ajit
?>

Output:

Number of ways = 5

Time Complexity: O(n)


Auxiliary Space: O(n)
Improved By : parashar, jit_t

Source

https://www.geeksforgeeks.org/count-number-ways-tile-floor-size-n-x-m-using-1-x-m-size-tiles/

784
Chapter 102

Count total number of N digit


numbers such that the
difference between sum of even
and odd digits is 1

Count total number of N digit numbers such that the difference between sum of even and
odd digits is 1 - GeeksforGeeks
Given a number n, we need to count total number of n digit numbers such that the sum
of even digits is 1 more than the sum of odd digits. Here even and odd means positions of
digits are like array indexes, for exampl, the leftmost (or leading) digit is considered as even
digit, next to leftmost is considered as odd and so on.
Example

Input: n = 2
Output: Required Count of 2 digit numbers is 9
Explanation : 10, 21, 32, 43, 54, 65, 76, 87, 98.

Input: n = 3
Output: Required Count of 3 digit numbers is 54
Explanation: 100, 111, 122, ......, 980

We strongly recommend you to minimize your browser and try this yourself
first.
This problem is mainly an extension of Count of n digit numbers whose sum of digits equals
to given sum. Here the solution of subproblems depend on four variables: digits, esum
(current even sum), osum (current odd sum), isEven(A flag to indicate whether current
digit is even or odd).

785
Chapter 102. Count total number of N digit numbers such that the difference between sum
of even and odd digits is 1

Below is Memoization based solution for the same.

// A memoization based recursive program to count numbers


// with difference between odd and even digit sums as 1
#include<bits/stdc++.h>
   
using namespace std;
   
// A lookup table used for memoization.
unsigned long long int lookup[50][1000][1000][2];
   
// Memnoization based recursive function to count numbers
// with even and odd digit sum difference as 1.  This function
// conisders leading zero as a digit
unsigned long long int  countRec(int digits, int esum,
                               int osum, bool isOdd, int n)
{
    // Base Case
    if (digits == n)
        return (esum - osum == 1);
   
    // If current subproblem is already computed
    if (lookup[digits][esum][osum][isOdd] != -1)
        return lookup[digits][esum][osum][isOdd];
   
    // Initialize result
    unsigned long long int ans = 0;
   
    // If current digit is odd, then add it to odd sum and recur
    if (isOdd)
      for (int i = 0; i <= 9; i++)
          ans +=  countRec(digits+1, esum, osum+i, false, n);
    else // Add to even sum and recur
      for (int i = 0; i <= 9; i++)
          ans +=  countRec(digits+1, esum+i, osum, true, n);
   
    // Store current result in lookup table and return the same
    return lookup[digits][esum][osum][isOdd] = ans;
}
   
// This is mainly a wrapper over countRec. It
// explicitly handles leading digit and calls
// countRec() for remaining digits.
unsigned long long int finalCount(int n)
{
    // Initialize number digits considered so far
    int digits = 0;
   

786
Chapter 102. Count total number of N digit numbers such that the difference between sum
of even and odd digits is 1

    // Initialize all entries of lookup table


    memset(lookup, -1, sizeof lookup);
   
    // Initializa final answer
    unsigned long long int ans = 0;
   
    // Initialize even and odd sums
    int esum = 0, osum = 0;
   
    // Explicitly handle first digit and call recursive function
    // countRec for remaining digits.  Note that the first digit
    // is considered as even digit.
    for (int i = 1; i <= 9; i++)
          ans +=  countRec(digits+1, esum + i, osum, true, n);
   
    return ans;
}
   
// Driver program
int main()
{
    int n = 3;
    cout << "Coutn of "<<n << " digit numbers is " << finalCount(n);
    return 0;
}

Output:

Count of 3 digit numbers is 54

Thanks to Gaurav Ahirwar for providing above solution.

Source

https://www.geeksforgeeks.org/count-total-number-of-n-digit-numbers-such-that-the-difference-between-the-sum-o

787
Chapter 103

Count ways to build street


under given constraints

Count ways to build street under given constraints - GeeksforGeeks


There is a street of length n and as we know it has two sides. Therefore a total of 2 * n spots
are available. In each of these spots either a house or an office can be built with following
2 restrictions:
1. No two offices on the same side of the street can be adjacent.
2. No two offices on different sides of the street can be exactly opposite to each other i.e.
they can’t overlook each other.
There are no restrictions on building houses and each spot must either have a house or office.
Given length of the street n, find total number of ways to build the street.
Source: Intuit Interview
Examples:

Input : 2
Output : 7
Please see below diagram for explanation.

Input : 3
Output : 17

Following image depicts the 7 possible ways for building the street with N = 2

788
Chapter 103. Count ways to build street under given constraints

Ways for building street with length 1


with 2 houses: (H H) = {1}
with 1 office and 1 house: (O H) (H O) = {2}
(O O) is not allowed according to the problem statement.
Total = 1 + 2 = 3

For length = 2,
with 2 houses: (H H) can be added to all
the cases of length 1:

(H H) (H H) (H H)
(H H) (O H) (H O) = {3}

with 1 office and 1 house:


(O H) and (H O) can both be added to all
the cases of length 1 with last row (H H)

(O H) (H O)
(H H) (H H) = {2}

when last row of a case of length 1


contains 1 office, it can only be
extended in one way to build an office
in row 2.
(H O) (O H)
(O H) (H O) = {2}

789
Chapter 103. Count ways to build street under given constraints

(O H) (H O) (O O)
(O H) (H O) (O H) etc are not allowed.

Total = 3 + 2 + 2 = 7

Since the problem can be solved by finding solution for smaller subproblems and then
extending the same logic, it can be solved using dynamic programming. We move in steps
of one unit length. For each row we have two options:
Build houses in both the spots
Build one house and one office
The first one can be done without any constraints. There is one way of building houses in
both the spots at length i. So total ways using this choice = total ways for length i – 1.
For the second choice, if row (i-1) had houses in both spots we have two ways of building a
office i.e. (H O) and (O H)
if row(i-1) had an office in one of its two spots we only have one way to build an office in
row i.If prev row had (O H) curr row would have (H O) and similarly for prev row = (H O)
curr row = (O H).
From the above logic, total ways with this choice = 2 * (choice1(i-1)) + choice2(i-1)
We will build a 2D dp for this.
dp[0][i] indicates choice1 and dp[1][i] indicates choice2 for row i.
Below is the implementation of above idea :
C++

// C++ program to count ways to build street 


// under given constraints
#include <bits/stdc++.h>
using namespace std;
  
// function to count ways of building
// a street of n rows
long countWays(int n)
{
    long dp[2][n + 1];
  
    // base case
    dp[0][1] = 1;
    dp[1][1] = 2;
  
    for (int i = 2; i <= n; i++) {
  
        // ways of building houses in both
        // the spots of ith row
        dp[0][i] = dp[0][i - 1] + dp[1][i - 1];
  

790
Chapter 103. Count ways to build street under given constraints

        // ways of building an office in one of


        // the two spots of ith row
        dp[1][i] = dp[0][i - 1] * 2 + dp[1][i - 1];
    }
  
    // total ways for n rows
    return dp[0][n] + dp[1][n];
}
  
// driver program for checking above function
int main()
{
  
    int n = 5;
    cout << "Total no of ways with n = " << n
         << " are: " << countWays(n) << endl;
}

PHP

<?php
// PHP program to count ways to build street 
// under given constraints
  
// function to count ways of building
// a street of n rows
function countWays($n)
{
  
    // base case
    $dp[0][1] = 1;
    $dp[1][1] = 2;
  
    for ($i = 2; $i <= $n; $i++) {
  
        // ways of building houses in both
        // the spots of ith row
        $dp[0][$i] = $dp[0][$i - 1] + 
                     $dp[1][$i - 1];
  
        // ways of building an office in one of
        // the two spots of ith row
        $dp[1][$i] = $dp[0][$i - 1] * 
                     2 + $dp[1][$i - 1];
    }
  
    // total ways for n rows
    return $dp[0][$n] + $dp[1][$n];

791
Chapter 103. Count ways to build street under given constraints

}
  
    // Driver Code
    $n = 5;
    echo "Total no of ways with n = ",$n,
         " are: " ,countWays($n),"\n";
  
// This code is contributed by jit_t
?>

Output:

Total no of ways with n = 5 are: 99

Time Complexity: O(N)


Auxiliary Space : O(N)
Improved By : jit_t

Source

https://www.geeksforgeeks.org/count-ways-build-street-given-constraints/

792
Chapter 104

Count ways to divide circle


using N non-intersecting chords

Count ways to divide circle using N non-intersecting chords - GeeksforGeeks


Given a number N, find the number of ways you can draw N chords in a circle with 2*N
points such that no 2 chords intersect.
Two ways are different if there exists a chord which is present in one way and not in other.
Examples:

Input : N = 2
Output : 2
Explanation: If points are numbered 1 to 4 in
clockwise direction, then different ways to
draw chords are:
{(1-2), (3-4)} and {(1-4), (2-3)}

Input : N = 1
Output : 1
Explanation: Draw a chord between points 1 and 2.

If we draw a chord between any two points, can you observe the current set of points
getting broken into two smaller sets S_1 and S_2. If we draw a chord from a point in S_1
to a point in S_2, it will surely intersect the chord we’ve just drawn.
So, we can arrive at a recurrence that Ways(n) = sum[i = 0 to n-1] { Ways(i)*Ways(n-i-1)
}.
Here we iterate over i, assuming that size of one of the sets is i and size of another set
automatically is (n-i-1) since we’ve already used a pair of points and i pair of points in one set.

C++

793
Chapter 104. Count ways to divide circle using N non-intersecting chords

// cpp code to count ways 


// to divide circle using
// N non-intersecting chords.
#include <bits/stdc++.h>
using namespace std;
  
int chordCnt( int A){
  
    // n = no of points required
    int n = 2 * A;
      
    // dp array containing the sum
    int dpArray[n + 1]={ 0 };
    dpArray[0] = 1;
    dpArray[2] = 1;
    for (int i=4;i<=n;i+=2){
        for (int j=0;j<i-1;j+=2){ 
              
          dpArray[i] +=
            (dpArray[j]*dpArray[i-2-j]);
        }
    } 
  
    // returning the required number
    return dpArray[n];
}
// Driver function
int main()
{
  
    int N;
    N = 2;
cout<<chordCnt( N)<<'\n';
    N = 1;
cout<<chordCnt( N)<<'\n';
    N = 4;
cout<<chordCnt( N)<<'\n';
    return 0;
}
  
// This code is contributed by Gitanjali.

Java

// Java code to count ways


// to divide circle using
// N non-intersecting chords.
import java.io.*;

794
Chapter 104. Count ways to divide circle using N non-intersecting chords

  
class GFG {
    static int chordCnt(int A)
    {
  
        // n = no of points required
        int n = 2 * A;
  
        // dp array containing the sum
        int[] dpArray = new int[n + 1];
        dpArray[0] = 1;
        dpArray[2] = 1;
        for (int i = 4; i <= n; i += 2) {
            for (int j = 0; j < i - 1; j += 2) 
            {
                dpArray[i] += (dpArray[j] * 
                              dpArray[i - 2 - j]);
            }
        }
  
        // returning the required number
        return dpArray[n];
    }
    public static void main(String[] args)
    {
        int N;
        N = 2;
        System.out.println(chordCnt(N));
        N = 1;
        System.out.println(chordCnt(N));
        N = 4;
        System.out.println(chordCnt(N));
    }
}
  
// This code is contributed by Gitanjali.

Python 3

# python code to count ways to divide


# circle using N non-intersecting chords.
def chordCnt( A):
  
    # n = no of points required
    n = 2 * A
  
    # dp array containing the sum
    dpArray = [0]*(n + 1)

795
Chapter 104. Count ways to divide circle using N non-intersecting chords

    dpArray[0] = 1
    dpArray[2] = 1
    for i in range(4, n + 1, 2):
        for j in range(0, i-1, 2):
            dpArray[i] += (dpArray[j]*dpArray[i-2-j])
  
    # returning the required number
    return int(dpArray[n])
  
# driver code
N = 2
print(chordCnt( N))
N = 1
print(chordCnt( N))
N = 4
print(chordCnt( N))

C#

// C# code to count ways to divide 


// circle using N non-intersecting chords.
using System;
  
class GFG {
      
    static int chordCnt(int A)
    {
        // n = no of points required
        int n = 2 * A;
  
        // dp array containing the sum
        int[] dpArray = new int[n + 1];
        dpArray[0] = 1;
        dpArray[2] = 1;
          
        for (int i = 4; i <= n; i += 2) 
        {
            for (int j = 0; j < i - 1; j += 2)
            {
                dpArray[i] += (dpArray[j] * dpArray[i - 2 - j]);
            }
        }
  
        // returning the required number
        return dpArray[n];
    }
      
    // Driver code

796
Chapter 104. Count ways to divide circle using N non-intersecting chords

    public static void Main()


    {
        int N;
        N = 2;
        Console.WriteLine(chordCnt(N));
        N = 1;
        Console.WriteLine(chordCnt(N));
        N = 4;
        Console.WriteLine(chordCnt(N));
    }
}
  
// This code is contributed by vt_m.

Output:

2
1
14

Source

https://www.geeksforgeeks.org/count-ways-divide-circle-using-n-non-intersecting-chords/

797
Chapter 105

Count ways to increase LCS


length of two strings by one

Count ways to increase LCS length of two strings by one - GeeksforGeeks


Given two strings of lower alphabet characters, we need to find the number of ways to insert
a character in the first string such that length of LCS of both strings increases by one.
Examples:

Input : str1 = “abab”, str2 = “abc”


Output : 3
LCS length of given two strings is 2.
There are 3 ways of insertion in str1,
to increase the LCS length by one which
are enumerated below,
str1 = “abcab” str2 = “abc” LCS length = 3
str1 = “abacb” str2 = “abc” LCS length = 3
str1 = “ababc” str2 = “abc” LCS length = 3

Input : str1 = “abcabc”, str2 = “abcd”


Output : 4

The idea is try all 26 possible characters at each position of first string, if length of str1
is m then a new character can be inserted in (m + 1) positions, now suppose at any time
character c is inserted at ith position in str1 then we will match it with all positions having
character c in str2. Suppose one such position is j, then for total LCS length to be one more
than previous, below condition should satisfy,

LCS(str1[1, m], str2[1, n]) = LCS(str1[1, i], str2[1, j-1]) +


LCS(str1[i+1, m], str2[j+1, n])

798
Chapter 105. Count ways to increase LCS length of two strings by one

Above equation states that sum of LCS of the suffix and prefix substrings at inserted char-
acter must be same as total LCS of strings, so that when the same character is inserted in
first string it will increase the length of LCS by one.
In below code two 2D arrays, lcsl and lcsr are used for storing LCS of prefix and suffix of
strings respectively. Method for filling these 2D arrays can be found here.
Please see below code for better understanding,

// C++ program to get number of ways to increase


// LCS by 1
#include <bits/stdc++.h>
using namespace std;
  
#define M 26
  
// Utility method to get integer position of lower
// alphabet character
int toInt(char ch)
{
    return (ch - 'a');
}
  
// Method returns total ways to increase LCS length by 1
int waysToIncreaseLCSBy1(string str1, string str2)
{
    int m = str1.length(), n = str2.length();
  
    // Fill positions of each character in vector
    vector<int> position[M];
    for (int i = 1; i <= n; i++)
        position[toInt(str2[i-1])].push_back(i);
  
    int lcsl[m + 2][n + 2];
    int lcsr[m + 2][n + 2];
  
    // Initializing 2D array by 0 values
    for (int i = 0; i <= m+1; i++)
        for (int j = 0; j <= n + 1; j++)
            lcsl[i][j] = lcsr[i][j] = 0;
  
    // Filling LCS array for prefix substrings
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (str1[i-1] == str2[j-1])
                lcsl[i][j] = 1 + lcsl[i-1][j-1];
            else
                lcsl[i][j] = max(lcsl[i-1][j],

799
Chapter 105. Count ways to increase LCS length of two strings by one

                                lcsl[i][j-1]);
        }
    }
  
    // Filling LCS array for suffix substrings
    for (int i = m; i >= 1; i--)
    {
        for (int j = n; j >= 1; j--)
        {
            if (str1[i-1] == str2[j-1])
                lcsr[i][j] = 1 + lcsr[i+1][j+1];
            else
                lcsr[i][j] = max(lcsr[i+1][j],
                                 lcsr[i][j+1]);
        }
    }
  
    // Looping for all possible insertion positions
    // in first string
    int ways = 0;
    for (int i=0; i<=m; i++)
    {
        // Trying all possible lower case characters
        for (char c='a'; c<='z'; c++)
        {
            // Now for each character, loop over same
            // character positions in second string
            for (int j=0; j<position[toInt(c)].size(); j++)
            {
                int p = position[toInt(c)][j];
  
                // If both, left and right substrings make
                // total LCS then increase result by 1
                if (lcsl[i][p-1] + lcsr[i+1][p+1] == lcsl[m][n])
                    ways++;
            }
        }
    }
  
    return ways;
}
  
//  Driver code to test above methods
int main()
{
    string str1 = "abcabc";
    string str2 = "abcd";
    cout << waysToIncreaseLCSBy1(str1, str2);

800
Chapter 105. Count ways to increase LCS length of two strings by one

    return 0;
}

Output:

Time Complexity : O(mn)


Auxiliary Space : O(mn)

Source

https://www.geeksforgeeks.org/count-ways-increase-lcs-length-two-strings-one/

801
Chapter 106

Count ways to reach the nth


stair using step 1, 2 or 3

Count ways to reach the nth stair using step 1, 2 or 3 - GeeksforGeeks


A child is running up a staircase with n steps and can hop either 1 step, 2 steps, or 3 steps
at a time. Implement a method to count how many possible ways the child can run up the
stairs.
There are two methods to solve this problem
1. Recursive Method
2. Dynamic Programming
Examples :

Input : 4
Output : 7

Input : 3
Output : 4

1. Recursive Method
How Code is Working :
Suppose you have n stairs then you can hop either 1 step, 2 step, 3 step.
1. If you hop 1 step then remaining stairs = n-1
2. If you hop 2 step then remaining stairs = n-2
3. If you hop 3 step then remaining stairs = n-3
If you hop 1 step then again you can hop 1 step, 2 step, 3 step until n equals 0.
Repeat this process and count total number of ways to reach at nth stair using step 1, 2, 3.

802
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

// Program to find n-th stair using step size


// 1 or 2 or 3.
#include <stdio.h>
  
// Returns count of ways to reach n-th stair
// using 1 or 2 or 3 steps.
int findStep(int n)
{
    if (n == 1 || n == 0) 
        return 1;
    else if (n == 2) 
        return 2;
      
    else 
        return findStep(n - 3) + 
               findStep(n - 2) +
               findStep(n - 1);    
}
  
// Driver code
int main()
{
    int n = 4;
    printf("%d\n", findStep(n));
    return 0;
}

Java

// Program to find n-th stair


// using step size 1 or 2 or 3.
import java.util.*;
import java.lang.*;
  
public class GfG{
      
    // Returns count of ways to reach
    // n-th stair using 1 or 2 or 3 steps.
    public static int findStep(int n)
    {
        if (n == 1 || n == 0) 
            return 1;
        else if (n == 2) 
            return 2;
       
        else
            return findStep(n - 3) + 
                   findStep(n - 2) +

803
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

                   findStep(n - 1);    
    }
      
    // Driver function
    public static void main(String argc[]){
        int n = 4;
        System.out.println(findStep(n));
    }
}
  
/* This code is contributed by Sagar Shukla */

Python

# Python program to find n-th stair  


# using step size 1 or 2 or 3.
  
# Returns count of ways to reach n-th 
# stair using 1 or 2 or 3 steps.
def findStep( n) :
    if (n == 1 or n == 0) :
        return 1
    elif (n == 2) :
        return 2
      
    else :
        return findStep(n - 3) + findStep(n - 2) + findStep(n - 1) 
  
  
# Driver code
n = 4
print(findStep(n))
  
#This code is contributed by Nikita Tiwari.

C#

// Program to find n-th stair


// using step size 1 or 2 or 3.
using System;
  
public class GfG{
      
    // Returns count of ways to reach
    // n-th stair using 1 or 2 or 3 steps.
    public static int findStep(int n)
    {

804
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

        if (n == 1 || n == 0) 
            return 1;
        else if (n == 2) 
            return 2;
      
        else
            return findStep(n - 3) + 
                   findStep(n - 2) +
                   findStep(n - 1); 
    }
      
    // Driver function
    public static void Main(){
        int n = 4;
        Console.WriteLine(findStep(n));
    }
}
  
/* This code is contributed by vt_m */

PHP

<?php
// PHP Program to find n-th stair 
// using step size 1 or 2 or 3.
  
// Returns count of ways to 
// reach n-th stair using  
// 1 or 2 or 3 steps.
function findStep($n)
{
    if ($n == 1 || $n == 0) 
        return 1;
    else if ($n == 2) 
        return 2;
      
    else
        return findStep($n - 3) + 
               findStep($n - 2) +
                findStep($n - 1); 
}
  
// Driver code
$n = 4;
echo findStep($n);
  
// This code is contributed by m_kit
?>

805
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

Output :

How Code is Working….

806
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

The Time Complexity of the program is Optimized using Dynamic Programming.


2. Using Dynamic Programming

// A C program to count number of ways to reach n't stair when


#include <stdio.h>
  
// A recursive function used by countWays
int countWays(int n)
{
    int res[n + 1];
    res[0] = 1;
    res[1] = 1;
    res[2] = 2;
    for (int i = 3; i <= n; i++) 
        res[i] = res[i-1] + res[i-2] 
                          + res[i-3];
      
    return res[n];
}
  
// Driver program to test above functions
int main()
{
    int n = 4;
    printf("%d", countWays(n));
    return 0;
}

Java

// Program to find n-th stair


// using step size 1 or 2 or 3.
import java.util.*;
import java.lang.*;
  
public class GfG {
  
    // A recursive function used by countWays
    public static int countWays(int n)
    {
        int[] res = new int[n + 1];
        res[0] = 1;
        res[1] = 1;
        res[2] = 2;

807
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

  
        for (int i = 3; i <= n; i++)
            res[i] = res[i - 1] + res[i - 2]
                                + res[i - 3];
  
        return res[n];
    }
  
    // Driver function
    public static void main(String argc[])
    {
        int n = 4;
        System.out.println(countWays(n));
    }
}
  
/* This code is contributed by Sagar Shukla */

Python

# Python program to find n-th stair  


# using step size 1 or 2 or 3.
  
# A recursive function used by countWays
def countWays(n) :
    res = [0] * (n + 1)
    res[0] = 1
    res[1] = 1
    res[2] = 2
      
    for i in range(3, n + 1) :
        res[i] = res[i - 1] + res[i - 2] + res[i - 3]
      
    return res[n]
  
# Driver code
n = 4
print(countWays(n))
  
  
# This code is contributed by Nikita Tiwari.

C#

// Program to find n-th stair


// using step size 1 or 2 or 3.
using System;

808
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

  
public class GfG {
  
    // A recursive function used by countWays
    public static int countWays(int n)
    {
        int[] res = new int[n + 1];
        res[0] = 1;
        res[1] = 1;
        res[2] = 2;
  
        for (int i = 3; i <= n; i++)
            res[i] = res[i - 1] + res[i - 2]
                                + res[i - 3];
  
        return res[n];
    }
  
    // Driver function
    public static void Main()
    {
        int n = 4;
        Console.WriteLine(countWays(n));
    }
}
  
/* This code is contributed by vt_m */

PHP

<?php
// A PHP program to count 
// number of ways to reach 
// n'th stair when
  
// A recursive function
// used by countWays
function countWays($n)
{
    $res[0] = 1;
    $res[1] = 1;
    $res[2] = 2;
    for ($i = 3; $i <= $n; $i++) 
        $res[$i] = $res[$i - 1] + 
                   $res[$i - 2] + 
                   $res[$i - 3];
      
    return $res[$n];

809
Chapter 106. Count ways to reach the nth stair using step 1, 2 or 3

}
  
// Driver Code
$n = 4;
echo countWays($n);
  
// This code is contributed by ajit
?>

Output :

Output Explanation :
1 -> 1 -> 1 -> 1
1 -> 1 -> 2
1 -> 2 -> 1
1 -> 3
2 -> 1 -> 1
2 -> 2
3 -> 1
So Total ways: 7
Other Related Articles
http://www.geeksforgeeks.org/count-ways-reach-nth-stair/
Improved By : jit_t

Source

https://www.geeksforgeeks.org/count-ways-reach-nth-stair-using-step-1-2-3/

810
Chapter 107

Count ways to reach the n’th


stair

Count ways to reach the n’th stair - GeeksforGeeks


There are n stairs, a person standing at the bottom wants to reach the top. The person can
climb either 1 stair or 2 stairs at a time. Count the number of ways, the person can reach
the top.

Consider the example shown in diagram. The value of n is 3. There are 3 ways to reach the
top. The diagram is taken from Easier Fibonacci puzzles

More Examples:

811
Chapter 107. Count ways to reach the n’th stair

Input: n = 1
Output: 1
There is only one way to climb 1 stair

Input: n = 2
Output: 2
There are two ways: (1, 1) and (2)

Input: n = 4
Output: 5
(1, 1, 1, 1), (1, 1, 2), (2, 1, 1), (1, 2, 1), (2, 2)

We can easily find recursive nature in above problem. The person can reach n’th stair from
either (n-1)’th stair or from (n-2)’th stair. Let the total number of ways to reach n’t stair
be ‘ways(n)’. The value of ‘ways(n)’ can be written as following.

ways(n) = ways(n-1) + ways(n-2)

The above expression is actually the expression for Fibonacci numbers, but there is one
thing to notice, the value of ways(n) is equal to fibonacci(n+1).
ways(1) = fib(2) = 1
ways(2) = fib(3) = 2
ways(3) = fib(4) = 3
So we can use function for fibonacci numbers to find the value of ways(n). Following is
C++ implementation of the above idea.

// A C program to count number of ways to reach n't stair when


// a person can climb 1, 2, ..m stairs at a time.
#include<stdio.h>
  
// A simple recursive program to find n'th fibonacci number
int fib(int n)
{
   if (n <= 1)
      return n;
   return fib(n-1) + fib(n-2);
}
  
// Returns number of ways to reach s'th stair
int countWays(int s)
{
    return fib(s + 1);
}

812
Chapter 107. Count ways to reach the n’th stair

  
// Driver program to test above functions
int main ()
{
  int s = 4;
  printf("Number of ways = %d", countWays(s));
  getchar();
  return 0;
}

Java

class stairs
{
    // A simple recursive program to find n'th fibonacci number
    static int fib(int n)
    {
       if (n <= 1)
          return n;
       return fib(n-1) + fib(n-2);
    }
      
    // Returns number of ways to reach s'th stair
    static int countWays(int s)
    {
        return fib(s + 1);
    }
  
  
    /* Driver program to test above function */ 
    public static void main (String args[])
    {
          int s = 4;
            System.out.println("Number of ways = "+ countWays(s));
    }
}/* This code is contributed by Rajat Mishra */

Python

# A program to count the number of ways to reach n'th stair


  
# Recurssive program to find n'th fibonacci number
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)
  

813
Chapter 107. Count ways to reach the n’th stair

# returns no. of ways to reach s'th stair


def countWays(s):
    return fib(s + 1)
  
# Driver program
  
s = 4
print "Number of ways = ",
print countWays(s)
  
# Contributed by Harshit Agrawal

C#

// C# program to count the 


// number of ways to reach 
// n'th stair 
using System;
  
class GFG
{
    // A simple recursive
    // program to find n'th
    // fibonacci number
    static int fib(int n)
    {
    if (n <= 1)
        return n;
    return fib(n - 1) + 
           fib(n - 2);
    }
      
    // Returns number of ways
    // to reach s'th stair
    static int countWays(int s)
    {
        return fib(s + 1);
    }
  
        // Driver Code
    static public void Main ()
    {
        int s = 4;
        Console.WriteLine("Number of ways = " + 
                                 countWays(s));
    }
}
  

814
Chapter 107. Count ways to reach the n’th stair

// This code is contributed 


// by akt_mit

PHP

<?php
// A PHP program to count 
// number of ways to reach 
// n'th stair when a person
// can climb 1, 2, ..m stairs 
// at a time. 
  
// A simple recursive
// function to find n'th 
// fibonacci number
function fib($n)
{
if ($n <= 1)
    return $n;
return fib($n - 1) + 
       fib($n - 2);
}
  
// Returns number of 
// ways to reach s'th stair
function countWays($s)
{
    return fib($s + 1);
}
  
// Driver Code
$s = 4;
echo "Number of ways = ", 
           countWays($s);
  
// This code is contributed
// by m_kit
?>

Output:

Number of ways = 5

The time complexity of the above implementation is exponential (golden ratio raised to
power n). It can be optimized to work in O(Logn) time using the previously discussed
Fibonacci function optimizations.

815
Chapter 107. Count ways to reach the n’th stair

Generalization of the above problem


How to count number of ways if the person can climb up to m stairs for a given value m?
For example if m is 4, the person can climb 1 stair or 2 stairs or 3 stairs or 4 stairs at a
time.
We can write the recurrence as following.

ways(n, m) = ways(n-1, m) + ways(n-2, m) + ... ways(n-m, m)

Following is the implementation of above recurrence.

// A C program to count number of ways to reach n't stair when


// a person can climb either 1 or 2 stairs at a time
#include<stdio.h>
  
// A recursive function used by countWays
int countWaysUtil(int n, int m)
{
    if (n <= 1)
        return n;
    int res = 0;
    for (int i = 1; i<=m && i<=n; i++)
        res += countWaysUtil(n-i, m);
    return res;
}
  
// Returns number of ways to reach s'th stair
int countWays(int s, int m)
{
    return countWaysUtil(s+1, m);
}
  
// Driver program to test above functions-
int main ()
{
    int s = 4, m = 2;
    printf("Nuber of ways = %d", countWays(s, m));
    return 0;
}

Java

class stairs
{

816
Chapter 107. Count ways to reach the n’th stair

    // A recursive function used by countWays


    static int countWaysUtil(int n, int m)
    {
        if (n <= 1)
            return n;
        int res = 0;
        for (int i = 1; i<=m && i<=n; i++)
            res += countWaysUtil(n-i, m);
        return res;
    }
   
    // Returns number of ways to reach s'th stair
    static int countWays(int s, int m)
    {
        return countWaysUtil(s+1, m);
    }
  
  
    /* Driver program to test above function */ 
    public static void main (String args[])
    {
          int s = 4,m = 2;
            System.out.println("Number of ways = "+ countWays(s,m));
    }
}/* This code is contributed by Rajat Mishra */

Python

# A program to count the number of ways to reach n'th stair


  
# Recursive function used by countWays
def countWaysUtil(n,m):
    if n <= 1:
        return n
    res = 0
    i = 1
    while i<=m and i<=n:
        res = res + countWaysUtil(n-i, m)
        i = i + 1
    return res
      
# Returns number of ways to reach s'th stair    
def countWays(s,m):
    return countWaysUtil(s+1, m)
      
  
# Driver program
s,m = 4,2

817
Chapter 107. Count ways to reach the n’th stair

print "Number of ways =",countWays(s, m)


  
# Contributed by Harshit Agrawal

C#

// C# program to Count ways to reach


// the n’th stair
using System;
  
class GFG {
      
    // A recursive function used by 
    // countWays
    static int countWaysUtil(int n, int m)
    {
        if (n <= 1)
            return n;
        int res = 0;
          
        for (int i = 1; i <= m && i <= n; i++)
            res += countWaysUtil(n-i, m);
        return res;
    }
  
    // Returns number of ways to reach
    // s'th stair
    static int countWays(int s, int m)
    {
        return countWaysUtil(s+1, m);
    }
  
    /* Driver program to test above function */
    public static void Main ()
    {
        int s = 4,m = 2;
        Console.Write("Number of ways = "
                           + countWays(s, m));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// A PHP program to count 

818
Chapter 107. Count ways to reach the n’th stair

// number of ways to reach 


// n'th stair when a person 
// can climb either 1 or 2 
// stairs at a time 
  
// A recursive function
// used by countWays
function countWaysUtil($n, $m)
{
    if ($n <= 1)
        return $n;
    $res = 0;
    for ($i = 1; $i <= $m && 
                 $i <= $n; $i++)
        $res += countWaysUtil($n - $i, $m);
    return $res;
}
  
// Returns number of ways
// to reach s'th stair
function countWays($s, $m)
{
    return countWaysUtil($s + 1, $m);
}
  
// Driver Code
$s = 4; $m = 2;
echo "Nuber of ways = ",
      countWays($s, $m);
      
// This code is contributed
// by akt_mit
?>

Output:

Number of ways = 5

The time complexity of above solution is exponential. It can be optimized to O(mn) by


using dynamic programming. Following is dynamic programming based solution. We build
a table res[] in bottom up manner.

// A C program to count number of ways to reach n't stair when


// a person can climb 1, 2, ..m stairs at a time
#include<stdio.h>

819
Chapter 107. Count ways to reach the n’th stair

  
// A recursive function used by countWays
int countWaysUtil(int n, int m)
{
    int res[n];
    res[0] = 1; res[1] = 1;
    for (int i=2; i<n; i++)
    {
       res[i] = 0;
       for (int j=1; j<=m && j<=i; j++)
         res[i] += res[i-j];
    }
    return res[n-1];
}
  
// Returns number of ways to reach s'th stair
int countWays(int s, int m)
{
    return countWaysUtil(s+1, m);
}
  
// Driver program to test above functions
int main ()
{
    int s = 4, m = 2;
    printf("Nuber of ways = %d", countWays(s, m));
    return 0;
}

Java

// Java program to count number of ways to reach n't stair when


// a person can climb 1, 2, ..m stairs at a time
  
class GFG
{
    // A recursive function used by countWays
    static int countWaysUtil(int n, int m)
    {
        int res[] = new int[n];
        res[0] = 1; res[1] = 1;
        for (int i=2; i<n; i++)
        {
           res[i] = 0;
           for (int j=1; j<=m && j<=i; j++)
             res[i] += res[i-j];
        }
        return res[n-1];

820
Chapter 107. Count ways to reach the n’th stair

    }
       
    // Returns number of ways to reach s'th stair
    static int countWays(int s, int m)
    {
        return countWaysUtil(s+1, m);
    }
  
    // Driver method 
    public static void main(String[] args)
    {
        int s = 4, m = 2;
        System.out.println("Nuber of ways = " + countWays(s, m));
    }
}

Python

# A program to count the number of ways to reach n'th stair


  
# Recursive function used by countWays
def countWaysUtil(n,m):
    res = [0 for x in range(n)] # Creates list res witth all elements 0
    res[0],res[1] = 1,1
      
    for i in range(2,n):
        j = 1
        while j<=m and j<=i:
            res[i] = res[i] + res[i-j]
            j = j + 1 
    return res[n-1]
  
# Returns number of ways to reach s'th stair
def countWays(s,m):
    return countWaysUtil(s+1, m)
      
# Driver Program
s,m = 4,2
print "Nmber of ways =",countWays(s,m)
      
# Contributed by Harshit Agrawal

C#

// C# program to count number 


// of ways to reach n't stair when
// a person can climb 1, 2, ..m 

821
Chapter 107. Count ways to reach the n’th stair

// stairs at a time
using System;
class GFG {
      
    // A recursive function
    // used by countWays
    static int countWaysUtil(int n, int m)
    {
        int []res = new int[n];
        res[0] = 1; res[1] = 1;
        for (int i = 2; i < n; i++)
        {
            res[i] = 0;
            for (int j = 1; j <= m && j <= i; j++)
                res[i] += res[i - j];
        }
        return res[n - 1];
    }
      
    // Returns number of ways 
    // to reach s'th stair
    static int countWays(int s, int m)
    {
        return countWaysUtil(s + 1, m);
    }
  
    // Driver Code
    public static void Main()
    {
        int s = 4, m = 2;
        Console.WriteLine("Number of ways = " + countWays(s, m));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// A PHP program to count number 
// of ways to reach n't stair when
// a person can climb 1, 2, ..m 
// stairs at a time
  
// A recursive function used by countWays
function countWaysUtil($n, $m)
{
    $res[0] = 1; $res[1] = 1;

822
Chapter 107. Count ways to reach the n’th stair

    for ($i = 2; $i < $n; $i++)


    {
        $res[$i] = 0;
        for ($j = 1; $j <= $m && $j <= $i; $j++)
        $res[$i] += $res[$i - $j];
    }
    return $res[$n - 1];
}
  
// Returns number of ways
// to reach s'th stair
function countWays($s, $m)
{
    return countWaysUtil($s + 1, $m);
}
  
    // Driver Code
    $s = 4; 
    $m = 2;
    echo "Nuber of ways = ", countWays($s, $m);
  
// This code is contributed by m_kit 
?>

Output:

Number of ways = 5

This article is contributed by Abhishek. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : jit_t, vt_m, nitin mittal, Saurabh Vemuri

Source

https://www.geeksforgeeks.org/count-ways-reach-nth-stair/

823
Chapter 108

Counting numbers of n digits


that are monotone

Counting numbers of n digits that are monotone - GeeksforGeeks


Call decimal number a monotone if:

.
Write a program which takes positive number n on input and returns number of decimal
numbers of length n that are monotone. Numbers can’t start with 0.

Examples :

Input : 1
Output : 9
Numbers are 1, 2, 3, ... 9

Input : 2
Output : 45
Numbers are 11, 12, 13, .... 22, 23
...29, 33, 34, ... 39.
Count is 9 + 8 + 7 ... + 1 = 45

Explanation: Let’s start by example of monotone numbers:

All those numbers are monotone as each digit on higher place is than the one before it.
What are the monotone numbers are of length 1 and digits 1 or 2? It is question to ask
yourself at the very beginning. We can see that possible numbers are:

824
Chapter 108. Counting numbers of n digits that are monotone

That was easy, now lets expand the question to digits 1, 2 and 3:

Now different question, what are the different monotone numbers consisting of only 1 and
length 3 are there?

Lets try now draw this very simple observation in 2 dimensional array for number of length
3, where first column is the length of string and first row is possible digits:

Let’s try to fill 3rd row 3rd column(number of monotone numbers consisting from numbers

1 or 2 with length 2). This should be:


If we will look closer we already have subsets of this set i.e:

– Monotone numbers that has length 2 and consist of 1 or 2

– Monotone numbers of length 2 and consisting of number 2


We just need to add previous values to get the longer one.
Final matrix should look like this:

825
Chapter 108. Counting numbers of n digits that are monotone

C++

// CPP program to count numbers of n digits


// that are  monotone.
#include <cstring>
#include <iostream>
  
// Considering all possible digits as
// {1, 2, 3, ..9}
int static const DP_s = 9;
  
int getNumMonotone(int len)
{
  
    // DP[i][j] is going to store monotone
    // numbers of length i+1 considering
    // j+1 digits.
    int DP[len][DP_s];
    memset(DP, 0, sizeof(DP));
  
    // Unit length numbers
    for (int i = 0; i < DP_s; ++i)
        DP[0][i] = i + 1;
  
    // Single digit numbers
    for (int i = 0; i < len; ++i)
        DP[i][0] = 1;
  
    // Filling rest of the entries in bottom
    // up manner.
    for (int i = 1; i < len; ++i)
        for (int j = 1; j < DP_s; ++j)
            DP[i][j] = DP[i - 1][j] + DP[i][j - 1];
  
    return DP[len - 1][DP_s - 1];
}
  
// Driver code.
int main()
{
    std::cout << getNumMonotone(10);
    return 0;
}

Java

// Java program to count numbers 

826
Chapter 108. Counting numbers of n digits that are monotone

// of n digits that are monotone.


  
class GFG 
{
    // Considering all possible 
    // digits as {1, 2, 3, ..9}
    static final int DP_s = 9;
      
    static int getNumMonotone(int len)
    {
      
        // DP[i][j] is going to store 
        // monotone numbers of length 
        // i+1 considering j+1 digits.
        int[][] DP = new int[len][DP_s];
      
        // Unit length numbers
        for (int i = 0; i < DP_s; ++i)
            DP[0][i] = i + 1;
      
        // Single digit numbers
        for (int i = 0; i < len; ++i)
            DP[i][0] = 1;
      
        // Filling rest of the entries 
        // in bottom up manner.
        for (int i = 1; i < len; ++i)
            for (int j = 1; j < DP_s; ++j)
                DP[i][j] = DP[i - 1][j] 
                           + DP[i][j - 1];
      
        return DP[len - 1][DP_s - 1];
    }
      
    // Driver code.
    public static void main (String[] args) 
    {
        System.out.println(getNumMonotone(10));
    }
}
  
// This code is contributed by Ansu Kumari.

Python3

# Python3 program to count numbers of n 


# digits that are monotone.
  

827
Chapter 108. Counting numbers of n digits that are monotone

# Considering all possible digits as


# {1, 2, 3, ..9}
DP_s = 9
  
def getNumMonotone(ln):
  
    # DP[i][j] is going to store monotone
    # numbers of length i+1 considering
    # j+1 digits.
    DP = [[0]*DP_s for i in range(ln)]
  
    # Unit lngth numbers
    for i in range(DP_s):
        DP[0][i] = i + 1
  
    # Single digit numbers
    for i in range(ln):
        DP[i][0] = 1
  
    # Filling rest of the entries  
    # in bottom up manner.
    for i in range(1, ln):
  
        for j in range(1, DP_s):
            DP[i][j] = DP[i - 1][j] + DP[i][j - 1]
  
    return DP[ln - 1][DP_s - 1]
  
  
# Driver code
print(getNumMonotone(10))
  
  
# This code is contributed by Ansu Kumari

C#

// C# program to count numbers 


// of n digits that are monotone.
using System;
  
class GFG 
{
    // Considering all possible 
    // digits as {1, 2, 3, ..9}
    static int DP_s = 9;
      
    static int getNumMonotone(int len)

828
Chapter 108. Counting numbers of n digits that are monotone

    {
      
        // DP[i][j] is going to store 
        // monotone numbers of length 
        // i+1 considering j+1 digits.
        int[,] DP = new int[len,DP_s];
      
        // Unit length numbers
        for (int i = 0; i < DP_s; ++i)
            DP[0,i] = i + 1;
      
        // Single digit numbers
        for (int i = 0; i < len; ++i)
            DP[i,0] = 1;
      
        // Filling rest of the entries 
        // in bottom up manner.
        for (int i = 1; i < len; ++i)
            for (int j = 1; j < DP_s; ++j)
                DP[i,j] = DP[i - 1,j] 
                        + DP[i,j - 1];
      
        return DP[len - 1,DP_s - 1];
    }
      
    // Driver code.
    public static void Main () 
    {
        Console.WriteLine(getNumMonotone(10));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to count numbers 
// of n digits that are monotone.
function getNumMonotone($len)
{
    // Considering all possible
    // digits as {1, 2, 3, ..9}
    $DP_s = 9;
  
  
    // DP[i][j] is going to store 
    // monotone numbers of length 

829
Chapter 108. Counting numbers of n digits that are monotone

    // i+1 considering j+1 digits.


    $DP = array(array_fill(0, $len, 0),
                array_fill(0, $len, 0));
  
    // Unit length numbers
    for ($i = 0; $i < $DP_s; ++$i)
        $DP[0][$i] = $i + 1;
  
    // Single digit numbers
    for ($i = 0; $i < $len; ++$i)
        $DP[$i][0] = 1;
  
    // Filling rest of the entries 
    // in bottom up manner.
    for ($i = 1; $i < $len; ++$i)
        for ($j = 1; $j < $DP_s; ++$j)
            $DP[$i][$j] = $DP[$i - 1][$j] + 
                          $DP[$i][$j - 1];
  
    return $DP[$len - 1][$DP_s - 1];
}
  
// Driver code
echo getNumMonotone(10);
  
// This code is contributed by mits
?>

Output :

43758

Improved By : Mithun Kumar

Source

https://www.geeksforgeeks.org/counting-numbers-n-digits-monotone/

830
Chapter 109

Counting pairs when a person


can form pair with at most one

Counting pairs when a person can form pair with at most one - GeeksforGeeks
Consider a coding competition on geeksforgeeks practice. Now their are n distinct partici-
pants taking part in the competition. A single participant can make pair with at most one
other participant. We need count the number of ways in which n participants participating
in the coding competition.
Examples :

Input : n = 2
Output : 2
2 shows that either both participant
can pair themselves in one way or both
of them can remain single.

Input : n = 3
Output : 4
One way : Three participants remain single
Three More Ways : [(1, 2)(3)], [(1), (2,3)]
and [(1,3)(2)]

1) Every participant can either pair with another participant or can remain single.
2) Let us consider X-th participant, he can either remain single or
he can pair up with someone from [1, x-1].
C++

// Number of ways in which participant can take part.


#include<iostream>

831
Chapter 109. Counting pairs when a person can form pair with at most one

using namespace std;


  
int numberOfWays(int x)
{
    // Base condition 
    if (x==0 || x==1)     
        return 1;
  
    // A participant can choose to consider
    // (1) Remains single. Number of people 
    //     reduce to (x-1)
    // (2) Pairs with one of the (x-1) others.
    //     For every pairing, number of people 
    //     reduce to (x-2). 
    else 
        return numberOfWays(x-1) + 
               (x-1)*numberOfWays(x-2);
}
  
// Driver code
int main()
{
    int x = 3;
    cout << numberOfWays(x) << endl;
    return 0;

Java

// Number of ways in which


// participant can take part.
import java.io.*;
  
class GFG {
  
static int numberOfWays(int x)
{
    // Base condition 
    if (x==0 || x==1)     
        return 1;
  
    // A participant can choose to consider
    // (1) Remains single. Number of people 
    //     reduce to (x-1)
    // (2) Pairs with one of the (x-1) others.
    //     For every pairing, number of people 
    //     reduce to (x-2). 
    else

832
Chapter 109. Counting pairs when a person can form pair with at most one

        return numberOfWays(x-1) + 
            (x-1)*numberOfWays(x-2);
}
  
// Driver code
public static void main (String[] args) {
int x = 3;
System.out.println( numberOfWays(x));
      
    }
}
  
// This code is contributed by vt_m.

Python3

# Python program to find Number of ways 


# in which participant can take part.
  
# Function to calculate number of ways.
def numberOfWays (x):
  
    # Base condition 
    if x == 0 or x == 1:
        return 1
          
    # A participant can choose to consider
    # (1) Remains single. Number of people
    # reduce to (x-1)
    # (2) Pairs with one of the (x-1) others.
    # For every pairing, number of people
    # reduce to (x-2).
    else:
        return (numberOfWays(x-1) +
              (x-1) * numberOfWays(x-2))
  
# Driver code
x = 3
print (numberOfWays(x))
  
# This code is contributed by "Sharad_Bhardwaj"

C#

// Number of ways in which


// participant can take part.
using System;

833
Chapter 109. Counting pairs when a person can form pair with at most one

  
class GFG {
  
    static int numberOfWays(int x)
    {
          
        // Base condition 
        if (x == 0 || x == 1) 
            return 1;
      
        // A participant can choose to
        // consider (1) Remains single.
        // Number of people reduce to
        // (x-1) (2) Pairs with one of
        // the (x-1) others. For every
        // pairing, number of people 
        // reduce to (x-2). 
        else
            return numberOfWays(x - 1) + 
            (x - 1) * numberOfWays(x - 2);
    }
      
    // Driver code
    public static void Main () 
    {
        int x = 3;
          
        Console.WriteLine(numberOfWays(x));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// Number of ways in which 
// participant can take part.
  
function numberOfWays($x)
{
    // Base condition 
    if ($x == 0 || $x == 1)     
        return 1;
  
    // A participant can choose 
    // to consider (1) Remains single. 
    // Number of people reduce to (x-1)

834
Chapter 109. Counting pairs when a person can form pair with at most one

    // (2) Pairs with one of the (x-1) 


    // others. For every pairing, number
    // of peopl reduce to (x-2). 
    else
        return numberOfWays($x - 1) + 
            ($x - 1) * numberOfWays($x - 2);
}
  
// Driver code
$x = 3;
echo numberOfWays($x);
  
// This code is contributed by Sam007
?>

Output :

Since there are overlapping subproblems, we can optimize it usingdynamic programming.

C++

// Number of ways in which participant can take part.


#include<iostream>
using namespace std;
  
int numberOfWays(int x)
{
    int dp[x+1];
    dp[0] = dp[1] = 1;
  
    for (int i=2; i<=x; i++)
       dp[i] = dp[i-1] + (i-1)*dp[i-2];
  
    return dp[x];
}
  
// Driver code
int main()
{
    int x = 3;
    cout << numberOfWays(x) << endl;
    return 0;

835
Chapter 109. Counting pairs when a person can form pair with at most one

Java

// Number of ways in which


// participant can take part.
import java.io.*;
class GFG {
  
static int numberOfWays(int x)
{
    int dp[] = new int[x+1];
    dp[0] = dp[1] = 1;
  
    for (int i=2; i<=x; i++)
    dp[i] = dp[i-1] + (i-1)*dp[i-2];
  
    return dp[x];
}
  
// Driver code
public static void main (String[] args) {
int x = 3;
System.out.println(numberOfWays(x));
      
    }
}
// This code is contributed by vt_m.

Python3

# Python program to find Number of ways 


# in which participant can take part.
  
# Function to calculate number of ways.
def numberOfWays (x):
  
    # Base condition 
    if x == 0 or x == 1:
        return 1
          
    # A participant can choose to consider
    # (1) Remains single. Number of people
    # reduce to (x-1)
    # (2) Pairs with one of the (x-1) others.
    # For every pairing, number of people
    # reduce to (x-2).
    else:
        return (numberOfWays(x-1) +

836
Chapter 109. Counting pairs when a person can form pair with at most one

              (x-1) * numberOfWays(x-2))
  
# Driver code
x = 3
print (numberOfWays(x))
  
# This code is contributed by "Sharad_Bhardwaj"

C#

// Number of ways in which


// participant can take part.
using System;
  
class GFG {
  
    static int numberOfWays(int x)
    {
        int []dp = new int[x+1];
        dp[0] = dp[1] = 1;
      
        for (int i = 2; i <= x; i++)
            dp[i] = dp[i - 1] +
                 (i - 1) * dp[i - 2];
      
        return dp[x];
    }
      
    // Driver code
    public static void Main ()
    {
        int x = 3;
          
        Console.WriteLine(numberOfWays(x));
    }
}
  
// This code is contributed by vt_m.  

PHP

<?php
// PHP program for Number of ways 
// in which participant can take part.
  
function numberOfWays($x)
{

837
Chapter 109. Counting pairs when a person can form pair with at most one

      
    $dp[0] = 1;
    $dp[1] = 1;
    for ($i = 2; $i <= $x; $i++)
    $dp[$i] = $dp[$i - 1] + ($i - 1) * 
                         $dp[$i - 2];
  
    return $dp[$x];
}
  
    // Driver code
    $x = 3;
    echo numberOfWays($x) ;
      
// This code is contributed by Sam007
?>

Output:

Improved By : vt_m, Sam007

Source

https://www.geeksforgeeks.org/counting-pairs-person-can-form-pair-one/

838
Chapter 110

Counts paths from a point to


reach Origin

Counts paths from a point to reach Origin - GeeksforGeeks


You are standing on a point (n, m) and you want to go to origin (0, 0) by taking steps
either left or down i.e. from each point you are allowed to move either in (n-1, m) or (n,
m-1). Find the number of paths from point to origin.
Examples:

Input : 3 6
Output : Number of Paths 84

Input : 3 0
Output : Number of Paths 1

839
Chapter 110. Counts paths from a point to reach Origin

As we are restricted to move down and left only we would run a recursive loop for each of
the combinations of the
steps that can be taken.

// Recursive function to count number of paths


countPaths(n, m)
{
// If we reach bottom or top left, we are
// have only one way to reach (0, 0)
if (n==0 || m==0)
return 1;

840
Chapter 110. Counts paths from a point to reach Origin

// Else count sum of both ways


return (countPaths(n-1, m) + countPaths(n, m-1));
}

Below is C++ implementation of above steps.

C++

// CPP program to count total number of


// paths from a point to origin
#include<bits/stdc++.h>
using namespace std;
  
// Recursive function to count number of paths
int countPaths(int n, int m)
{
    // If we reach bottom or top left, we are
    // have only one way to reach (0, 0)
    if (n==0 || m==0)
        return 1;
  
    // Else count sum of both ways
    return (countPaths(n-1, m) + countPaths(n, m-1));
}
  
// Driver Code
int main()
{
    int n = 3, m = 2;
    cout << " Number of Paths " << countPaths(n, m);
    return 0;
}

Java

// Java program to count total number of


// paths from a point to origin
import java.io.*;
  
class GFG {
      
    // Recursive function to count number of paths
    static int countPaths(int n, int m)
    {
        // If we reach bottom or top left, we are
        // have only one way to reach (0, 0)
        if (n == 0 || m == 0)

841
Chapter 110. Counts paths from a point to reach Origin

            return 1;
      
        // Else count sum of both ways
        return (countPaths(n - 1, m) + countPaths(n, m - 1));
    }
      
    // Driver Code
    public static void main (String[] args)
    {
        int n = 3, m = 2;
        System.out.println (" Number of Paths "
                            + countPaths(n, m));
          
    }
}
  
// This code is contributed by vt_m

Python3

# Python program to count


# total number of
# paths from a point to origin
# Recursive function to 
# count number of paths
def countPaths(n,m):
  
    # If we reach bottom
    # or top left, we are
    # have only one way to reach (0, 0)
    if (n==0 or m==0):
        return 1
   
    # Else count sum of both ways
    return (countPaths(n-1, m) + countPaths(n, m-1))
  
# Driver Code
n = 3
m = 2
print(" Number of Paths ", countPaths(n, m))
  
# This code is contributed
# by Azkia Anam.

C#

// C# program to count total number of

842
Chapter 110. Counts paths from a point to reach Origin

// paths from a point to origin


using System;
          
public class GFG {
      
    // Recursive function to count number
    // of paths
    static int countPaths(int n, int m)
    {
          
        // If we reach bottom or top left,
        // we are have only one way to
        // reach (0, 0)
        if (n == 0 || m == 0)
            return 1;
      
        // Else count sum of both ways
        return (countPaths(n - 1, m) 
                 + countPaths(n, m - 1));
    }
      
    // Driver Code
    public static void Main ()
    {
        int n = 3, m = 2;
          
        Console.WriteLine (" Number of"
         + " Paths " + countPaths(n, m));
          
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP program to count total number
// of paths from a point to origin
  
// Recursive function to 
// count number of paths
function countPaths($n, $m)
{
      
    // If we reach bottom or 
    // top left, we are
    // have only one way to

843
Chapter 110. Counts paths from a point to reach Origin

    // reach (0, 0)


    if ($n == 0 || $m == 0)
        return 1;
  
    // Else count sum of both ways
    return (countPaths($n - 1, $m) + 
            countPaths($n, $m - 1));
}
  
    // Driver Code
    $n = 3; 
    $m = 2;
    echo " Number of Paths " 
      , countPaths($n, $m);
  
// This code is contributed by aj_36
?>

Output:

Number of Paths 10

We can use Dynamic Programming as there are overlapping subproblems. We can draw
recursion tree to see overlapping problems. For example, in case of countPaths(4, 4), we
compute countPaths(3, 3) multiple times.
C++

// CPP program to count total number of


// paths from a point to origin
#include<bits/stdc++.h>
using namespace std;
  
// DP based function to count number of paths
int countPaths(int n, int m)
{
    int dp[n+1][m+1];
  
    // Fill entries in bottommost row and leftmost
    // columns
    for (int i=0; i<=n; i++)
      dp[i][0] = 1;
    for (int i=0; i<=m; i++)
      dp[0][i] = 1;
  
    // Fill DP in bottom up manner
    for (int i=1; i<=n; i++)

844
Chapter 110. Counts paths from a point to reach Origin

       for (int j=1; j<=m; j++)


          dp[i][j] = dp[i-1][j] + dp[i][j-1];
  
    return dp[n][m];
}
  
// Driver Code
int main()
{
    int n = 3, m = 2;
    cout << " Number of Paths " << countPaths(n, m);
    return 0;
}

Java

// Java program to count total number of


// paths from a point to origin
import java.io.*;
  
class GFG {
      
    // DP based function to count number of paths
    static int countPaths(int n, int m)
    {
        int dp[][] = new int[n + 1][m + 1];
      
        // Fill entries in bottommost row and leftmost
        // columns
        for (int i = 0; i <= n; i++)
            dp[i][0] = 1;
        for (int i = 0; i <= m; i++)
            dp[0][i] = 1;
      
        // Fill DP in bottom up manner
        for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
      
        return dp[n][m];
    }
      
    // Driver Code
    public static void main (String[] args) {
        int n = 3, m = 2;
        System.out.println(" Number of Paths "
                           + countPaths(n, m));
          

845
Chapter 110. Counts paths from a point to reach Origin

    }
}
  
// This code is contributed by vt_m

C#

// C# program to count total number of


// paths from a point to origin
using System;
          
public class GFG {
      
    // DP based function to count number
    // of paths
    static int countPaths(int n, int m)
    {
        int [,]dp = new int[n + 1,m + 1];
      
        // Fill entries in bottommost row
        // and leftmost columns
        for (int i = 0; i <= n; i++)
            dp[i,0] = 1;
        for (int i = 0; i <= m; i++)
            dp[0,i] = 1;
      
        // Fill DP in bottom up manner
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                dp[i,j] = dp[i - 1,j]
                         + dp[i,j - 1];
          
        return dp[n,m];
    }
      
    // Driver Code
    public static void Main ()
    {
        int n = 3, m = 2;
          
        Console.WriteLine(" Number of"
        + " Paths " + countPaths(n, m));
          
    }
}
  
// This code is contributed by Sam007.

846
Chapter 110. Counts paths from a point to reach Origin

PHP

<?php
// PHP program to count total number of
// paths from a point to origin
  
// DP based function to 
// count number of paths
function countPaths($n, $m)
{
      
    //$dp[$n+1][$m+1];
    // Fill entries in bottommost
    // row and leftmost columns
    for ($i = 0; $i <= $n; $i++)
        $dp[$i][0] = 1;
          
    for ($i = 0; $i <= $m; $i++)
        $dp[0][$i] = 1;
  
    // Fill DP in bottom up manner
    for ($i = 1; $i <= $n; $i++)
    for ($j = 1; $j <= $m; $j++)
        $dp[$i][$j] = $dp[$i - 1][$j] + 
                      $dp[$i][$j - 1];
  
    return $dp[$n][$m];
}
  
    // Driver Code
    $n = 3;
    $m = 2;
    echo " Number of Paths " , countPaths($n, $m);
  
// This code is contributed by m_kit
?>

Output:

Number of Paths 10

Improved By : Sam007, jit_t

Source

https://www.geeksforgeeks.org/counts-paths-point-reach-origin/

847
Chapter 111

Delannoy Number

Delannoy Number - GeeksforGeeks


In mathematics, a Delannoy number D describes the number of paths from the southwest
corner (0, 0) of a rectangular grid to the northeast corner (m, n), using only single steps
north, northeast, or east.
For Example, D(3, 3) equals 63.
Delannoy Number can be calculated by:

Delannoy number can be used to find:

• Counts the number of global alignments of two sequences of lengths m and n.


• Number of points in an m-dimensional integer lattice that are at most n steps from
the origin.
• In cellular automata, the number of cells in an m-dimensional von Neumann neigh-
borhood of radius n.
• Number of cells on a surface of an m-dimensional von Neumann neighborhood of radius
n.

Examples :

Input : n = 3, m = 3
Output : 63

848
Chapter 111. Delannoy Number

Input : n = 4, m = 5
Output : 681

Below is the implementation of finding Delannoy Number:

C++

// CPP Program of finding nth Delannoy Number.


#include <bits/stdc++.h>
using namespace std;
  
// Return the nth Delannoy Number.
int dealnnoy(int n, int m)
{
    // Base case
    if (m == 0 || n == 0)
        return 1;
  
    // Recursive step.
    return dealnnoy(m - 1, n) + 
           dealnnoy(m - 1, n - 1) +
           dealnnoy(m, n - 1);
}
  
// Driven Program
int main()
{
    int n = 3, m = 4;
    cout << dealnnoy(n, m) << endl;
    return 0;
}

Java

// Java Program for finding nth Delannoy Number.


import java.util.*;
import java.lang.*;
  
public class GfG{
      
    // Return the nth Delannoy Number.
    public static int dealnnoy(int n, int m)
    {
        // Base case
        if (m == 0 || n == 0)
            return 1;

849
Chapter 111. Delannoy Number

  
        // Recursive step.
        return dealnnoy(m - 1, n) + 
            dealnnoy(m - 1, n - 1) +
            dealnnoy(m, n - 1);
    }
      
    // driver function
    public static void main(String args[]){
        int n = 3, m = 4;
        System.out.println(dealnnoy(n, m));
    }
}
  
/* This code is contributed by Sagar Shukla. */

Python3

# Python3 Program for finding 


# nth Delannoy Number.
  
# Return the nth Delannoy Number.
def dealnnoy(n, m):
      
    # Base case
    if (m == 0 or n == 0) :
        return 1
  
    # Recursive step.
    return dealnnoy(m - 1, n) + dealnnoy(m - 1, n - 1) + dealnnoy(m, n - 1)
  
# Driven code
n = 3
m = 4;
print( dealnnoy(n, m) )
  
# This code is contributed by "rishabh_jain".

C#

// C# Program for finding nth Delannoy Number.


using System;
  
public class GfG {
  
    // Return the nth Delannoy Number.
    public static int dealnnoy(int n, int m)

850
Chapter 111. Delannoy Number

    {
  
        // Base case
        if (m == 0 || n == 0)
            return 1;
  
        // Recursive step.
        return dealnnoy(m - 1, n) + 
               dealnnoy(m - 1, n - 1) + 
                     dealnnoy(m, n - 1);
    }
  
    // driver function
    public static void Main()
    {
        int n = 3, m = 4;
        Console.WriteLine(dealnnoy(n, m));
    }
}
  
/* This code is contributed by vt_m. */

PHP

<?php
// PHP Program of finding nth
// Delannoy Number.
  
// Return the nth Delannoy Number.
function dealnnoy( $n, $m)
{
      
    // Base case
    if ($m == 0 or $n == 0)
        return 1;
  
    // Recursive step.
    return dealnnoy($m - 1, $n) + 
           dealnnoy($m - 1, $n - 1) +
           dealnnoy($m, $n - 1);
}
  
    // Driver Code
    $n = 3; 
    $m = 4;
    echo dealnnoy($n, $m);
  
// This code is contributed by anuj_67.

851
Chapter 111. Delannoy Number

?>

Output:

129

Below is the Dynamic Programming program to find nth Delannoy Number:

C++

// CPP Program of finding nth Delannoy Number.


#include <bits/stdc++.h>
using namespace std;
  
// Return the nth Delannoy Number.
int dealnnoy(int n, int m)
{
    int dp[m + 1][n + 1];
  
    // Base cases
    for (int i = 0; i <= m; i++) 
        dp[i][0] = 1;
    for (int i = 0; i <= m; i++) 
        dp[0][i] = 1;    
  
    for (int i = 1; i <= m; i++) 
        for (int j = 1; j <= n; j++) 
            dp[i][j] = dp[i - 1][j] +
                       dp[i - 1][j - 1] + 
                       dp[i][j - 1];
  
    return dp[m][n];
}
  
// Driven Program
int main()
{
    int n = 3, m = 4;
    cout << dealnnoy(n, m) << endl;
    return 0;
}

Java

// Java Program of finding nth Delannoy Number.

852
Chapter 111. Delannoy Number

  
import java.io.*;
  
class GFG {
      
    // Return the nth Delannoy Number.
    static int dealnnoy(int n, int m)
    {
        int dp[][]=new int[m + 1][n + 1];
       
        // Base cases
        for (int i = 0; i <= m; i++) 
            dp[i][0] = 1;
        for (int i = 0; i < m; i++) 
            dp[0][i] = 1;    
       
        for (int i = 1; i <= m; i++) 
            for (int j = 1; j <= n; j++) 
                dp[i][j] = dp[i - 1][j] +
                           dp[i - 1][j - 1] + 
                           dp[i][j - 1];
       
        return dp[m][n];
    }
       
    // Driven Program
    public static void main(String args[])
    {
        int n = 3, m = 4;
        System.out.println(dealnnoy(n, m));
          
    }
}
  
// This code is contributed by Nikita Tiwari.

Python3

# Python3 Program for finding nth


# Delannoy Number.
  
# Return the nth Delannoy Number.
def dealnnoy (n, m):
    dp = [[0 for x in range(n+1)] for x in range(m+1)]
  
    # Base cases
    for i in range(m):
        dp[0][i] = 1

853
Chapter 111. Delannoy Number

      
    for i in range(1, m + 1):
        dp[i][0] = 1
  
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            dp[i][j] = dp[i - 1][j] + dp[i - 1][j - 1] + dp[i][j - 1];
  
    return dp[m][n]
  
# Driven code
n = 3
m = 4
print(dealnnoy(n, m))
  
# This code is contributed by "rishabh_jain".

C#

// C# Program of finding nth Delannoy Number.


using System;
  
class GFG {
  
    // Return the nth Delannoy Number.
    static int dealnnoy(int n, int m)
    {
          
        int[, ] dp = new int[m + 1, n + 1];
  
        // Base cases
        for (int i = 0; i <= m; i++)
            dp[i, 0] = 1;
        for (int i = 0; i < m; i++)
            dp[0, i] = 1;
  
        for (int i = 1; i <= m; i++)
            for (int j = 1; j <= n; j++)
                dp[i, j] = dp[i - 1, j]
                     + dp[i - 1, j - 1]
                         + dp[i, j - 1];
  
        return dp[m, n];
    }
  
    // Driven Program
    public static void Main()
    {

854
Chapter 111. Delannoy Number

        int n = 3, m = 4;
          
        Console.WriteLine(dealnnoy(n, m));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program of finding
// nth Delannoy Number.
  
// Return the nth Delannoy Number.
function dealnnoy($n, $m)
{
    $dp[$m + 1][$n + 1] = 0;
  
    // Base cases
    for ($i = 0; $i <= $m; $i++) 
        $dp[$i][0] = 1;
    for ( $i = 0; $i <= $m; $i++) 
        $dp[0][$i] = 1; 
  
    for ($i = 1; $i <= $m; $i++) 
        for ($j = 1; $j <= $n; $j++) 
            $dp[$i][$j] = $dp[$i - 1][$j] +
                      $dp[$i - 1][$j - 1] + 
                           $dp[$i][$j - 1];
  
    return $dp[$m][$n];
}
  
// Driven Code
$n = 3; $m = 4;
echo dealnnoy($n, $m) ;
  
// This code is contributed by SanjuTomar 
?>

Output :

129

Improved By : SanjuTomar, vt_m

855
Chapter 111. Delannoy Number

Source

https://www.geeksforgeeks.org/delannoy-number/

856
Chapter 112

Different ways to sum n using


numbers greater than or equal
to m

Different ways to sum n using numbers greater than or equal to m - GeeksforGeeks


Given two natural number n and m. The task is to find the number of ways in which the
numbers that are greater than or equal to m can be added to get the sum n.
Examples:

Input : n = 3, m = 1
Output : 3
Following are three different ways
to get sum n such that each term is
greater than or equal to m
1 + 1 + 1, 1 + 2, 3

Input : n = 2, m = 1
Output : 2
Two ways are 1 + 1 and 2

The idea is to use Dynamic Programming by define 2D matrix, say dp[][]. dp[i][j] define
the number of ways to get sum i using the numbers greater than or equal to j. So dp[i][j]
can be defined as:

If i < j, dp[i][j] = 0, because we cannot achieve smaller sum of i using numbers


greater than or equal to j.
If i = j, dp[i][j] = 1, because there is only one way to show sum i using number
i which is equal to j.

857
Chapter 112. Different ways to sum n using numbers greater than or equal to m

Else dp[i][j] = dp[i][j+1] + dp[i-j][j], because obtaining a sum i using num-


bers greater than or equal to j is equal to the sum of obtaining a sum of i using
numbers greater than or equal to j+1 and obtaining the sum of i-j using numbers
greater than or equal to j.

Below is the implementation of this approach:

CPP

// CPP Program to find number of ways to


// which numbers that are greater than
// given number can be added to get sum.
#include <bits/stdc++.h>
#define MAX 100
using namespace std;
  
// Return number of ways to which numbers
// that are greater than given number can
// be added to get sum.
int numberofways(int n, int m)
{
    int dp[n+2][n+2];
    memset(dp, 0, sizeof(dp));
  
    dp[0][n + 1] = 1;
  
    // Filling the table. k is for numbers
    // greater than or equal that are allowed.
    for (int k = n; k >= m; k--) {
  
        // i is for sum
        for (int i = 0; i <= n; i++) {
  
            // initializing dp[i][k] to number
            // ways to get sum using numbers
            // greater than or equal k+1
            dp[i][k] = dp[i][k + 1];
  
            // if i > k
            if (i - k >= 0)
                dp[i][k] = (dp[i][k] + dp[i - k][k]);
        }
    }
  
    return dp[n][m];
}
  

858
Chapter 112. Different ways to sum n using numbers greater than or equal to m

// Driver Program
int main()
{
    int n = 3, m = 1;
    cout << numberofways(n, m) << endl;
    return 0;
}

Java

// Java Program to find number of ways to


// which numbers that are greater than
// given number can be added to get sum.
import java.io.*;
  
class GFG {
      
    // Return number of ways to which numbers
    // that are greater than given number can
    // be added to get sum.
    static int numberofways(int n, int m)
    {
        int dp[][]=new int[n+2][n+2];
          
        dp[0][n + 1] = 1;
       
        // Filling the table. k is for numbers
        // greater than or equal that are allowed.
        for (int k = n; k >= m; k--) {
       
            // i is for sum
            for (int i = 0; i <= n; i++) {
       
                // initializing dp[i][k] to number
                // ways to get sum using numbers
                // greater than or equal k+1
                dp[i][k] = dp[i][k + 1];
       
                // if i > k
                if (i - k >= 0)
                    dp[i][k] = (dp[i][k] + dp[i - k][k]);
            }
        }
       
        return dp[n][m];
    }
       
    // Driver Program

859
Chapter 112. Different ways to sum n using numbers greater than or equal to m

    public static void main(String args[])


    {
        int n = 3, m = 1;
        System.out.println(numberofways(n, m));
    }
}
  
/*This code is contributed by Nikita tiwari.*/

C#

// C# program to find number of ways to


// which numbers that are greater than
// given number can be added to get sum.
using System;
  
class GFG {
  
    // Return number of ways to which numbers
    // that are greater than given number can
    // be added to get sum.
    static int numberofways(int n, int m)
    {
        int[, ] dp = new int[n + 2, n + 2];
  
        dp[0, n + 1] = 1;
  
        // Filling the table. k is for numbers
        // greater than or equal that are allowed.
        for (int k = n; k >= m; k--) {
  
            // i is for sum
            for (int i = 0; i <= n; i++) {
  
                // initializing dp[i][k] to number
                // ways to get sum using numbers
                // greater than or equal k+1
                dp[i, k] = dp[i, k + 1];
  
                // if i > k
                if (i - k >= 0)
                    dp[i, k] = (dp[i, k] + dp[i - k, k]);
            }
        }
  
        return dp[n, m];
    }
  

860
Chapter 112. Different ways to sum n using numbers greater than or equal to m

    // Driver Program


    public static void Main()
    {
        int n = 3, m = 1;
        Console.WriteLine(numberofways(n, m));
    }
}
  
/*This code is contributed by vt_m.*/

Output:

Source

https://www.geeksforgeeks.org/different-ways-sum-n-using-numbers-greater-equal-m/

861
Chapter 113

Digit DP | Introduction

Digit DP | Introduction - GeeksforGeeks


Prerequisite : How to solve a Dynamic Programming Problem ?
There are many types of problems that ask to count the number of integers ‘x‘ between two
integers say ‘a‘ and ‘b‘ such that x satisfies a specific property that can be related to its
digits.
So, if we say G(x) tells the number of such integers between 1 to x (inclusively), then the
number of such integers between a and b can be given by G(b) – G(a-1). This is when
Digit DP (Dynamic Programming) comes into action. All such integer counting problems
that satisfy the above property can be solved by digit DP approach.
Key Concept

• Let given number x has n digits. The main idea of digit DP is to first represent the
digits as an array of digits t[]. Let’s say a we have tn tn-1 tn-2 … t2 t1 as the decimal
representation where ti (0 < i <= n) tells the i-th digit from the right. The leftmost
digit tn is the most significant digit.
• Now, after representing the given number this way we generate the numbers less than
the given number and simultaneously calculate using DP, if the number satisfy the
given property. We start generating integers having number of digits = 1 and
then till number of digits = n. Integers having less number of digits than
n can be analyzed by setting the leftmost digits to be zero.

Example Problem :
Given to integers a and b. Your task is to print the sum of
all the digits appearing in the integers between a and b.
For example if a = 5 and b = 11, then answer is 38 (5 + 6 + 7 + 8 + 9 + 1 + 0 + 1 + 1)
Constraints : 1 <= a < b <= 10^18
Now we see that if we have calculated the answer for state having n-1 digits, i.e., tn-1 tn-2
… t2 t1 and we need to calculate answer for state having n digitdtn tn-1 tn-2 … t2 t1 . So,

862
Chapter 113. Digit DP | Introduction

clearly, we can use the result of the previous state instead of re-calculating it. Hence, it
follows the overlapping property.
Let’s think for a state for this DP
Our DP state will be dp(idx, tight, sum)
1) idx

• It tells about the index value from right in the given integer

2) tight

• This will tell if the current digits range is restricted or not. If the current digit’s
range is not restricted then it will span from 0 to 9 (inclusively) else it will span
from 0 to digit[idx] (inclusively).
Example: consider our limiting integer to be 3245 and we need to calculate G(3245)
index : 4 3 2 1
digits : 3 2 4 5

Unrestricted range:
Now suppose the integer generated till now is : 3 1 * * ( * is empty place, where digits are
to be inserted to form the integer).

index : 4 3 2 1
digits : 3 2 4 5
generated integer: 3 1 _ _

here, we see that index 2 has unrestricted range. Now index 2 can have digits from range 0
to 9(inclusively).
For unrestricted range tight = 0
Restricted range:
Now suppose the integer generated till now is : 3 2 * * ( ‘*’ is an empty place, where digits
are to be inserted to form the integer).

index : 4 3 2 1
digits : 3 2 4 5
generated integer: 3 2 _ _

here, we see that index 2 has a restricted range. Now index 2 can only have digits from
range 0 to 4 (inclusively)
For unrestricted range tight = 1
3) sum

863
Chapter 113. Digit DP | Introduction

• This parameter will store the sum of digits in the generated integer from msd to idx.
• Max value for this parameter sum can be 9*18 = 162, considering 18 digits in the
integer

State Relation
The basic idea for state relation is very simple. We formulate the dp in top-down fashion.
Let’s say we are at the msd having index idx. So initially sum will be 0.
Therefore, we will fill the digit at index by the digits in its range. Let’s say its range is
from 0 to k (k<=9, depending on the tight value) and fetch the answer from the next state
having index = idx-1 and sum = previous sum + digit chosen.

int ans = 0;
for (int i=0; i<=k; i++) {
ans += state(idx-1, newTight, sum+i)
}

state(idx,tight,sum) = ans;

How to calculate the newTight value?


The new tight value from a state depends on its previous state. If tight value form the
previous state is 1 and the digit at idx chosen is digit[idx](i.e the digit at idx in limiting
integer) , then only our new tight will be 1 as it only then tells that the number formed till
now is prefix of the limiting integer.

// digitTaken is the digit chosen


// digit[idx] is the digit in the limiting
// integer at index idx from right
// previouTight is the tight value form previous
// state

newTight = previousTight & (digitTake == digit[idx])

C++ code for the above implementation:

// Given two integers a and b. The task is to print


// sum of all the digits appearing in the
// integers between a and b
#include "bits/stdc++.h"
using namespace std;
  
// Memoization for the state results
long long dp[20][180][2];

864
Chapter 113. Digit DP | Introduction

  
// Stores the digits in x in a vector digit
long long getDigits(long long x, vector <int> &digit)
{
    while (x)
    {
        digit.push_back(x%10);
        x /= 10;
    }
}
  
// Return sum of digits from 1 to integer in
// digit vector
long long digitSum(int idx, int sum, int tight,
                          vector <int> &digit)
{
    // base case
    if (idx == -1)
       return sum;
  
    // checking if already calculated this state
    if (dp[idx][sum][tight] != -1 and tight != 1)
        return dp[idx][sum][tight];
  
    long long ret = 0;
  
    // calculating range value
    int k = (tight)? digit[idx] : 9;
  
    for (int i = 0; i <= k ; i++)
    {
        // caclulating newTight value for next state
        int newTight = (digit[idx] == i)? tight : 0;
  
        // fetching answer from next state
        ret += digitSum(idx-1, sum+i, newTight, digit);
    }
  
    if (!tight)
      dp[idx][sum][tight] = ret;
  
    return ret;
}
  
// Returns sum of digits in numbers from a to b.
int rangeDigitSum(int a, int b)
{
    // initializing dp with -1

865
Chapter 113. Digit DP | Introduction

    memset(dp, -1, sizeof(dp));


  
    // storing digits of a-1 in digit vector
    vector<int> digitA;
    getDigits(a-1, digitA);
  
    // Finding sum of digits from 1 to "a-1" which is passed
    // as digitA.
    long long ans1 = digitSum(digitA.size()-1, 0, 1, digitA);
  
    // Storing digits of b in digit vector
    vector<int> digitB;
    getDigits(b, digitB);
  
    // Finding sum of digits from 1 to "b" which is passed
    // as digitB.
    long long ans2 = digitSum(digitB.size()-1, 0, 1, digitB);
  
    return (ans2 - ans1);
}
  
// driver function to call above function
int main()
{
    long long a = 123, b = 1024;
    cout << "digit sum for given range : "
         << rangeDigitSum(a, b) << endl;
    return 0;
}

Output:

digit sum for given range : 12613

Time Complexity:
There are total idx*sum*tight states and we are performing 0 to 9 iterations to visit every
state. Therefore, The Time Complexity will be O(10*idx*sum*tight). Here, we observe
that tight = 2 and idx can be max 18 for 64 bit unsigned integer and moreover, the sum
will be max 9*18 ~ 200. So, overall we have 10*18*200*2 ~ 10^5 iterations which can be
easily executed in 0.01 seconds.
The above problem can also be solved using simple recursion without any memoization. The
recursive solution for the above problem can be found here. We will be soon adding more
problems on digit dp in our future posts.
Improved By : sauravtygg

866
Chapter 113. Digit DP | Introduction

Source

https://www.geeksforgeeks.org/digit-dp-introduction/

867
Chapter 114

Dynamic Programming on
Trees | Set 2

Dynamic Programming on Trees | Set 2 - GeeksforGeeks


Given a tree with N nodes and N-1 edges, find out the maximum height of tree when
any node in the tree is considered as the root of the tree.

The above diagram represents a tree with 11 nodes and 10 edges, and the path which
gives us the maximum height when node 1 is considered as root. The maximum height is 3.

868
Chapter 114. Dynamic Programming on Trees | Set 2

In the above diagram, when 2 is considered as root, then the longest path found is in RED
color. A naive approach will be to traverse the tree using DFS traversal for every node
and calculate the maximum height when the node is treated as the root of the tree. The
time complexity for DFS traversal of a tree is O(N). The overall time complexity of
DFS for all N nodes will be O(N)*N i.e., O(N2 ).
The above problem can be solved by using Dynamic Programming on Trees. To solve
this problem, pre-calculate two things for every node. One will be the maximum height while
traveling downwards via its branches to the leaves. While the other will be the maximum
height when traveling upwards via its parent to any of the leaves.
Optimal Substructure :
When node i is considered as root,
in[i] be the maximum height of tree when we travel downwards via its sub-trees and leaves.
Also, out[i] be the maximum height of the tree while traveling upwards via its parent.

The maximum height of tree when node i is


considered as root will be max(in[i], out[i]).

Calculation of in[i] :

869
Chapter 114. Dynamic Programming on Trees | Set 2

In the image above, values of in[i] have been calculated for every node i. The maximum of
every subtree is taken and added with 1 to the parent of that subtree. Add 1 for the edge
between parent and subtree. Traverse the tree using DFS and calculate in[i] as max(in[i],
1+in[child]) for every node.
Calculation of out[i] :

The above diagram shows all the out[i] values and the path. For calculation of out[i], move
upwards to the parent of node i. From the parent of node i, there are two ways to move in,
one will be in all the branches of the parent. The other direction is to move to the parent(call
it parent2 to avoid confusion) of the parent(call it parent1) of node i. The maximum height
upwards via parent2 is out[parent1] itself. Generally, out[node i] as 1+max(out[i], 1+max

870
Chapter 114. Dynamic Programming on Trees | Set 2

of all branches). Add 1 for the edges between node and parent.

The above diagram explains the calculation of out[i] when 2 is considered as the root of the
tree. The branches of node 2 is not taken into count since the maximum height via that
path has already been calculated and stored in i[2]. Moving up, in this case, the parent of 2
i.e., 1 has no parent. So, the branches except for the one which has the node are considered
while calculating the maximum.

The above diagram explains the calculation of out[10]. The parent of node 10, i.e., 7 has
a parent and a branch(precisely a child in this case). So the maximum height of both has
been taken to count in such cases when parent and branches exist.

871
Chapter 114. Dynamic Programming on Trees | Set 2

In case of multiple branches of a parent, take the longest of them to


count(excluding the branch in which the node lies)
Calculating the maximum height of all the branches connected to parent :
in[i] stores the maximum height while moving downwards. No need to store all the lengths
of branches. Only the first and second maximum length among all the branches will give
answer. Since, algorithm used is based on DFS, all the branches connected to parent will
be considered, including the branch which has the node. If the first maximum path thus
obtained is same as in[i], then maximum1 is the length of the branch in which node i lies.
In this case, our longest path will be maximum2.
Recurrence relation of in[i] and out[i] :

in[i] = max(in[i], 1 + in[child])


out[i] = 1 + max(out[parent of i], 1 + longest path of all branches of parent of
i)

Below is the implementation of the above idea :

C++

// CPP code to find the maximum path length


// considering any node as root
#include <bits/stdc++.h>
using namespace std;
const int MAX_NODES = 100;
  
int in[MAX_NODES];
int out[MAX_NODES];
  
// function to pre-calculate the array in[]
// which stores the maximum height when travelled
// via branches
void dfs1(vector<int> v[], int u, int parent)
{
    // initially every node has 0 height
    in[u] = 0;
  
    // traverse in the subtree of u
    for (int child : v[u]) {
  
        // if child is same as parent
        if (child == parent)
            continue;
  
        // dfs called
        dfs1(v, child, u);
  

872
Chapter 114. Dynamic Programming on Trees | Set 2

        // recursively calculate the max height


        in[u] = max(in[u], 1 + in[child]);
    }
}
  
// function to pre-calculate the array ouut[]
// which stores the maximum height when traveled
// via parent
void dfs2(vector<int> v[], int u, int parent)
{
    // stores the longest and second 
    // longest branches
    int mx1 = -1, mx2 = -1;
  
    // traverse in the subtress of u
    for (int child : v[u]) {
        if (child == parent)
            continue;
  
        // compare and store the longest
        // and second longest
        if (in[child] >= mx1) {
            mx2 = mx1;
            mx1 = in[child];
        }
  
        else if (in[child] > mx2)
            mx2 = in[child];
    }
  
    // traverse in the subtree of u
    for (int child : v[u]) {
        if (child == parent)
            continue;
  
        int longest = mx1;
  
        // if longest branch has the node, then
        // consider the second longest branch
        if (mx1 == in[child])
            longest = mx2;
  
        // recursively calculate out[i]
        out[child] = 1 + max(out[u], 1 + longest);
  
        // dfs fucntion call
        dfs2(v, child, u);
    }

873
Chapter 114. Dynamic Programming on Trees | Set 2

}
  
// fucntion to print all the maximum heights
// from every node
void printHeights(vector<int> v[], int n)
{
    // traversal to calculate in[] array
    dfs1(v, 1, 0);
  
    // traversal to calculate out[] array
    dfs2(v, 1, 0);
  
    // print all maximum heights
    for (int i = 1; i <= n; i++)
        cout << "The maximum height when node " 
             << i << " is considered as root"
             << " is " << max(in[i], out[i]) 
             << "\n";
}
  
// Driver Code
int main()
{
    int n = 11;
    vector<int> v[n + 1];
  
    // initialize the tree given in the diagram
    v[1].push_back(2), v[2].push_back(1);
    v[1].push_back(3), v[3].push_back(1);
    v[1].push_back(4), v[4].push_back(1);
    v[2].push_back(5), v[5].push_back(2);
    v[2].push_back(6), v[6].push_back(2);
    v[3].push_back(7), v[7].push_back(3);
    v[7].push_back(10), v[10].push_back(7);
    v[7].push_back(11), v[11].push_back(7);
    v[4].push_back(8), v[8].push_back(4);
    v[4].push_back(9), v[9].push_back(4);
  
    // function to print the maximum height from every node
    printHeights(v, n);
  
    return 0;
}

Output :

The maximum height when node 1 is considered as root is 3

874
Chapter 114. Dynamic Programming on Trees | Set 2

The maximum height when node 2 is considered as root is 4


The maximum height when node 3 is considered as root is 3
The maximum height when node 4 is considered as root is 4
The maximum height when node 5 is considered as root is 5
The maximum height when node 6 is considered as root is 5
The maximum height when node 7 is considered as root is 4
The maximum height when node 8 is considered as root is 5
The maximum height when node 9 is considered as root is 5
The maximum height when node 10 is considered as root is 5
The maximum height when node 11 is considered as root is 5

Time Complexity : O(N)


Auxiliary Space : O(N)

Source

https://www.geeksforgeeks.org/dynamic-programming-trees-set-2/

875
Chapter 115

Dynamic Programming on
Trees | Set-1

Dynamic Programming on Trees | Set-1 - GeeksforGeeks


Dynamic Programming(DP) is a technique to solve problems by breaking them down into
overlapping sub-problems which follows the optimal substructure. There are various prob-
lems using DP like subset sum, knapsack, coin change etc. DP can also be applied on trees
to solve some specific problems.
Pre-requisite: DFS
Given a tree with N nodes and N-1 edges, calculate the maximum sum of the node values
from root to any of the leaves without re-visiting any node.

876
Chapter 115. Dynamic Programming on Trees | Set-1

Given above is a diagram of a tree with N=14 nodes and N-1=13 edges. The values at
node being 3, 2, 1, 10, 1, 3, 9, 1, 5, 3, 4, 5, 9 and 8 respectively for nodes 1, 2, 3,
4….14.
The diagram below shows all the paths from root to leaves :

All the paths are marked by different colors :


Path 1(red, 3-2-1-4) : sum of all node values = 10
Path 2(orange, 3-2-1-5) : sum of all node values = 11
Path 3(yellow, 3-2-3) : sum of all node values = 8
Path 4(green, 3-1-9-9) : sum of all node values = 22
Path 5(violet, 3-1-9-8) : sum of all node values = 21
Path 6(pink, 3-10-1) : sum of all node values = 14
Path 7(blue, 3-10-5) : sum of all node values = 18
Path 8(brown, 3-10-3) : sum of all node values = 16
The answer is 22, as Path 4 has the maximum sum of values of nodes in its path from a
root to leaves.
The greedy approach fails in this case. Starting from the root and take 3 from the

877
Chapter 115. Dynamic Programming on Trees | Set-1

first level, 10 from the next level and 5 from the third level greedily. Result is path-7 if after
following greedy approach, hence do not apply greedy approach over here.
The problem can be solved using Dynamic Programming on trees. Start memoizing
from the leaves and add the maximum of leaves to the root of every sub-tree. At the last
step, there will be root and the sub-tree under it, adding the value at node and maximum
of sub-tree will give us the maximum sum of the node values from root to any of the leaves.

The diagram above shows how to start from the leaves and add the maximum of
leaves of a sub-tree to its root. Move upward and repeat the same procedure of storing
the maximum of every sub-tree leaves and adding it to its root. In this example, the
maximum of node 11 and 12 is taken to count and then added to node 5(In this sub-tree,
5 is the root and 11, 12 are its leaves). Similarly, the maximum of node 13 and 15 is
taken to count and then added to node 7. Repeat the steps for every sub-tree till we reach
the node.
Let DPi be the maximum summation of node values in the path between i and any of its
leaves moving downwards. Traverse the tree using DFS traversal. Store the maximum

878
Chapter 115. Dynamic Programming on Trees | Set-1

of all the leaves of the sub-tree, and add it to the root of the sub-tree. At the end, DP1 will
have the maximum sum of the node values from root to any of the leaves without re-visiting
any node.
Below is the implementation of the above idea :

CPP

// CPP code to find the maximum path sum


#include <bits/stdc++.h>
using namespace std;
  
int dp[100];
  
// function for dfs traversal and to store the
// maximum value in dp[] for every node till the leaves
void dfs(int a[], vector<int> v[], int u, int parent)
{
    // initially dp[u] is always a[u]
    dp[u] = a[u - 1];
  
    // stores the maximum value from nodes
    int maximum = 0;
  
    // traverse the tree
    for (int child : v[u]) {
  
        // if child is parent, then we continue
        // without recursing further
        if (child == parent)
            continue;
  
        // call dfs for further traversal
        dfs(a, v, child, u);
  
        // store the maximum of previous visited node
        // and present visited node
        maximum = max(maximum, dp[child]);
    }
  
    // add the maximum value returned to the parent node
    dp[u] += maximum;
}
  
// function that returns the maximum value
int maximumValue(int a[], vector<int> v[])
{
    dfs(a, v, 1, 0);

879
Chapter 115. Dynamic Programming on Trees | Set-1

    return dp[1];
}
  
// Driver Code
int main()
{
    // number of nodes
    int n = 14;
  
    // adjacency list
    vector<int> v[n + 1];
  
    // create undirected edges
    // initialize the tree given in the diagram
    v[1].push_back(2), v[2].push_back(1);
    v[1].push_back(3), v[3].push_back(1);
    v[1].push_back(4), v[4].push_back(1);
    v[2].push_back(5), v[5].push_back(2);
    v[2].push_back(6), v[6].push_back(2);
    v[3].push_back(7), v[7].push_back(3);
    v[4].push_back(8), v[8].push_back(4);
    v[4].push_back(9), v[9].push_back(4);
    v[4].push_back(10), v[10].push_back(4);
    v[5].push_back(11), v[11].push_back(5);
    v[5].push_back(12), v[12].push_back(5);
    v[7].push_back(13), v[13].push_back(7);
    v[7].push_back(14), v[14].push_back(7);
  
    // values of node 1, 2, 3....14
    int a[] = { 3, 2, 1, 10, 1, 3, 9, 1, 5, 3, 4, 5, 9, 8 };
  
    // function call
    cout << maximumValue(a, v);
  
    return 0;
}

Output:

22

Time Complexity : O(N), where N is the number of nodes.

Source

https://www.geeksforgeeks.org/dynamic-programming-trees-set-1/

880
Chapter 116

Dynamic Programming vs
Divide-and-Conquer

Dynamic Programming vs Divide-and-Conquer - GeeksforGeeks


TL;DR
In this article I’m trying to explain the difference/similarities between dynamic programing
and divide and conquer approaches based on two examples: binary search and minimum
edit distance (Levenshtein distance).

The Problem

When I started to learn algorithms it was hard for me to understand the main idea of
dynamic programming (DP) and how it is different from divide-and-conquer (DC) approach.
When it gets to comparing those two paradigms usually Fibonacci function comes to the
rescue as great example. But when we’re trying to solve the same problem using both DP
and DC approaches to explain each of them, it feels for me like we may lose valuable detail
that might help to catch the difference faster. And these detail tells us that each technique
serves best for different types of problems.
I’m still in the process of understanding DP and DC difference and I can’t say that I’ve fully
grasped the concepts so far. But I hope this article will shed some extra light and help you
to do another step of learning such valuable algorithm paradigms as dynamic programming
and divide-and-conquer.

Dynamic Programming and Divide-and-Conquer Similarities

As I see it for now I can say that dynamic programming is an extension of divide and conquer
paradigm.
I would not treat them as something completely different. Because they both work by
recursively breaking down a problem into two or more sub-problems of the same or related

881
Chapter 116. Dynamic Programming vs Divide-and-Conquer

type, until these become simple enough to be solved directly. The solutions to the sub-
problems are then combined to give a solution to the original problem.
So why do we still have different paradigm names then and why I called dynamic program-
ming an extension. It is because dynamic programming approach may be applied to the
problem only if the problem has certain restrictions or prerequisites. And after that dy-
namic programming extends divide and conquer approach with memoization or tabulation
technique.
Let’s go step by step…

Dynamic Programming Prerequisites/Restrictions

As we’ve just discovered there are two key attributes that divide and conquer problem must
have in order for dynamic programming to be applicable:

1. Optimal substructure—optimal solution can be constructed from optimal solutions of


its subproblems
2. Overlapping sub-problems—problem can be broken down into subproblems which are
reused several times or a recursive algorithm for the problem solves the same subprob-
lem over and over rather than always generating new subproblems

Once these two conditions are met we can say that this divide and conquer problem may
be solved using dynamic programming approach.

Dynamic Programming Extension for Divide and Conquer

Dynamic programming approach extends divide and conquer approach with two techniques
(memoization and tabulation) that both have a purpose of storing and re-using sub-problems
solutions that may drastically improve performance. For example naive recursive implemen-
tation of Fibonacci function has time complexity of O(2^n) where DP solution doing the
same with only O(n) time.
Memoization (top-down cache filling) refers to the technique of caching and reusing previ-
ously computed results. The memoized fib function would thus look like this:

memFib(n) {
if (mem[n] is undefined)
if (n < 2) result = n
else result = memFib(n-2) + memFib(n-1)
mem[n] = result
return mem[n]
}

Tabulation (bottom-up cache filling) is similar but focuses on filling the entries of the cache.
Computing the values in the cache is easiest done iteratively. The tabulation version of fib
would look like this:

882
Chapter 116. Dynamic Programming vs Divide-and-Conquer

Figure 116.1:

tabFib(n) {
mem[0] = 0
mem[1] = 1
for i = 2...n
mem[i] = mem[i-2] + mem[i-1]
return mem[n]
}

You may read more about memoization and tabulation comparison here.
The main idea you should grasp here is that because our divide and conquer problem has
overlapping sub-problems the caching of sub-problem solutions becomes possible and thus
memoization/tabulation step up onto the scene.

So What the Difference Between DP and DC After All

Since we’re now familiar with DP prerequisites and its methodologies we’re ready to put all
that was mentioned above into one picture.
Let’s go and try to solve some problems using DP and DC approaches to make this illustra-
tion more clear.

Divide and Conquer Example: Binary Search

Binary search algorithm, also known as half-interval search, is a search algorithm that finds

883
Chapter 116. Dynamic Programming vs Divide-and-Conquer

the position of a target value within a sorted array. Binary search compares the target value
to the middle element of the array; if they are unequal, the half in which the target cannot
lie is eliminated and the search continues on the remaining half until the target value is
found. If the search ends with the remaining half being empty, the target is not in the array.
Example
Here is a visualization of the binary search algorithm where 4 is the target value.
Let’s draw the same logic but in form of decision tree.

You may clearly see here a divide and conquer principle of solving the problem. We’re
iteratively breaking the original array into sub-arrays and trying to find required element
in there.
Can we apply dynamic programming to it? No. It is because there are no overlapping sub-
problems. Every time we split the array into completely independent parts. And according
to divide and conquer prerequisites/restrictions the sub-problems must be overlapped some-
how.
Normally every time you draw a decision tree and it is actually a tree (and not a decision
graph) it would mean that you don’t have overlapping sub-problems and this is not dynamic
programming problem.
The Code
Here you may find complete source code of binary search function with test cases and
explanations.

function binarySearch(sortedArray, seekElement) {


let startIndex = 0;
let endIndex = sortedArray.length - 1;
while (startIndex <= endIndex) {
const middleIndex = startIndex + Math.floor((endIndex - startIndex) / 2);
// If we've found the element just return its position.
if (sortedArray[middleIndex] === seekElement)) {
return middleIndex;
}
// Decide which half to choose: left or right one.
if (sortedArray[middleIndex] < seekElement)) {
// Go to the right half of the array.
startIndex = middleIndex + 1;
} else {
// Go to the left half of the array.
endIndex = middleIndex - 1;
}
}
return -1;
}

884
Chapter 116. Dynamic Programming vs Divide-and-Conquer

Figure 116.2:

885
Chapter 116. Dynamic Programming vs Divide-and-Conquer

Figure 116.3:

886
Chapter 116. Dynamic Programming vs Divide-and-Conquer

Figure 116.4:

Dynamic Programming Example: Minimum Edit Distance

Normally when it comes to dynamic programming examples the Fibonacci number algorithm
is being taken by default. But let’s take a little bit more complex algorithm to have some
kind of variety that should help us to grasp the concept.
Minimum Edit Distance (or Levenshtein Distance) is a string metric for measuring the differ-
ence between two sequences. Informally, the Levenshtein distance between two words is the
minimum number of single-character edits (insertions, deletions or substitutions) required
to change one word into the other.
Example
For example, the Levenshtein distance between “kitten” and “sitting” is 3, since the following
three edits change one into the other, and there is no way to do it with fewer than three
edits:

1. kitten > sitten (substitution of “s” for “k”)


2. sitten > sittin (substitution of “i” for “e”)
3. sittin > sitting (insertion of “g” at the end).

Applications
This has a wide range of applications, for instance, spell checkers, correction systems for
optical character recognition, fuzzy string searching, and software to assist natural language
translation based on translation memory.
Mathematical Definition
Mathematically, the Levenshtein distance between two strings a, b (of length |a| and |b|
respectively) is given by function lev(|a|, |b|) where
Note that the first element in the minimum corresponds to deletion (from a to b), the second
to insertion and the third to match or mismatch, depending on whether the respective
symbols are the same.
Explanation
Ok, let’s try to figure out what that formula is talking about. Let’s take a simple example of
finding minimum edit distance between strings ME and MY. Intuitively you already know
that minimum edit distance here is 1 operation and this operation is “replace E with Y”. But
let’s try to formalize it in a form of the algorithm in order to be able to do more complex
examples like transforming Saturday into Sunday.

887
Chapter 116. Dynamic Programming vs Divide-and-Conquer

Figure 116.5: Simple example of finding minimum edit distance between ME and MY strings

To apply the formula to ME>MY transformation we need to know minimum edit distances
of ME>M, M>MY and M>M transformations in prior. Then we will need to pick the
minimum one and add +1 operation to transform last letters E?Y.
So we can already see here a recursive nature of the solution: minimum edit distance of
ME>MY transformation is being calculated based on three previously possible transforma-
tions. Thus we may say that this is divide and conquer algorithm.
To explain this further let’s draw the following matrix.
Cell (0, 1) contains red number 1. It means that we need 1 operation to transform M to
empty string: delete M. This is why this number is red.
Cell (0, 2) contains red number 2. It means that we need 2 operations to transform ME to
empty string: delete E, delete M.
Cell (1, 0) contains green number 1. It means that we need 1 operation to transform empty
string to M: insert M. This is why this number is green.
Cell (2, 0) contains green number 2. It means that we need 2 operations to transform empty
string to MY: insert Y, insert M.
Cell (1, 1) contains number 0. It means that it costs nothing to transform M to M.
Cell (1, 2) contains red number 1. It means that we need 1 operation to transform ME to
M: delete E.
And so on…
This looks easy for such small matrix as ours (it is only 3×3). But how we could calculate all
those numbers for bigger matrices (let’s say 9×7 one, for Saturday>Sunday transformation)?
The good news is that according to the formula you only need three adjacent cells (i-1, j),
(i-1, j-1), and (i, j-1) to calculate the number for current cell (i, j) . All we need to do is to

888
Chapter 116. Dynamic Programming vs Divide-and-Conquer

Figure 116.6: Recursive nature of minimum edit distance problem

Figure 116.7: Decision graph for minimum edit distance with overlapping sub-problems

find the minimum of those three cells and then add +1 in case if we have different letters
in i-s row and j-s column
So once again you may clearly see the recursive nature of the problem.
Ok we’ve just found out that we’re dealing with divide and conquer problem here. But can
we apply dynamic programming approach to it? Does this problem satisfies our overlapping
sub-problems and optimal substructure restrictions? Yes. Let’s see it from decision graph.
First of all this is not a decision tree. It is a decision graph. You may see a number of
overlapping subproblems on the picture that are marked with red. Also there is no way to
reduce the number of operations and make it less then a minimum of those three adjacent
cells from the formula.
Also you may notice that each cell number in the matrix is being calculated based on
previous ones. Thus the tabulation technique (filling the cache in bottom-up direction) is
being applied here. You’ll see it in code example below.
Applying this principles further we may solve more complicated cases like with Saturday >

889
Chapter 116. Dynamic Programming vs Divide-and-Conquer

Figure 116.8: Minimum edit distance to convert Saturday to Sunday

Sunday transformation.
The Code
Here you may find complete source code of minimum edit distance function with test cases
and explanations.

function levenshteinDistance(a, b) {
const distanceMatrix = Array(b.length + 1)
.fill(null)
.map(
() => Array(a.length + 1).fill(null)
);

for (let i = 0; i <= a.length; i += 1) {


distanceMatrix[0][i] = i;
}

for (let j = 0; j <= b.length; j += 1) {


distanceMatrix[j][0] = j;
}

for (let j = 1; j <= b.length; j += 1) {


for (let i = 1; i <= a.length; i += 1) {
const indicator = a[i - 1] === b[j - 1] ? 0 : 1;

890
Chapter 116. Dynamic Programming vs Divide-and-Conquer

distanceMatrix[j][i] = Math.min(
distanceMatrix[j][i - 1] + 1, // deletion
distanceMatrix[j - 1][i] + 1, // insertion
distanceMatrix[j - 1][i - 1] + indicator, // substitution
);
}
}

return distanceMatrix[b.length][a.length];
}

Conclusion

In this article we have compared two algorithmic approaches such as dynamic programming
and divide-and-conquer. We’ve found out that dynamic programing is based on divide and
conquer principle and may be applied only if the problem has overlapping sub-problems
and optimal substructure (like in Levenshtein distance case). Dynamic programming then
is using memoization or tabulation technique to store solutions of overlapping sub-problems
for later usage.
I hope this article hasn’t brought you more confusion but rather shed some light on these
two important algorithmic concepts! �
You may find more examples of divide and conquer and dynamic programming problems
with explanations, comments and test cases in JavaScript Algorithms and Data Structures
repository.
Happy coding!

Source

https://www.geeksforgeeks.org/dynamic-programming-vs-divide-and-conquer/

891
Chapter 117

Dynamic Programming |
Building Bridges

Dynamic Programming | Building Bridges - GeeksforGeeks


Consider a 2-D map with a horizontal river passing through its center. There are n cities
on the southern bank with x-coordinates a(1) … a(n) and n cities on the northern bank
with x-coordinates b(1) … b(n). You want to connect as many north-south pairs of cities
as possible with bridges such that no two bridges cross. When connecting cities, you can
only connect city a(i) on the northern bank to city b(i) on the southern bank. Maximum
number of bridges that can be built to connect north-south pairs with the aforementioned
constraints.

The values in the upper bank can be considered as the northern x-coordinates of the cities
and the values in the bottom bank can be considered as the corresponding southern x-
coordinates of the cities to which the northern x-coordinate city can be connected.
Examples:

Input : 6 4 2 1
2 3 6 5
Output : Maximum number of bridges = 2

892
Chapter 117. Dynamic Programming | Building Bridges

Explanation: Let the north-south x-coordinates


be written in increasing order.

1 2 3 4 5 6
\ \
\ \ For the north-south pairs
\ \ (2, 6) and (1, 5)
\ \ the bridges can be built.
\ \ We can consider other pairs also,
\ \ but then only one bridge can be built
\ \ because more than one bridge built will
\ \ then cross each other.
\ \
1 2 3 4 5 6

Input : 8 1 4 3 5 2 6 7
1 2 3 4 5 6 7 8
Output : Maximum number of bridges = 2

Approach: It is a variation of LIS problem. The following are the steps to solve the
problem.

1. Sort the north-south pairs on the basis of increasing order of south x-coordinates.
2. If two south x-coordinates are same, then sort on the basis of increasing order of north
x-coordinates.
3. Now find the Longest Increasing Subsequence of the north x-coordinates.
4. One thing to note that in the increasing subsequence a value can be greater as well as
can be equal to its previous value.

We can also sort on the basis of north x-coordinates and find the LIS on the south x-
coordinates.

// C++ implementation of building bridges


#include <bits/stdc++.h>
  
using namespace std;
  
// north-south coodinates
// of each City Pair
struct CityPairs
{
    int north, south;
};
  
// comparison function to sort
// the given set of CityPairs
bool compare(struct CityPairs a, struct CityPairs b)

893
Chapter 117. Dynamic Programming | Building Bridges

{
    if (a.south == b.south)
        return a.north < b.north;
    return a.south < b.south;
}
  
// function to find the maximum number
// of bridges that can be built
int maxBridges(struct CityPairs values[], int n)
{
    int lis[n];
    for (int i=0; i<n; i++)
        lis[i] = 1;
          
    sort(values, values+n, compare);
      
    // logic of longest increasing subsequence
    // applied on the northern coordinates
    for (int i=1; i<n; i++)
        for (int j=0; j<i; j++)
            if (values[i].north >= values[j].north 
                && lis[i] < 1 + lis[j])
                lis[i] = 1 + lis[j];
          
          
    int max = lis[0];
    for (int i=1; i<n; i++)
        if (max < lis[i])
            max = lis[i];
      
    // required number of bridges
    // that can be built        
    return max;        
}
  
// Driver program to test above
int main()
{
    struct CityPairs values[] = {{6, 2}, {4, 3}, {2, 6}, {1, 5}};
    int n = 4;
    cout << "Maximum number of bridges = " 
             << maxBridges(values, n);    
    return 0;

Output:

894
Chapter 117. Dynamic Programming | Building Bridges

Maximum number of bridges = 2

Time Complexity: O(n2 )


Problem References:
https://www.geeksforgeeks.org/dynamic-programming-set-14-variations-of-lis/
Solution References:
https://www.youtube.com/watch?v=w6tSmS86C4w

Source

https://www.geeksforgeeks.org/dynamic-programming-building-bridges/

895
Chapter 118

Dynamic Programming |
High-effort vs. Low-effort Tasks
Problem

Dynamic Programming | High-effort vs. Low-effort Tasks Problem - GeeksforGeeks


You are given n days and for each day (di) you could either perform a high effort tasks (hi)
or a low effort tasks (li) or no task with the constraint that you can choose a high-effort
tasks only if you chose no task on the previous day. Write a program to find the maximum
amount of tasks you can perform within these n days.
Examples:

No. of days (n) = 5


Day L.E. H.E
1 1 3
2 5 6
3 4 8
4 5 7
5 3 6
Maximum amount of tasks
= 3 + 5 + 4 + 5 + 3
= 20

Optimal Substructure
To find the maximum amount of tasks done till i’th day, we need to compare 2 choices:

1. Go for high effort tasks on that day, then find the maximum amount of tasks done till
(i – 2) th day.
2. Go for low effort task on that day and find the maximum amount of tasks done till (i
– 1) th day.

896
Chapter 118. Dynamic Programming | High-effort vs. Low-effort Tasks Problem

Let high [1…n] be the input array for high effort task amount on i’th day and low [1…n] be
the input array for low effort task amount on ith day.
Let max_task (high [], low [], i) be the function that returns maximum amount of task done
till ith day, so it will return max(high[i] + max_task(high, low, (i – 2)), low [i] + max_task
(high, low, (i – 1)))
Therefore, the problem has optimal substructure property as the problem can be solved
using solutions to subproblems.
Overlapping Subproblems
Following is a simple recursive implementation of the High-effort vs. Low-effort task problem.
The implementation simply follows the recursive structure mentioned above. So, High-effort
vs. Low-effort Task Problem has both properties of a dynamic programming problem.

// A naive recursive C program to find maximum


// tasks.
#include<stdio.h>
  
// Returns the maximum among the 2 numbers
int max(int x, int y)
{
    return (x > y ? x : y);
}
  
// Returns maximum amount of task that can be
// done till day n
int maxTasks(int high[], int low[], int n)
{
    // If n is less than equal to 0, then no
    // solution exists
    if (n <= 0)
        return 0;
  
    /* Determines which task to choose on day n,
       then returns the maximum till that day */
    return max(high[n-1] + maxTasks(high, low, (n-2)),
              low[n-1] + maxTasks(high, low, (n-1)));
}
  
// Driver program to test above function
int main()
{
    int n = 5;
    int high[] = {3, 6, 8, 7, 6};
    int low[] = {1, 5, 4, 5, 3};
    printf("%dn", maxTasks(high, low, n));
    return 0;
}

897
Chapter 118. Dynamic Programming | High-effort vs. Low-effort Tasks Problem

Output :

20

It should be noted that the above function computes the same subproblems again and again.
Therefore, this problem has Overlapping Subproblems Property. So the High-effort vs. Low-
effort Task Problem has both the properties of a dynamic programming problem.
Dynamic Programming Solution

// A DP based C++ program to find maximum tasks.


#include<stdio.h>
  
// Returns the maximum among the 2 numbers
int max(int x, int y)
{
    return (x > y ? x : y);
}
  
// Returns maximum amount of task that can be
// done till day n
int maxTasks(int high[], int low[], int n)
{
    // An array task_dp that stores the maximum
    // task done
    int task_dp[n+1];
  
    // If n = 0, no solution exists
    task_dp[0] = 0;
  
    // If n = 1, high effort task on that day will
    // be the solution
    task_dp[1] = high[0];
  
    // Fill the entire array determining which
    // task to choose on day i
    for (int i = 2; i <= n; i++)
        task_dp[i] = max(high[i-1] + task_dp[i-2],
                         low[i-1] + task_dp[i-1]);
    return task_dp[n];
}
  
// Driver program to test above function
int main()
{
    int n = 5;
    int high[] = {3, 6, 8, 7, 6};
    int low[] = {1, 5, 4, 5, 3};

898
Chapter 118. Dynamic Programming | High-effort vs. Low-effort Tasks Problem

    printf("%dn", maxTasks(high, low, n));


    return 0;
}

Output:

20

Time Complexity : O(n)

Source

https://www.geeksforgeeks.org/dynamic-programming-high-effort-vs-low-effort-tasks-problem/

899
Chapter 119

Dynamic Programming |
Wildcard Pattern Matching |
Linear Time and Constant
Space

Dynamic Programming | Wildcard Pattern Matching | Linear Time and Constant Space -
GeeksforGeeks
Given a text and a wildcard pattern, find if wildcard pattern is matched with text. The
matching should cover the entire text (not partial text).
The wildcard pattern can include the characters ‘?’ and ‘*’
‘?’ – matches any single character
‘*’ – Matches any sequence of characters (including the empty sequence)
Prerequisite : Dynamic Programming | Wildcard Pattern Matching
Examples:

Text = "baaabab",
Pattern = “*****ba*****ab", output : true
Pattern = "baaa?ab", output : true
Pattern = "ba*a?", output : true
Pattern = "a*ab", output : false

900
Chapter 119. Dynamic Programming | Wildcard Pattern Matching | Linear Time and
Constant Space

Each occurrence of ‘?’ character in wildcard pattern can be replaced with any other character
and each occurrence of ‘*’ with a sequence of characters such that the wildcard pattern
becomes identical to the input string after replacement.
We have discussed a solution here which has O(m x n) time and O(m x n) space complexity.
For applying the optimization, we will at first note the BASE CASE which involves :
If the length of the pattern is zero then answer will be true only if the length of the text
with which we have to match the pattern is also zero.
ALGORITHM | (STEP BY STEP)
Step – (1) : Let i be the marker to point at the current character of the text.
Let j be the marker to point at the current character of the pattern.
Let index_txt be the marker to point at the character of text on which we encounter ‘*’ in
pattern.
Let index_pat be the marker to point at the position of ‘*’ in the pattern.
NOTE : WE WILL TRAVERSE THE GIVEN STRING AND PATTERN US-
ING A WHILE LOOP
Step – (2) : At any instant if we observe that txt[i] == pat[j], then we increment both i and
j as no operation needs to be performed in this case.

901
Chapter 119. Dynamic Programming | Wildcard Pattern Matching | Linear Time and
Constant Space

Step – (3) : If we encounter pat[j] == ‘?’, then it resembles the case mentioned in step –
(2) as ‘?’ has the property to match with any single character.
Step – (4) : If we encounter pat[j] == ‘*’, then we update the value of index_txt and
index_pat as ‘*’ has the property to match any sequence of characters (including the empty
sequence) and we will increment the value of j to compare next character of pattern with
the current character of the text.(As character represented by i has not been answered yet).
Step – (5) : Now if txt[i] == pat[j], and we have encountered a ‘*’ before, then it means
that ‘*’ included the empty sequence, else if txt[i] != pat[j], a character needs to be provided
by ‘*’ so that current character matching takes place, then i needs to be incremented as it
is answered now but the character represented by j still needs to be answered, therefore, j =
index_pat + 1, i = index_txt + 1 (as ‘*’ can capture other characters as well), index_txt++
(as current character in text is matched).
Step – (6) : If step – (5) is not valid, that means txt[i] != pat[j], also we have not encountered
a ‘*’ that means it is not possible for the pattern to match the string. (return false).
Step – (7) : Check whether j reached its final value or not, then return the final answer.
Let us see the above algorithm in action, then we will move to the coding section
:
text = “baaabab”
pattern = “*****ba*****ab”
NOW APPLYING THE ALGORITHM
Step – (1) : i = 0 (i –> ‘b’)
j = 0 (j –> ‘*’)
index_txt = -1
index_pat = -1
NOTE : LOOP WILL RUN TILL i REACHES ITS FINAL
VALUE OR THE ANSWER BECOMES FALSE MIDWAY.
FIRST COMPARISON :-
As we see here that pat[j] == ‘*’, therefore directly jumping on to step – (4).
Step – (4) : index_txt = i (index_txt –> ‘b’)
index_pat = j (index_pat –> ‘*’)
j++ (j –> ‘*’)
After four more comparisons : i = 0 (i –> ‘b’)
j = 5 (j –> ‘b’)
index_txt = 0 (index_txt –> ‘b’)
index_pat = 4 (index_pat –> ‘*’)
SIXTH COMPARISON :-
As we see here that txt[i] == pat[j], but we already encountered ‘*’ therefore using step –
(5).
Step – (5) : i = 1 (i –> ‘a’)
j = 6 (j –> ‘a’)
index_txt = 0 (index_txt –> ‘b’)
index_pat = 4 (index_pat –> ‘*’)

902
Chapter 119. Dynamic Programming | Wildcard Pattern Matching | Linear Time and
Constant Space

SEVENTH COMPARISON :-
Step – (5) : i = 2 (i –> ‘a’)
j = 7 (j –> ‘*’)
index_txt = 0 (index_txt –> ‘b’)
index_pat = 4 (index_pat –> ‘*’)
EIGTH COMPARISON :-
Step – (4) : i = 2 (i –> ‘a’)
j = 8 (j –> ‘*’)
index_txt = 2 (index_txt –> ‘a’)
index_pat = 7 (index_pat –> ‘*’)
After four more comparisons : i = 2 (i –> ‘a’)
j = 12 (j –> ‘a’)
index_txt = 2 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
THIRTEENTH COMPARISON :-
Step – (5) : i = 3 (i –> ‘a’)
j = 13 (j –> ‘b’)
index_txt = 2 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
FOURTEENTH COMPARISON :-
Step – (5) : i = 3 (i –> ‘a’)
j = 12 (j –> ‘a’)
index_txt = 3 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
FIFTEENTH COMPARISON :-
Step – (5) : i = 4 (i –> ‘b’)
j = 13 (j –> ‘b’)
index_txt = 3 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
SIXTEENTH COMPARISON :-
Step – (5) : i = 5 (i –> ‘a’)
j = 14 (j –> end)
index_txt = 3 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
SEVENTEENTH COMPARISON :-
Step – (5) : i = 4 (i –> ‘b’)
j = 12 (j –> ‘a’)
index_txt = 4 (index_txt –> ‘b’)
index_pat = 11 (index_pat –> ‘*’)
EIGHTEENTH COMPARISON :-

903
Chapter 119. Dynamic Programming | Wildcard Pattern Matching | Linear Time and
Constant Space

Step – (5) : i = 5 (i –> ‘a’)


j = 12 (j –> ‘a’)
index_txt = 5 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
NINETEENTH COMPARISON :-
Step – (5) : i = 6 (i –> ‘b’)
j = 13 (j –> ‘b’)
index_txt = 5 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
TWENTIETH COMPARISON :-
Step – (5) : i = 7 (i –> end)
j = 14 (j –> end)
index_txt = 5 (index_txt –> ‘a’)
index_pat = 11 (index_pat –> ‘*’)
NOTE : NOW WE WILL COME OUT OF LOOP TO RUN STEP – 7.
Step – (7) : j is already present at its end position, therefore answer is true.
Below is the implementation of above optimized approach.

// C++ program to implement wildcard


// pattern matching algorithm
#include <bits/stdc++.h>
using namespace std;
  
// Function that matches input text
// with given wildcard pattern
bool strmatch(char txt[], char pat[],
              int n, int m)
{
    // empty pattern can only
    // match with empty string.
    // Base Case :
    if (m == 0)
        return (n == 0);
  
    // step-1 :
    // initailze markers :
    int i = 0, j = 0, index_txt = -1,
        index_pat = -1;
  
    while (i < n) {
  
        // For step - (2, 5)
        if (txt[i] == pat[j]) {
            i++;

904
Chapter 119. Dynamic Programming | Wildcard Pattern Matching | Linear Time and
Constant Space

            j++;
        }
  
        // For step - (3)
        else if (j < m && pat[j] == '?') {
            i++;
            j++;
        }
  
        // For step - (4)
        else if (j < m && pat[j] == '*') {
            index_txt = i;
            index_pat = j;
            j++;
        }
  
        // For step - (5)
        else if (index_pat != -1) {
            j = index_pat + 1;
            i = index_txt + 1;
            index_txt++;
        }
  
        // For step - (6)
        else {
            return false;
        }
    }
  
    // For step - (7)
    while (j < m && pat[j] == '*') {
        j++;
    }
  
    // Final Check
    if (j == m) {
        return true;
    }
  
    return false;
}
  
// Driver code
int main()
{
    char str[] = "baaabab";
    char pattern[] = "*****ba*****ab";
    // char pattern[] = "ba*****ab";

905
Chapter 119. Dynamic Programming | Wildcard Pattern Matching | Linear Time and
Constant Space

    // char pattern[] = "ba*ab";


    // char pattern[] = "a*ab";
  
    if (strmatch(str, pattern,
                 strlen(str), strlen(pattern)))
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
  
    char pattern2[] = "a*****ab";
    if (strmatch(str, pattern2,
                 strlen(str), strlen(pattern2)))
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
  
    return 0;
}

Output:

Yes
No

Time complexity of above solution is O(m). Auxiliary space used is O(1).

Source

https://www.geeksforgeeks.org/dynamic-programming-wildcard-pattern-matching-linear-time-constant-space/

906
Chapter 120

Edit Distance | DP using


Memoization

Edit Distance | DP using Memoization - GeeksforGeeks


Given two strings str1 and str2 and below operations that can be performed on str1. Find
the minimum number of edits (operations) required to convert ‘str1’ into ‘str2’.

• Insert
• Remove
• Replace

All of the above operations are of equal cost.


Examples:

Input: str1 = “geek”, str2 = “gesek”


Output: 1
We can convert str1 into str2 by inserting a ‘s’.
Input: str1 = “cat”, str2 = “cut”
Output: 1
We can convert str1 into str2 by replacing ‘a’ with ‘u’.
Input: str1 = “sunday”, str2 = “saturday”
Output: 3
Last three and first characters are same. We basically
need to convert “un” to “atur”. This can be done using
below three operations.
Replace ‘n’ with ‘r’, insert t, insert a

<div
What are the subproblems in this case? The idea is to process all characters one by
one staring from either from left or right sides of both strings. Let us traverse from right

907
Chapter 120. Edit Distance | DP using Memoization

corner, there are two possibilities for every pair of character being traversed. The following
are the conditions:

1. If last characters of two strings are same, nothing much to do. Ignore last characters
and get count for remaining strings. So we recur for lengths m-1 and n-1.
2. Else (If last characters are not same), we consider all operations on ‘str1’, consider all
three operations on last character of first string, recursively compute minimum cost
for all three operations and take minimum of three values.
• Insert: Recur for m and n-1
• Remove: Recur for m-1 and n
• Replace: Recur for m-1 and n-1

Below is the implementation of the above approach:


C++

// A Naive recursive C++ program to find minimum number


// operations to convert str1 to str2
#include <bits/stdc++.h>
using namespace std;
  
// Utility function to find minimum of three numbers
int min(int x, int y, int z)
{
    return min(min(x, y), z);
}
  
int editDist(string str1, string str2, int m, int n)
{
    // If first string is empty, the only option is to
    // insert all characters of second string into first
    if (m == 0)
        return n;
  
    // If second string is empty, the only option is to
    // remove all characters of first string
    if (n == 0)
        return m;
  
    // If last characters of two strings are same, nothing
    // much to do. Ignore last characters and get count for
    // remaining strings.
    if (str1[m - 1] == str2[n - 1])
        return editDist(str1, str2, m - 1, n - 1);
  
    // If last characters are not same, consider all three
    // operations on last character of first string, recursively

908
Chapter 120. Edit Distance | DP using Memoization

    // compute minimum cost for all three operations and take
    // minimum of three values.
    return 1 + min(editDist(str1, str2, m, n - 1), // Insert
                   editDist(str1, str2, m - 1, n), // Remove
                   editDist(str1, str2, m - 1, n - 1) // Replace
                   );
}
  
// Driver program
int main()
{
    // your code goes here
    string str1 = "sunday";
    string str2 = "saturday";
  
    cout << editDist(str1, str2, str1.length(), str2.length());
  
    return 0;
}

Java

// A Naive recursive Java program to find minimum number


// operations to convert str1 to str2
class EDIST {
    static int min(int x, int y, int z)
    {
        if (x <= y && x <= z)
            return x;
        if (y <= x && y <= z)
            return y;
        else
            return z;
    }
  
    static int editDist(String str1, String str2, int m, int n)
    {
        // If first string is empty, the only option is to
        // insert all characters of second string into first
        if (m == 0)
            return n;
  
        // If second string is empty, the only option is to
        // remove all characters of first string
        if (n == 0)
            return m;
  
        // If last characters of two strings are same, nothing

909
Chapter 120. Edit Distance | DP using Memoization

        // much to do. Ignore last characters and get count for
        // remaining strings.
        if (str1.charAt(m - 1) == str2.charAt(n - 1))
            return editDist(str1, str2, m - 1, n - 1);
  
        // If last characters are not same, consider all three
        // operations on last character of first string, recursively
        // compute minimum cost for all three operations and take
        // minimum of three values.
        return 1 + min(editDist(str1, str2, m, n - 1), // Insert
                       editDist(str1, str2, m - 1, n), // Remove
                       editDist(str1, str2, m - 1, n - 1) // Replace
                       );
    }
  
    public static void main(String args[])
    {
        String str1 = "sunday";
        String str2 = "saturday";
  
        System.out.println(editDist(str1, str2, str1.length(), str2.length()));
    }
}

Python

# A Naive recursive Python program to fin minimum number


# operations to convert str1 to str2
def editDistance(str1, str2, m, n):
  
    # If first string is empty, the only option is to
    # insert all characters of second string into first
    if m == 0:
         return n
  
    # If second string is empty, the only option is to
    # remove all characters of first string
    if n == 0:
        return m
  
    # If last characters of two strings are same, nothing
    # much to do. Ignore last characters and get count for
    # remaining strings.
    if str1[m-1]== str2[n-1]:
        return editDistance(str1, str2, m-1, n-1)
  
    # If last characters are not same, consider all three
    # operations on last character of first string, recursively

910
Chapter 120. Edit Distance | DP using Memoization

    # compute minimum cost for all three operations and take
    # minimum of three values.
    return 1 + min(editDistance(str1, str2, m, n-1),    # Insert
                   editDistance(str1, str2, m-1, n),    # Remove
                   editDistance(str1, str2, m-1, n-1)    # Replace
                   )
  
# Driver program to test the above function
str1 = "sunday"
str2 = "saturday"
print editDistance(str1, str2, len(str1), len(str2))

C#

// A Naive recursive C# program to


// find minimum numberoperations
// to convert str1 to str2
using System;
  
class GFG {
    static int min(int x, int y, int z)
    {
        if (x <= y && x <= z)
            return x;
        if (y <= x && y <= z)
            return y;
        else
            return z;
    }
  
    static int editDist(String str1, String str2, int m, int n)
    {
        // If first string is empty, the only option is to
        // insert all characters of second string into first
        if (m == 0)
            return n;
  
        // If second string is empty, the only option is to
        // remove all characters of first string
        if (n == 0)
            return m;
  
        // If last characters of two strings are same, nothing
        // much to do. Ignore last characters and get count for
        // remaining strings.
        if (str1[m - 1] == str2[n - 1])
            return editDist(str1, str2, m - 1, n - 1);
  

911
Chapter 120. Edit Distance | DP using Memoization

        // If last characters are not same, consider all three


        // operations on last character of first string, recursively
        // compute minimum cost for all three operations and take
        // minimum of three values.
        return 1 + min(editDist(str1, str2, m, n - 1), // Insert
                       editDist(str1, str2, m - 1, n), // Remove
                       editDist(str1, str2, m - 1, n - 1) // Replace
                       );
    }
  
    // Driver code
    public static void Main()
    {
        String str1 = "sunday";
        String str2 = "saturday";
        Console.WriteLine(editDist(str1, str2, str1.Length,
                                   str2.Length));
    }
}

Output:

The time complexity of above solution is O(3^n) which is exponential. The worst case
happens when none of characters of two strings match. Below is a recursive call diagram
for worst case.

We can see that many subproblems are solved, again and again, for example, eD(2, 2) is
called three times. Since same suproblems are called again, this problem has Overlapping

912
Chapter 120. Edit Distance | DP using Memoization

Subprolems property. So Edit Distance problem has both properties (see thisand this) of a
dynamic programming problem. Like other typical Dynamic Programming(DP) problems,
recomputations of same subproblems can be avoided by constructing a temporary array that
stores results of subproblems. The bottom-up approach can be found here.
The problem can also be solved using top-down Dynamic Programming and using mem-
oization. In the recursive code, memoization can be used to avoid overlapping problems.
There are several repetitive calls which can be computed in O(1) if the value is stored when
called for the first time. On observing the recursive code, it is seen that a maximum of two
parameters is changing their value on every recursive call. There will be cases when the
same recursive call has been called previously. Since two parameters are not constant, a
2-D array can be used to avoid repetitive calls. Hence the return value is stored in some
2-D array. Below are the steps:

• Initialize a 2-D DP array of size m *n with -1 at all the index.


• On every recursive call, store the return value at dp[m][n] so that if func(m, n) is
called again, it can be answered in O(1) without using recursion.
• Check if the recursive call has been visited previously or not by checking the value at
dp[m][n].

Below is the implementation of the above approach:

// A memoization program to find minimum number


// operations to convert str1 to str2
#include <bits/stdc++.h>
using namespace std;
  
// Maximum 2-D array coloumn size
const int maximum = 1000;
  
// Utility function to find minimum of three numbers
int min(int x, int y, int z)
{
    return min(min(x, y), z);
}
  
int editDist(string str1, string str2, int m, int n, int dp[][maximum])
{
    // If first string is empty, the only option is to
    // insert all characters of second string into first
    if (m == 0)
        return n;
  
    // If second string is empty, the only option is to
    // remove all characters of first string
    if (n == 0)
        return m;
  

913
Chapter 120. Edit Distance | DP using Memoization

    // if the recursive call has been


    // called previously, then return
    // the stored value that was calculated
    // previously
    if (dp[m - 1][n - 1] != -1)
        return dp[m - 1][n - 1];
  
    // If last characters of two strings are same, nothing
    // much to do. Ignore last characters and get count for
    // remaining strings.
  
    // Store the returned value at dp[m-1][n-1]
    // considering 1-based indexing
    if (str1[m - 1] == str2[n - 1])
        return dp[m - 1][n - 1] = editDist(str1, str2, m - 1, n - 1, dp);
  
    // If last characters are not same, consider all three
    // operations on last character of first string, recursively
    // compute minimum cost for all three operations and take
    // minimum of three values.
  
    // Store the returned value at dp[m-1][n-1]
    // considering 1-based indexing
    return dp[m - 1][n - 1] = 1 + min(editDist(str1, str2, m, n - 1, dp), // Insert
                                      editDist(str1, str2, m - 1, n, dp), // Remove
                                      editDist(str1, str2, m - 1, n - 1, dp) // Replace
                                      );
}
  
// Driver Code
int main()
{
  
    string str1 = "sunday";
    string str2 = "saturday";
    int m = str1.length();
    int n = str2.length();
  
    // Declare a dp array which stores
    // the answer to recursive calls
    int dp[m][maximum];
  
    // initially all index with -1
    memset(dp, -1, sizeof dp);
  
    // Function call
    // memoization nad top-down approach
    cout << editDist(str1, str2, m, n, dp);

914
Chapter 120. Edit Distance | DP using Memoization

  
    return 0;
}

Output:

Time Complexity: O(M * N)


Auxiliary Space: O(M * N)

Source

https://www.geeksforgeeks.org/edit-distance-dp-using-memoization/

915
Chapter 121

Edit distance and LCS (Longest


Common Subsequence)

Edit distance and LCS (Longest Common Subsequence) - GeeksforGeeks


In standard Edit Distance where we are allowed 3 operations, insert, delete and replace.
Consider a variation of edit distance where we are allowed only two operations insert and
delete, find edit distance in this variation.

Input : str1 = "cat", st2 = "cut"


Output : 2
We are allowed to insert and delete. We delete 'a'
from "cat" and insert "u" to make it "cut".

Input : str1 = "acb", st2 = "ab"


Output : 1
We can convert "acb" to "ab" by removing 'c'.

One solution is to simply modify Edit Distance Solution by making two recursive call instead
of three. An interesting solution is based on LCS.
1) Find LCS of two strings. Let length of LCS be x.
2) Let length of first string be m and length of second string be n. Our result is (m – x) +
(n – x). We basically need to do (m – x) delete operations and (n – x) insert operations.

// CPP program to find Edit Distance (when only two


// operations are allowed, insert and delete) using LCS.
#include<bits/stdc++.h>
using namespace std;
  
int editDistanceWith2Ops(string &X, string &Y)
{

916
Chapter 121. Edit distance and LCS (Longest Common Subsequence)

    // Find LCS


    int m = X.length(), n = Y.length(); 
    int L[m+1][n+1]; 
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
            else if (X[i-1] == Y[j-1])
                L[i][j] = L[i-1][j-1] + 1;
            else
                L[i][j] = max(L[i-1][j], L[i][j-1]);
        }
    }    
    int lcs  = L[m][n];
  
    // Edit distance is delete operations + 
    // insert operations.
    return (m - lcs) + (n - lcs);
}
  
/* Driver program to test above function */
int main()
{
    string X = "abc", Y = "acd";
    cout << editDistanceWith2Ops(X, Y);
    return 0;
}

Output:

Time Complexity : O(m * n)


Auxiliary Space : O(m * n)

Source

https://www.geeksforgeeks.org/edit-distance-and-lcs-longest-common-subsequence/

917
Chapter 122

Efficient program to print all


prime factors of a given number

Efficient program to print all prime factors of a given number


Given a number n, write an efficient function to print all prime factors of n. For example,
if the input number is 12, then output should be “2 2 3”. And if the input number is 315,
then output should be “3 3 5 7”.
Following are the steps to find all prime factors.
1) While n is divisible by 2, print 2 and divide n by 2.
2) After step 1, n must be odd. Now start a loop from i = 3 to square root of n. While i
divides n, print i and divide n by i, increment i by 2 and continue.
3) If n is a prime number and is greater than 2, then n will not become 1 by above two
steps. So print n if it is greater than 2.
C/C++

// Program to print all prime factors


# include <stdio.h>
# include <math.h>
  
// A function to print all prime factors of a given number n
void primeFactors(int n)
{
    // Print the number of 2s that divide n
    while (n%2 == 0)
    {
        printf("%d ", 2);
        n = n/2;
    }
  
    // n must be odd at this point.  So we can skip 
    // one element (Note i = i +2)

918
Chapter 122. Efficient program to print all prime factors of a given number

    for (int i = 3; i <= sqrt(n); i = i+2)


    {
        // While i divides n, print i and divide n
        while (n%i == 0)
        {
            printf("%d ", i);
            n = n/i;
        }
    }
  
    // This condition is to handle the case when n 
    // is a prime number greater than 2
    if (n > 2)
        printf ("%d ", n);
}
  
/* Driver program to test above function */
int main()
{
    int n = 315;
    primeFactors(n);
    return 0;
}

Java

// Program to print all prime factors


import java.io.*;
import java.lang.Math;
  
class GFG
{
    // A function to print all prime factors
    // of a given number n
    public static void primeFactors(int n)
    {
        // Print the number of 2s that divide n
        while (n%2==0)
        {
            System.out.print(2 + " ");
            n /= 2;
        }
  
        // n must be odd at this point.  So we can
        // skip one element (Note i = i +2)
        for (int i = 3; i <= Math.sqrt(n); i+= 2)
        {
            // While i divides n, print i and divide n

919
Chapter 122. Efficient program to print all prime factors of a given number

            while (n%i == 0)
            {
                System.out.print(i + " ");
                n /= i;
            }
        }
  
        // This condition is to handle the case whien
        // n is a prime number greater than 2
        if (n > 2)
            System.out.print(n);
    }
  
    public static void main (String[] args)
    {
        int n = 315;
        primeFactors(n);
    }
}

Python

# Python program to print prime factors


  
import math
  
# A function to print all prime factors of 
# a given number n
def primeFactors(n):
      
    # Print the number of two's that divide n
    while n % 2 == 0:
        print 2,
        n = n / 2
          
    # n must be odd at this point
    # so a skip of 2 ( i = i + 2) can be used
    for i in range(3,int(math.sqrt(n))+1,2):
          
        # while i divides n , print i ad divide n
        while n % i== 0:
            print i,
            n = n / i
              
    # Condition if n is a prime
    # number greater than 2
    if n > 2:
        print n

920
Chapter 122. Efficient program to print all prime factors of a given number

          
# Driver Program to test above function
  
n = 315
primeFactors(n)
  
# This code is contributed by Harshit Agrawal

C#

// C# Program to print all prime factors


using System;
  
namespace prime
{
public class GFG
{     
                  
    // A function to print all prime 
    // factors of a given number n
    public static void primeFactors(int n)
    {
        // Print the number of 2s that divide n
        while (n % 2 == 0)
        {
            Console.Write(2 + " ");
            n /= 2;
        }
  
        // n must be odd at this point. So we can
        // skip one element (Note i = i +2)
        for (int i = 3; i <= Math.Sqrt(n); i+= 2)
        {
            // While i divides n, print i and divide n
            while (n % i == 0)
            {
                Console.Write(i + " ");
                n /= i;
            }
        }
  
        // This condition is to handle the case whien
        // n is a prime number greater than 2
        if (n > 2)
            Console.Write(n);
    }
      
    // Driver Code

921
Chapter 122. Efficient program to print all prime factors of a given number

    public static void Main()


    {
        int n = 315;
        primeFactors(n);
    }
  

}
  
// This code is contributed by Sam007

PHP

<?php
// PHP Efficient program to print all
// prime factors of a given number
  
// function to print all prime 
// factors of a given number n
function primeFactors($n)
{
      
    // Print the number of
    // 2s that divide n
    while($n % 2 == 0)
    {
        echo 2," ";
        $n = $n / 2;
    }
  
    // n must be odd at this 
    // point. So we can skip 
    // one element (Note i = i +2)
    for ($i = 3; $i <= sqrt($n); 
                   $i = $i + 2)
    {
          
        // While i divides n, 
        // print i and divide n
        while ($n % $i == 0)
        {
            echo $i," ";
            $n = $n / $i;
        }
    }
  
    // This condition is to 
    // handle the case when n 

922
Chapter 122. Efficient program to print all prime factors of a given number

    // is a prime number greater


    // than 2
    if ($n > 2)
        echo $n," ";
}
  
    // Driver Code
    $n = 315;
    primeFactors($n);
  
// This code is contributed by aj_36
?>

Output:

3 3 5 7

How does this work?


The steps 1 and 2 take care of composite numbers and step 3 takes care of prime numbers.
To prove that the complete algorithm works, we need to prove that steps 1 and 2 actually
take care of composite numbers. This is clear that step 1 takes care of even numbers. And
after step 1, all remaining prime factor must be odd (difference of two prime factors must
be at least 2), this explains why i is incremented by 2.
Now the main part is, the loop runs till square root of n not till. To prove that this
optimization works, let us consider the following property of composite numbers.
Every composite number has at least one prime factor less than or equal to square root of
itself.
This property can be proved using counter statement. Let a and b be two factors of n such
that a*b = n. If both are greater than √n, then a.b > √n, * √n, which contradicts the
expression “a * b = n”.
In step 2 of the above algorithm, we run a loop and do following in loop
a) Find the least prime factor i (must be less than √n,)
b) Remove all occurrences i from n by repeatedly dividing n by i.
c) Repeat steps a and b for divided n and i = i + 2. The steps a and b are repeated till n
becomes either 1 or a prime number.
Related Article :
Prime Factorization using Sieve O(log n) for multiple queries
Thanks to Vishwas Garg for suggesting the above algorithm. Please write comments if you
find anything incorrect, or you want to share more information about the topic discussed
above
Improved By : jit_t

923
Chapter 122. Efficient program to print all prime factors of a given number

Source

https://www.geeksforgeeks.org/print-all-prime-factors-of-a-given-number/

924
Chapter 123

Entringer Number

Entringer Number - GeeksforGeeks


The Entringer Number E(n, k) are the number of permutations of {1, 2, …, n + 1},
starting with k + 1, which, after initally falling, alternatively fall then rise. The Entringer
are given by:

For example, for n = 4 and k = 2, E(4, 2) is 4.


They are:
32415
32514
31425
31524
Examples :

Input : n = 4, k = 2
Output : 4

Input : n = 4, k = 3
Output : 5

Below is program to find Entringer Number E(n, k). The program is based on above simple
recursive formula.

C++

925
Chapter 123. Entringer Number

// CPP Program to find Entringer Number E(n, k)


#include <bits/stdc++.h>
using namespace std;
  
// Return Entringer Number E(n, k)
int zigzag(int n, int k)
{
    // Base Case
    if (n == 0 && k == 0)
        return 1;
  
    // Base Case
    if (k == 0)
        return 0;
  
    // Recursive step
    return zigzag(n, k - 1) +
           zigzag(n - 1, n - k);
}
  
// Driven Program
int main()
{
    int n = 4, k = 3;
    cout << zigzag(n, k) << endl;
    return 0;
}

Java

// JAVA Code For Entringer Number


import java.util.*;
  
class GFG {
      
    // Return Entringer Number E(n, k)
    static int zigzag(int n, int k)
    {
        // Base Case
        if (n == 0 && k == 0)
            return 1;
       
        // Base Case
        if (k == 0)
            return 0;
       
        // Recursive step
        return zigzag(n, k - 1) +

926
Chapter 123. Entringer Number

               zigzag(n - 1, n - k);
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int n = 4, k = 3;
        System.out.println(zigzag(n, k));
          
    }
}
  
// This code is contributed by Arnav Kr. Mandal.

Python3

# Python Program to find Entringer Number E(n, k)


  
# Return Entringer Number E(n, k)
def zigzag(n, k):
  
    # Base Case
    if (n == 0 and k == 0):
        return 1
  
    # Base Case
    if (k == 0):
        return 0
  
    # Recursive step
    return zigzag(n, k - 1) + zigzag(n - 1, n - k);
  
# Driven Program
n = 4
k = 3
print(zigzag(n, k))
  
# This code is contributed by
# Smitha Dinesh Semwal    

C#

// C# Code For Entringer Number


using System;
  
class GFG {
  

927
Chapter 123. Entringer Number

    // Return Entringer Number E(n, k)


    static int zigzag(int n, int k)
    {
        // Base Case
        if (n == 0 && k == 0)
            return 1;
  
        // Base Case
        if (k == 0)
            return 0;
  
        // Recursive step
        return zigzag(n, k - 1) + 
               zigzag(n - 1, n - k);
    }
  
    /* Driver program to test above function */
    public static void Main()
    {
        int n = 4, k = 3;
        Console.WriteLine(zigzag(n, k));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program to find
// Entringer Number E(n, k)
  
// Return Entringer Number E(n, k)
function zigzag($n, $k)
{
    // Base Case
    if ($n == 0 and $k == 0)
        return 1;
  
    // Base Case
    if ($k == 0)
        return 0;
  
    // Recursive step
    return zigzag($n, $k - 1) +
        zigzag($n - 1,$n - $k);
}
  

928
Chapter 123. Entringer Number

// Driven Code
$n = 4; $k = 3;
echo zigzag($n, $k) ;
  
// This code is contributed by anuj_67.
?>

Output :

Below is the implementation of finding Entringer Number using Dynamic Programming:

C++

// CPP Program to find Entringer Number E(n, k)


#include <bits/stdc++.h>
using namespace std;
  
// Return Entringer Number E(n, k)
int zigzag(int n, int k)
{
    int dp[n + 1][k + 1];
    memset(dp, 0, sizeof(dp));
  
    // Base cases
    dp[0][0] = 1;
    for (int i = 1; i <= n; i++) 
        dp[i][0] = 0;    
  
    // Finding dp[i][j]
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= i; j++) 
            dp[i][j] = dp[i][j - 1] + 
                       dp[i - 1][i - j];
  
    return dp[n][k];
}
  
// Driven Program
int main()
{
    int n = 4, k = 3;
    cout << zigzag(n, k) << endl;
    return 0;
}

929
Chapter 123. Entringer Number

Java

// JAVA Code For Entringer Number


import java.util.*;
  
class GFG {
      
    // Return Entringer Number E(n, k)
    static int zigzag(int n, int k)
    {
        int dp[][] = new int[n + 1][k + 1];
         
        // Base cases
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++) 
            dp[i][0] = 0;    
       
        // Finding dp[i][j]
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= Math.min(i, k);
                                          j++) 
                dp[i][j] = dp[i][j - 1] + 
                           dp[i - 1][i - j];
            }
       
        return dp[n][k];
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int n = 4, k = 3;
        System.out.println(zigzag(n, k));
    }
}
      
// This code is contributed by Arnav Kr. Mandal.    

Python3

# Pyhton3 Program to find Entringer


# Number E(n, k)
  
# Return Entringer Number E(n, k)
def zigzag(n, k):
    dp = [[0 for x in range(k+1)] 
             for y in range(n+1)] 

930
Chapter 123. Entringer Number

  
    # Base cases
    dp[0][0] = 1
    for i in range(1, n+1):
        dp[i][0] = 0
  
    # Finding dp[i][j]
    for i in range(1, n+1):
        for j in range(1, k+1):
            dp[i][j] = (dp[i][j - 1] 
                 + dp[i - 1][i - j])
                          
    return dp[n][k]
  
# Driven Program
n = 4
k = 3
print(zigzag(n, k))
  
# This code is contributed by 
# Prasad Kshirsagar

C#

// C# Code For Entringer Number


using System;
  
class GFG {
  
    // Return Entringer Number E(n, k)
    static int zigzag(int n, int k)
    {
        int[, ] dp = new int[n + 1, k + 1];
  
        // Base cases
        dp[0, 0] = 1;
        for (int i = 1; i <= n; i++)
            dp[i, 0] = 0;
  
        // Finding dp[i][j]
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= Math.Min(i, k);
                j++)
                dp[i, j] = dp[i, j - 1] + dp[i - 1, i - j];
        }
  
        return dp[n, k];
    }

931
Chapter 123. Entringer Number

  
    /* Driver program to test above function */
    public static void Main()
    {
        int n = 4, k = 3;
        Console.WriteLine(zigzag(n, k));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program to find 
// Entringer Number E(n, k)
  
// Return Entringer Number E(n, k)
function zigzag($n, $k)
{
    $dp = array(array());
      
  
    // Base cases
    $dp[0][0] = 1;
    for ($i = 1; $i <= $n; $i++) 
        $dp[$i][0] = 0; 
  
    // Finding dp[i][j]
    for ($i = 1; $i <= $n; $i++) 
    {
        for ($j = 1; $j <= $i; $j++) 
            $dp[$i][$j] = $dp[$i][$j - 1] + 
                          $dp[$i - 1][$i - $j];
    }
    return $dp[$n][$k];
}
  
// Driven Code
$n = 4; $k = 3;
echo zigzag($n, $k);
  
// This code is contributed by anuj_67.
?>

Output :

932
Chapter 123. Entringer Number

Improved By : vt_m, Prasad_Kshirsagar

Source

https://www.geeksforgeeks.org/entringer-number/

933
Chapter 124

Eulerian Number

Eulerian Number - GeeksforGeeks


In combinatorics, the Eulerian Number A(n, m), is the number of permutations of the
numbers 1 to n in which exactly m elements are greater than previous element.
For example, there are 4 permutations of the number 1 to 3 in which exactly 1 element is
greater than the previous elements.

Examples :

Input : n = 3, m = 1
Output : 4
Please see above diagram (There
are 4 permutations where 1 no. is
greater.

Input : n = 4, m = 1
Output : 11

Eulerian Numbers are the coefficients of the Eulerian polynomials described below.

934
Chapter 124. Eulerian Number

The Eulerian polynomials are defined by the exponential generating function

The Eulerian polynomials can be computed by the recurrence

An explicit formula for A(n, m) is

We can calculate A(n, m) by recurrence relation:

Example:
Suppose, n = 3 and m = 1.
Therefore,
A(3, 1)
= (3 – 1) * A(2, 0) + (1 + 1) * A(2, 1)
= 2 * A(2, 0) + 2 * A(2, 1)
= 2 * 1 + 2 * ( (2 – 1) * A(1, 0) + (1 + 1) * A(1, 1))
= 2 + 2 * (1 * 1 + 2 * ((1 – 1) * A(0, 0) + (1 + 1) * A(0, 1))
= 2 + 2 * (1 + 2 * (0 * 1 + 2 * 0)
= 2 + 2 * (1 + 2 * 0)
=2+2*1
=2+2
=4
We can verify this with example shown above.
Below is the implementation of finding A(n, m):

C++

// CPP Program to find Eulerian number A(n, m)

935
Chapter 124. Eulerian Number

#include <bits/stdc++.h>
using namespace std;
  
// Return euleriannumber A(n, m)
int eulerian(int n, int m)
{
    if (m >= n || n == 0)
        return 0;
  
    if (m == 0)
        return 1;
  
    return (n - m) * eulerian(n - 1, m - 1) + 
           (m + 1) * eulerian(n - 1, m);
}
  
// Driven Program
int main()
{
    int n = 3, m = 1;
    cout << eulerian(n, m) << endl;
    return 0;
}

Java

// Java rogram to find Eulerian number A(n, m)


import java.util.*;
  
class Eulerian
{
    // Return eulerian number A(n, m)
    public static int eulerian(int n, int m)
    {
        if (m >= n || n == 0)
            return 0;
  
        if (m == 0)
            return 1;
  
        return (n - m) * eulerian(n - 1, m - 1) +
            (m + 1) * eulerian(n - 1, m);
    }
      
    // driver code    
    public static void main(String[] args)
    {
        int n = 3, m = 1;

936
Chapter 124. Eulerian Number

        System.out.print( eulerian(n, m) );
    }
}
  
// This code is contributed by rishabh_jain

Python3

# Python3 Program to find Eulerian number A(n, m)


  
# Return euleriannumber A(n, m)
def eulerian(n, m):
    if (m >= n or n == 0):
        return 0;
  
    if (m == 0):
        return 1;
  
    return ((n - m) * eulerian(n - 1, m - 1) +
            (m + 1) * eulerian(n - 1, m))
  
# Driver code
n = 3
m = 1
print( eulerian(n, m) )
  
# This code is contributed by rishabh_jain

C#

// C# rogram to find Eulerian number A(n, m)


using System;
  
class Eulerian {
      
    // Return eulerian number A(n, m)
    public static int eulerian(int n, int m)
    {
        if (m >= n || n == 0)
            return 0;
  
        if (m == 0)
            return 1;
  
        return (n - m) * eulerian(n - 1, m - 1) + 
                    (m + 1) * eulerian(n - 1, m);
    }

937
Chapter 124. Eulerian Number

  
    // driver code
    public static void Main()
    {
        int n = 3, m = 1;
        Console.WriteLine(eulerian(n, m));
    }
}
  
// This code is contributed by vt_m

PHP

<?php
// PHP Program to find
// Eulerian number A(n, m)
  
// Return euleriannumber A(n, m)
function eulerian($n, $m)
{
    if ($m >= $n || $n == 0)
        return 0;
  
    if ($m == 0)
        return 1;
  
    return ($n - $m) * eulerian($n - 1, $m - 1) + 
                 ($m + 1) * eulerian($n - 1, $m);
}
  
// Driven Code
$n = 3; $m = 1;
echo eulerian($n, $m);
  
// This code is contributed by anuj_67.
?>

Output :

Below is the implementation of finding A(n, m) using Dynamic Programming:

C++

938
Chapter 124. Eulerian Number

// CPP Program to find Eulerian number A(n, m)


#include <bits/stdc++.h>
using namespace std;
  
// Return euleriannumber A(n, m)
int eulerian(int n, int m)
{
    int dp[n + 1][m + 1];
  
    memset(dp, 0, sizeof(dp));
  
    // For each row from 1 to n
    for (int i = 1; i <= n; i++) {
  
        // For each column from 0 to m
        for (int j = 0; j <= m; j++) {
  
            // If i is greater than j
            if (i > j) {
  
                // If j is 0, then make that 
                // state as 1.
                if (j == 0)
                    dp[i][j] = 1;
  
                // basic recurrence relation.
                else
                    dp[i][j] = ((i - j) *
                     dp[i - 1][j - 1]) + 
                    ((j + 1) * dp[i - 1][j]);
            }
        }
    }
  
    return dp[n][m];
}
  
// Driven Program
int main()
{
    int n = 3, m = 1;
    cout << eulerian(n, m) << endl;
    return 0;
}

Java

// Java rogram to find Eulerian number A(n, m)

939
Chapter 124. Eulerian Number

import java.util.*;
  
class Eulerian
{
    // Return euleriannumber A(n, m)
    public static int eulerian(int n, int m)
    {
        int[][] dp = new int[n+1][m+1];
  
        // For each row from 1 to n
        for (int i = 1; i <= n; i++) {
      
            // For each column from 0 to m
            for (int j = 0; j <= m; j++) {
  
                // If i is greater than j
                if (i > j) {
  
                    // If j is 0, then make 
                    // that state as 1.
                    if (j == 0)
                        dp[i][j] = 1;
  
                    // basic recurrence relation.
                    else
                        dp[i][j] = ((i - j) *
                            dp[i - 1][j - 1]) +
                        ((j + 1) * dp[i - 1][j]);
                }
            }
        }
  
        return dp[n][m];
    }
      
    // driver code
    public static void main(String[] args)
    {
        int n = 3, m = 1;
        System.out.print( eulerian(n, m) );
    }
}
  
// This code is contributed by rishabh_jain

Python3

# Python3 Program to find Eulerian 

940
Chapter 124. Eulerian Number

# number A(n, m)
  
# Return euleriannumber A(n, m)
def eulerian(n, m):
    dp = [[0 for x in range(m+1)] 
             for y in range(n+1)] 
  
    # For each row from 1 to n
    for i in range(1, n+1):
  
        # For each column from 0 to m
        for j in range(0, m+1):
  
            # If i is greater than j
            if (i > j):
                # If j is 0, then make that 
                # state as 1.
  
                if (j == 0):
                    dp[i][j] = 1
  
                # basic recurrence relation.
                else :
                    dp[i][j] = (((i - j) * 
                       dp[i - 1][j - 1]) + 
                       ((j + 1) * dp[i - 1][j]))
                      
    return dp[n][m]
  
# Driven Program
n = 3
m = 1
print(eulerian(n, m))
  
# This code is contributed by Prasad Kshirsagar

C#

// C# rogram to find Eulerian number A(n, m)


using System;
  
class Eulerian {
      
    // Return euleriannumber A(n, m)
    public static int eulerian(int n, int m)
    {
        int[, ] dp = new int[n + 1, m + 1];
  

941
Chapter 124. Eulerian Number

        // For each row from 1 to n


        for (int i = 1; i <= n; i++) {
  
            // For each column from 0 to m
            for (int j = 0; j <= m; j++) {
  
                // If i is greater than j
                if (i > j) {
  
                    // If j is 0, then make
                    // that state as 1.
                    if (j == 0)
                        dp[i, j] = 1;
  
                    // basic recurrence relation.
                    else
                        dp[i, j] = ((i - j) * dp[i - 1, j - 1]) +
                                        ((j + 1) * dp[i - 1, j]);
                }
            }
        }
  
        return dp[n, m];
    }
  
    // driver code
    public static void Main()
    {
        int n = 3, m = 1;
        Console.WriteLine(eulerian(n, m));
    }
}
  
// This code is contributed by vt_m

Output :

Improved By : vt_m, Prasad_Kshirsagar

Source

https://www.geeksforgeeks.org/eulerian-number/

942
Chapter 125

Find Jobs involved in Weighted


Job Scheduling

Find Jobs involved in Weighted Job Scheduling - GeeksforGeeks


Given N jobs where every job is represented by following three elements of it.
1. Start Time
2. Finish Time
3. Profit or Value Associated
Find the subset of jobs associated with maximum profit such that no two jobs in the
subset overlap.
Examples:

Input:
Number of Jobs n = 4
Job Details {Start Time, Finish Time, Profit}
Job 1: {1, 2, 50}
Job 2: {3, 5, 20}
Job 3: {6, 19, 100}
Job 4: {2, 100, 200}

Output:
Jobs involved in maximum profit are
Job 1: {1, 2, 50}
Job 4: {2, 100, 200}

In previous post, we have discussed about Weighted Job Scheduling problem. However, the
post only covered code related to finding maximum profit. In this post, we will also print
the jobs invloved in maximum profit.

943
Chapter 125. Find Jobs involved in Weighted Job Scheduling

Let arr[0..n-1] be the input array of Jobs. We define an array DP[] such that DP[i] stores
Jobs involved to achieve maximum profit of array arr[0..i]. i.e. DP[i] stores solution to
subproblem arr[0..i]. The rest of algorithm remains same as discussed in previous post.
Below is its C++ implementation –

// C++ program for weighted job scheduling using Dynamic


// Programming and Binary Search
#include <bits/stdc++.h>
using namespace std;
  
// A job has start time, finish time and profit.
struct Job
{
    int start, finish, profit;
};
  
// to store subset of jobs
struct weightedJob
{
    // vector of Jobs
    vector<Job> job;
  
    // find profit associated with included Jobs
    int value;
};
  
// A utility function that is used for sorting events
// according to finish time
bool jobComparator(Job s1, Job s2)
{
    return (s1.finish < s2.finish);
}
  
// A Binary Search based function to find the latest job
// (before current job) that doesn't conflict with current
// job. "index" is index of the current job. This function
// returns -1 if all jobs before index conflict with it. The
// array jobs[] is sorted in increasing order of finish time
int latestNonConflict(Job jobs[], int index)
{
    // Initialize 'lo' and 'hi' for Binary Search
    int lo = 0, hi = index - 1;
  
    // Perform binary Search iteratively
    while (lo <= hi)
    {
        int mid = (lo + hi) / 2;
        if (jobs[mid].finish <= jobs[index].start)

944
Chapter 125. Find Jobs involved in Weighted Job Scheduling

        {
            if (jobs[mid + 1].finish <= jobs[index].start)
                lo = mid + 1;
            else
                return mid;
        }
        else
            hi = mid - 1;
    }
  
    return -1;
}
  
// The main function that finds the subset of jobs
// associated with maximum profit such that no two
// jobs in the subset overlap.
int findMaxProfit(Job arr[], int n)
{
    // Sort jobs according to finish time
    sort(arr, arr + n, jobComparator);
  
    // Create an array to store solutions of subproblems.
    // DP[i] stores the Jobs involved and their total profit
    // till arr[i] (including arr[i])
    weightedJob DP[n];
  
    // initialize DP[0] to arr[0]
    DP[0].value = arr[0].profit;
    DP[0].job.push_back(arr[0]);
  
    // Fill entries in DP[] using recursive property
    for (int i = 1; i < n; i++)
    {
        // Find profit including the current job
        int inclProf = arr[i].profit;
        int l = latestNonConflict(arr, i);
        if (l != - 1)
            inclProf += DP[l].value;
  
        // Store maximum of including and excluding
        if (inclProf > DP[i - 1].value)
        {
            DP[i].value = inclProf;
  
            // including previous jobs and current job
            DP[i].job = DP[l].job;
            DP[i].job.push_back(arr[i]);
  

945
Chapter 125. Find Jobs involved in Weighted Job Scheduling

        }
        else
            // excluding the current job
            DP[i] = DP[i - 1];
    }
  
    // DP[n - 1] stores the result
    cout << "Optimal Jobs for maximum profits are\n" ;
    for (int i=0; i<DP[n-1].job.size(); i++)
    {
        Job j = DP[n-1].job[i];
        cout << "(" << j.start << ", " << j.finish
             << ", " << j.profit << ")" << endl;
    }
    cout << "\nTotal Optimal profit is " << DP[n - 1].value;
}
  
// Driver program
int main()
{
    Job arr[] = {{3, 5, 20}, {1, 2, 50}, {6, 19, 100},
        {2, 100, 200} };
    int n = sizeof(arr)/sizeof(arr[0]);
  
    findMaxProfit(arr, n);
  
    return 0;
}

Output:

Optimal Jobs for maximum profits are


(1, 2, 50)
(2, 100, 200)

Total Optimal profit is 250

Source

https://www.geeksforgeeks.org/find-jobs-involved-in-weighted-job-scheduling/

946
Chapter 126

Find Maximum dot product of


two arrays with insertion of 0’s

Find Maximum dot product of two arrays with insertion of 0’s - GeeksforGeeks
Given two arrays of positive integers of size m and n where m > n. We need to maximize
the dot product by inserting zeros in the second array but we cannot disturb the order of
elements.
Examples:

Input : A[] = {2, 3 , 1, 7, 8}


B[] = {3, 6, 7}
Output : 107
Explanation : We get maximum dot product after
inserting 0 at first and third positions in
second array.
Maximum Dot Product : = A[i] * B[j]
2*0 + 3*3 + 1*0 + 7*6 + 8*7 = 107

Input : A[] = {1, 2, 3, 6, 1, 4}


B[] = {4, 5, 1}
Output : 46

Asked in: Directi Interview


Another way to look at this problem is, for every pair of elements element A[i] and B[j]
where j >= i , we have two choices:

1. We multiply A[i] and B[j] and add to product (We include A[i]).
2. We exclude A[i] from product (In other words, we insert 0 at current position in B[])

947
Chapter 126. Find Maximum dot product of two arrays with insertion of 0’s

The idea is to use Dynamic programing.

1) Given Array A[] of size 'm' and B[] of size 'n'

2) Create 2D matrix 'DP[n + 1][m + 1]' initialize it


with '0'

3) Run loop outer loop for i = 1 to n


Inner loop j = 1 to m

// Two cases arise


// 1) Include A[j]
// 2) Exclude A[j] (insert 0 in B[])
dp[i][j] = max(dp[i-1][j-1] + A[j-1] * B[i -1],
dp[i][j-1])

// Last return maximum dot product that is


return dp[n][m]

Below is the implementation of above idea.

C++

// C++ program to find maximum dot product of two array


#include<bits/stdc++.h>
using namespace std;
  
// Function compute Maximum Dot Product and
// return it
long long int MaxDotProduct(int A[], int B[],
                            int m, int n)
{
    // Create 2D Matrix that stores dot product
    // dp[i+1][j+1] stores product considering B[0..i]
    // and A[0...j]. Note that since all m > n, we fill
    // values in upper diagonal of dp[][]
    long long int dp[n+1][m+1];
    memset(dp, 0, sizeof(dp));
  
    // Traverse through all elements of B[]
    for (int i=1; i<=n; i++)
  
        // Consider all values of A[] with indexes greater
        // than or equal to i and compute dp[i][j]
        for (int j=i; j<=m; j++)
  

948
Chapter 126. Find Maximum dot product of two arrays with insertion of 0’s

            // Two cases arise


            // 1) Include A[j]
            // 2) Exclude A[j] (insert 0 in B[]) 
            dp[i][j] = max((dp[i-1][j-1] + (A[j-1]*B[i-1])) ,
                            dp[i][j-1]);
  
    // return Maximum Dot Product
    return dp[n][m] ;
}
  
// Driver program to test above function
int main()
{
    int A[] = { 2, 3 , 1, 7, 8 } ;
    int B[] = { 3, 6, 7 } ;
    int m = sizeof(A)/sizeof(A[0]);
    int n = sizeof(B)/sizeof(B[0]);
    cout << MaxDotProduct(A, B, m, n);
    return 0;
}

Java

// Java program to find maximum 


// dot product of two array
import java.util.*;
  
class GFG 
{
// Function to compute Maximum 
// Dot Product and return it
static int MaxDotProduct(int A[], int B[], int m, int n)
{
    // Create 2D Matrix that stores dot product
    // dp[i+1][j+1] stores product considering B[0..i]
    // and A[0...j]. Note that since all m > n, we fill
    // values in upper diagonal of dp[][]
    int dp[][] = new int[n + 1][m + 1];
    for (int[] row : dp)
    Arrays.fill(row, 0);
  
    // Traverse through all elements of B[]
    for (int i = 1; i <= n; i++)
  
    // Consider all values of A[] with indexes greater
    // than or equal to i and compute dp[i][j]
    for (int j = i; j <= m; j++)
  

949
Chapter 126. Find Maximum dot product of two arrays with insertion of 0’s

        // Two cases arise


        // 1) Include A[j]
        // 2) Exclude A[j] (insert 0 in B[])
        dp[i][j] =
            Math.max((dp[i - 1][j - 1] + 
                    (A[j - 1] * B[i - 1])), dp[i][j - 1]);
  
    // return Maximum Dot Product
    return dp[n][m];
}
  
// Driver code
public static void main(String[] args) {
    int A[] = {2, 3, 1, 7, 8};
    int B[] = {3, 6, 7};
    int m = A.length;
    int n = B.length;
    System.out.print(MaxDotProduct(A, B, m, n));
}
}
  
// This code is contributed by Anant Agarwal.

Output:

107

Time Complexity : O(nm)

Source

https://www.geeksforgeeks.org/find-maximum-dot-product-two-arrays-insertion-0s/

950
Chapter 127

Find all combinations of k-bit


numbers with n bits set where 1
<= n <= k in sorted order

Find all combinations of k-bit numbers with n bits set where 1 <= n <= k in sorted order
- GeeksforGeeks
Given a number k, find all the possible combinations of k-bit numbers with n-bits set where
1 <= n <= k. The solution should print all numbers with one set bit first, followed by
numbers with two bits set,.. up to the numbers whose all k-bits are set. If two numbers
have the same number of set bits, then smaller number should come first.
Examples:

Input: K = 3
Output:
001 010 100
011 101 110
111

Input: K = 4
Output:
0001 0010 0100 1000
0011 0101 0110 1001 1010 1100
0111 1011 1101 1110
1111

Input: K = 5
Output:
00001 00010 00100 01000 10000
00011 00101 00110 01001 01010 01100 10001 10010 10100 11000

951
Chapter 127. Find all combinations of k-bit numbers with n bits set where 1 <= n <= k
in sorted order

00111 01011 01101 01110 10011 10101 10110 11001 11010 11100
01111 10111 11011 11101 11110
11111

We need to find all the possible combinations of k-bit numbers with n set bits where 1 <= n
<= k. If we carefully analyze, we see that problem can further be divided into sub-problems.
We can find all combinations of length k with n ones by prefixing 0 to all combinations of
length k-1 with n ones and 1 to all combinations of length k-1 with n-1 ones. We can use
Dynamic Programming to save solutions of sub-problems.
Below is C++ implementation of above idea –

// C++ program find all the possible combinations of 


// k-bit numbers with n-bits set where 1 <= n <= k
#include <iostream>
#include <vector>
using namespace std;
// maximum allowed value of K
#define K 16
  
// DP lookup table
vector<string> DP[K][K];
  
// Function to find all combinations k-bit numbers with 
// n-bits set where 1 <= n <= k
void findBitCombinations(int k)
{
    string str = "";
      
    // DP[k][0] will store all k-bit numbers  
    // with 0 bits set (All bits are 0's)
    for (int len = 0; len <= k; len++) 
    {
        DP[len][0].push_back(str);
        str = str + "0";
    }
      
    // fill DP lookup table in bottom-up manner
    // DP[k][n] will store all k-bit numbers  
    // with n-bits set
    for (int len = 1; len <= k; len++)
    {
        for (int n = 1; n <= len; n++)
        {
            // prefix 0 to all combinations of length len-1 
            // with n ones
            for (string str : DP[len - 1][n])
                DP[len][n].push_back("0" + str);

952
Chapter 127. Find all combinations of k-bit numbers with n bits set where 1 <= n <= k
in sorted order

  
            // prefix 1 to all combinations of length len-1 
            // with n-1 ones
            for (string str : DP[len - 1][n - 1])
                DP[len][n].push_back("1" + str);
        }
    }
      
    // print all k-bit binary strings with
    // n-bit set
    for (int n = 1; n <= k; n++) 
    {
        for (string str : DP[k][n])
            cout << str << " ";
  
        cout << endl;
    }
}
  
// Driver code
int main()
{
    int k = 5;
    findBitCombinations(k);
  
    return 0;
}

Output:

00000
00001 00010 00100 01000 10000
00011 00101 00110 01001 01010 01100 10001 10010 10100 11000
00111 01011 01101 01110 10011 10101 10110 11001 11010 11100
01111 10111 11011 11101 11110
11111

Source

https://www.geeksforgeeks.org/find-combinations-k-bit-numbers-n-bits-set-1-n-k-sorted-order/

953
Chapter 128

Find all distinct palindromic


sub-strings of a given string

Find all distinct palindromic sub-strings of a given string - GeeksforGeeks


Given a string of lowercase ASCII characters, find all distinct continuous palindromic sub-
strings of it.
Examples:

Input: str = "abaaa"


Output: Below are 5 palindrome sub-strings
a
aa
aaa
aba
b

Input: str = "geek"


Output: Below are 4 palindrome sub-strings
e
ee
g
k

Step 1: Finding all palindromes using modified Manacher’s algorithm:


Considering each character as a pivot, expand on both sides to find the length of both even
and odd length palindromes centered at the pivot character under consideration and store
the length in the 2 arrays (odd & even).
Time complexity for this step is O(n^2)

954
Chapter 128. Find all distinct palindromic sub-strings of a given string

Step 2: Inserting all the found palindromes in a HashMap:


Insert all the palindromes found from the previous step into a HashMap. Also insert all the
individual characters from the string into the HashMap (to generate distinct single letter
palindromic sub-strings).
Time complexity of this step is O(n^3) assuming that the hash insert search takes O(1) time.
Note that there can be at most O(n^2) palindrome sub-strings of a string. In below C++
code ordered hashmap is used where the time complexity of insert and search is O(Logn).
In C++, ordered hashmap is implemented using Red Black Tree.
Step 3: Printing the distinct palindromes and number of such distinct palin-
dromes:
The last step is to print all values stored in the HashMap (only distinct elements will be
hashed due to the property of HashMap). The size of the map gives the number of distinct
palindromic continuous sub-strings.
Below is the implementation of the above idea.
C/C++

// C++ program to find all distinct palindrome sub-strings


// of a given string
#include <iostream>
#include <map>
using namespace std;
  
// Function to print all distinct palindrome sub-strings of s
void palindromeSubStrs(string s)
{
    map<string, int> m;
    int n = s.size();
  
    // table for storing results (2 rows for odd-
    // and even-length palindromes
    int R[2][n+1];
  
    // Find all sub-string palindromes from the given input
    // string insert 'guards' to iterate easily over s
    s = "@" + s + "#";
  
    for (int j = 0; j <= 1; j++)
    {
        int rp = 0;   // length of 'palindrome radius'
        R[j][0] = 0;
  
        int i = 1;
        while (i <= n)
        {
            //  Attempt to expand palindrome centered at i
            while (s[i - rp - 1] == s[i + j + rp])

955
Chapter 128. Find all distinct palindromic sub-strings of a given string

                rp++;  // Incrementing the length of palindromic


                       // radius as and when we find vaid palindrome
  
            // Assigning the found palindromic length to odd/even
            // length array
            R[j][i] = rp;
            int k = 1;
            while ((R[j][i - k] != rp - k) && (k < rp))
            {
                R[j][i + k] = min(R[j][i - k],rp - k);
                k++;
            }
            rp = max(rp - k,0);
            i += k;
        }
    }
  
    // remove 'guards'
    s = s.substr(1, n);
  
    // Put all obtained palindromes in a hash map to
    // find only distinct palindromess
    m[string(1, s[0])]=1;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j <= 1; j++)
            for (int rp = R[j][i]; rp > 0; rp--)
               m[s.substr(i - rp - 1, 2 * rp + j)]=1;
        m[string(1, s[i])]=1;
    }
  
    //printing all distinct palindromes from hash map
   cout << "Below are " << m.size()-1
        << " palindrome sub-strings";
   map<string, int>::iterator ii;
   for (ii = m.begin(); ii!=m.end(); ++ii)
      cout << (*ii).first << endl;
}
  
// Driver program
int main()
{
    palindromeSubStrs("abaaa");
    return 0;
}

Java

956
Chapter 128. Find all distinct palindromic sub-strings of a given string

// Java program to find all distinct palindrome


// sub-strings of a given string
import java.util.Map;
import java.util.TreeMap;
  
public class GFG 
{     
    // Function to print all distinct palindrome
    // sub-strings of s
    static void palindromeSubStrs(String s)
    {
        //map<string, int> m;
        TreeMap<String , Integer> m = new TreeMap<>();
        int n = s.length();
       
        // table for storing results (2 rows for odd-
        // and even-length palindromes
        int[][] R = new int[2][n+1];
       
        // Find all sub-string palindromes from the 
        // given input string insert 'guards' to 
        // iterate easily over s
        s = "@" + s + "#";
       
        for (int j = 0; j <= 1; j++)
        {
            int rp = 0;   // length of 'palindrome radius'
            R[j][0] = 0;
       
            int i = 1;
            while (i <= n)
            {
                //  Attempt to expand palindrome centered 
                // at i
                while (s.charAt(i - rp - 1) == s.charAt(i + 
                                                j + rp))
                    rp++;  // Incrementing the length of
                           // palindromic radius as and 
                           // when we find vaid palindrome
       
                // Assigning the found palindromic length
                // to odd/even length array
                R[j][i] = rp;
                int k = 1;
                while ((R[j][i - k] != rp - k) && (k < rp))
                {
                    R[j][i + k] = Math.min(R[j][i - k], 
                                              rp - k);

957
Chapter 128. Find all distinct palindromic sub-strings of a given string

                    k++;
                }
                rp = Math.max(rp - k,0);
                i += k;
            }
        }
       
        // remove 'guards'
        s = s.substring(1, s.length()-1);
       
        // Put all obtained palindromes in a hash map to
        // find only distinct palindromess
        m.put(s.substring(0,1), 1);
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j <= 1; j++)
                for (int rp = R[j][i]; rp > 0; rp--)
                   m.put(s.substring(i - rp - 1,  i - rp - 1 
                                       + 2 * rp + j), 1);
            m.put(s.substring(i, i + 1), 1);
        }
       
        // printing all distinct palindromes from 
        // hash map
       System.out.println("Below are " + (m.size())
                           + " palindrome sub-strings");
         
       for (Map.Entry<String, Integer> ii:m.entrySet())
          System.out.println(ii.getKey());
    }
       
    // Driver program
    public static void main(String args[])
    {
        palindromeSubStrs("abaaa");
    }
}
// This code is contributed by Sumit Ghosh

Python

# Python program Find all distinct palindromic sub-strings


# of a given string
  
# Function to print all distinct palindrome sub-strings of s
def palindromeSubStrs(s):
    m = dict()
    n = len(s)

958
Chapter 128. Find all distinct palindromic sub-strings of a given string

  
    # table for storing results (2 rows for odd-
    # and even-length palindromes
    R = [[0 for x in xrange(n+1)] for x in xrange(2)]
  
    # Find all sub-string palindromes from the given input
    # string insert 'guards' to iterate easily over s
    s = "@" + s + "#"
  
    for j in xrange(2):
        rp = 0    # length of 'palindrome radius'
        R[j][0] = 0
  
        i = 1
        while i <= n:
  
            # Attempt to expand palindrome centered at i
            while s[i - rp - 1] == s[i + j + rp]:
                rp += 1 # Incrementing the length of palindromic
                        # radius as and when we find valid palindrome
  
            # Assigning the found palindromic length to odd/even
            # length array
            R[j][i] = rp
            k = 1
            while (R[j][i - k] != rp - k) and (k < rp):
                R[j][i+k] = min(R[j][i-k], rp - k)
                k += 1
            rp = max(rp - k, 0)
            i += k
  
    # remove guards
    s = s[1:len(s)-1]
  
    # Put all obtained palindromes in a hash map to
    # find only distinct palindrome
    m[s[0]] = 1
    for i in xrange(1,n):
        for j in xrange(2):
            for rp in xrange(R[j][i],0,-1):
                m[s[i - rp - 1 : i - rp - 1 + 2 * rp + j]] = 1
        m[s[i]] = 1
  
    # printing all distinct palindromes from hash map
    print "Below are " + str(len(m)) + " pali sub-strings"
    for i in m:
        print i
  

959
Chapter 128. Find all distinct palindromic sub-strings of a given string

# Driver program
palindromeSubStrs("abaaa")
# This code is contributed by BHAVYA JAIN and ROHIT SIKKA

Output:

Below are 5 palindrome sub-strings


a
aa
aaa
aba
b

Similar Problem:
Count All Palindrome Sub-Strings in a String
This article is contributed by Vignesh Narayanan and Sowmya Sampath. Please write
comments if you find anything incorrect, or you want to share more information about the
topic discussed above.
Improved By : utkarshver

Source

https://www.geeksforgeeks.org/find-number-distinct-palindromic-sub-strings-given-string/

960
Chapter 129

Find all distinct subset (or


subsequence) sums of an array

Find all distinct subset (or subsequence) sums of an array - GeeksforGeeks


Given a set of integers, find distinct sum that can be generated from the subsets of the given
sets and print them in an increasing order. It is given that sum of array elements is small.
Examples:

Input : arr[] = {1, 2, 3}


Output : 0 1 2 3 4 5 6
Distinct subsets of given set are
{}, {1}, {2}, {3}, {1,2}, {2,3},
{1,3} and {1,2,3}. Sums of these
subsets are 0, 1, 2, 3, 3, 5, 4, 6
After removing duplicates, we get
0, 1, 2, 3, 4, 5, 6

Input : arr[] = {2, 3, 4, 5, 6}


Output : 0 2 3 4 5 6 7 8 9 10 11 12
13 14 15 16 17 18 20

Input : arr[] = {20, 30, 50}


Output : 0 20 30 50 70 80 100

The naive solution for this problem is to generate all the subsets, store their sums in a
hash set and finally print all keys from hash set.

C++

961
Chapter 129. Find all distinct subset (or subsequence) sums of an array

// C++ program to print distinct subset sums of


// a given array.
#include<bits/stdc++.h>
using namespace std;
  
// sum denotes the current sum of the subset
// currindex denotes the index we have reached in
// the given array
void distSumRec(int arr[], int n, int sum,
                int currindex, unordered_set<int> &s)
{
    if (currindex > n)
        return;
  
    if (currindex == n)
    {
        s.insert(sum);
        return;
    }
  
    distSumRec(arr, n, sum + arr[currindex],
                            currindex+1, s);
    distSumRec(arr, n, sum, currindex+1, s);
}
  
// This function mainly calls recursive function
// distSumRec() to generate distinct sum subsets.
// And finally prints the generated subsets.
void printDistSum(int arr[], int n)
{
    unordered_set<int> s;
    distSumRec(arr, n, 0, 0, s);
  
    // Print the result
    for (auto i=s.begin(); i!=s.end(); i++)
        cout << *i << " ";
}
  
// Driver code
int main()
{
    int arr[] = {2, 3, 4, 5, 6};
    int n = sizeof(arr)/sizeof(arr[0]);
    printDistSum(arr, n);
    return 0;
}

Java

962
Chapter 129. Find all distinct subset (or subsequence) sums of an array

// Java program to print distinct


// subset sums of a given array.
import java.io.*;
import java.util.*;
  
class GFG 
{
    // sum denotes the current sum 
    // of the subset currindex denotes 
    // the index we have reached in
    // the given array
    static void distSumRec(int arr[], int n, int sum,
                          int currindex, HashSet<Integer> s)
    {
        if (currindex > n)
            return;
  
        if (currindex == n) {
            s.add(sum);
            return;
        }
  
        distSumRec(arr, n, sum + arr[currindex],
                    currindex + 1, s);
        distSumRec(arr, n, sum, currindex + 1, s);
    }
  
    // This function mainly calls 
    // recursive function distSumRec() 
    // to generate distinct sum subsets.
    // And finally prints the generated subsets.
    static void printDistSum(int arr[], int n)
    {
        HashSet<Integer> s = new HashSet<>();
        distSumRec(arr, n, 0, 0, s);
  
        // Print the result
        for (int i : s)
            System.out.print(i + " ");
    }
      
    //Driver code
    public static void main(String[] args)
    {
        int arr[] = { 2, 3, 4, 5, 6 };
        int n = arr.length;
        printDistSum(arr, n);
    }

963
Chapter 129. Find all distinct subset (or subsequence) sums of an array

}
  
// This code is contributed by Gitanjali.

Output:

0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20

Time complexity of the above naive recursive approach is O(2n ).


Time complexity of the above problem can be improved using Dynamic Programming,
especially when sum of given elements is small. We can make a dp table with rows
containing the size of the array and size of the column will be sum of all the elements in
the array.

C++

// C++ program to print distinct subset sums of


// a given array.
#include<bits/stdc++.h>
using namespace std;
  
// Uses Dynamic Programming to find distinct
// subset sums
void printDistSum(int arr[], int n)
{
    int sum = 0;
    for (int i=0; i<n; i++)
        sum += arr[i];
  
    // dp[i][j] would be true if arr[0..i-1] has
    // a subset with sum equal to j.
    bool dp[n+1][sum+1];
    memset(dp, 0, sizeof(dp));
  
    // There is always a subset with 0 sum
    for (int i=0; i<=n; i++)
        dp[i][0] = true;
  
    // Fill dp[][] in bottom up manner
    for (int i=1; i<=n; i++)
    {
        dp[i][arr[i-1]] = true;
        for (int j=1; j<=sum; j++)
        {

964
Chapter 129. Find all distinct subset (or subsequence) sums of an array

            // Sums that were achievable


            // without current array element
            if (dp[i-1][j] == true)
            {
                dp[i][j] = true;
                dp[i][j + arr[i-1]] = true;
            }
        }
    }
  
    // Print last row elements
    for (int j=0; j<=sum; j++)
        if (dp[n][j]==true)
            cout << j << " ";
}
  
  
// Driver code
int main()
{
    int arr[] = {2, 3, 4, 5, 6};
    int n = sizeof(arr)/sizeof(arr[0]);
    printDistSum(arr, n);
    return 0;
}

Java

// Java program to print distinct


// subset sums of a given array.
import java.io.*;
import java.util.*;
  
class GFG {
  
    // Uses Dynamic Programming to
    // find distinct subset sums
    static void printDistSum(int arr[], int n)
    {
        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
  
        // dp[i][j] would be true if arr[0..i-1] 
        // has a subset with sum equal to j.
        boolean[][] dp = new boolean[n + 1][sum + 1];
  
        // There is always a subset with 0 sum

965
Chapter 129. Find all distinct subset (or subsequence) sums of an array

        for (int i = 0; i <= n; i++)


            dp[i][0] = true;
  
        // Fill dp[][] in bottom up manner
        for (int i = 1; i <= n; i++) 
        {
            dp[i][arr[i - 1]] = true;
            for (int j = 1; j <= sum; j++) 
            {
                // Sums that were achievable
                // without current array element
                if (dp[i - 1][j] == true) 
                {
                    dp[i][j] = true;
                    dp[i][j + arr[i - 1]] = true;
                }
            }
        }
  
        // Print last row elements
        for (int j = 0; j <= sum; j++)
            if (dp[n][j] == true)
                System.out.print(j + " ");
    }
  
        // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 2, 3, 4, 5, 6 };
        int n = arr.length;
        printDistSum(arr, n);
    }
}
  
// This code is contributed by Gitanjali.

C#

// C# program to print distinct


// subset sums of a given array.
using System;
   
class GFG {
   
    // Uses Dynamic Programming to
    // find distinct subset sums
    static void printDistSum(int []arr, int n)
    {

966
Chapter 129. Find all distinct subset (or subsequence) sums of an array

        int sum = 0;
        for (int i = 0; i < n; i++)
            sum += arr[i];
   
        // dp[i][j] would be true if arr[0..i-1] 
        // has a subset with sum equal to j.
        bool [,]dp = new bool[n + 1,sum + 1];
   
        // There is always a subset with 0 sum
        for (int i = 0; i <= n; i++)
            dp[i,0] = true;
   
        // Fill dp[][] in bottom up manner
        for (int i = 1; i <= n; i++) 
        {
            dp[i,arr[i - 1]] = true;
            for (int j = 1; j <= sum; j++) 
            {
                // Sums that were achievable
                // without current array element
                if (dp[i - 1,j] == true) 
                {
                    dp[i,j] = true;
                    dp[i,j + arr[i - 1]] = true;
                }
            }
        }
   
        // Print last row elements
        for (int j = 0; j <= sum; j++)
            if (dp[n,j] == true)
                Console.Write(j + " ");
    }
   
    // Driver code
    public static void Main()
    {
        int []arr = { 2, 3, 4, 5, 6 };
        int n = arr.Length;
        printDistSum(arr, n);
    }
}
   
// This code is contributed by nitin mittal.

Output:

0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20

967
Chapter 129. Find all distinct subset (or subsequence) sums of an array

Time complexity of the above approach is O(n*sum) where n is the size of the array and
sum is the sum of all the integers in the array.
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/find-distinct-subset-subsequence-sums-array/

968
Chapter 130

Find all distinct subset (or


subsequence) sums of an array |
Set-2

Find all distinct subset (or subsequence) sums of an array | Set-2 - GeeksforGeeks
Given an array of N positive integers write an efficient function to find the sum of all those
integers which can be expressed as the sum of at least one subset of the given array i.e.
calculate total sum of each subset whose sum is distinct using only O(sum) extra space.
Examples:

Input: arr[] = {1, 2, 3}


Output: 0 1 2 3 4 5 6
Distinct subsets of given set are {}, {1}, {2}, {3}, {1, 2}, {2, 3}, {1, 3} and {1,
2, 3}. Sums of these subsets are 0, 1, 2, 3, 3, 5, 4, 6. After removing duplicates,
we get 0, 1, 2, 3, 4, 5, 6
Input: arr[] = {2, 3, 4, 5, 6}
Output: 0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20
Input: arr[] = {20, 30, 50}
Output: 0 20 30 50 70 80 100

A post using O(N*sum) and O(N*sum) space has been discussed in this post.
In this post, an approach using O(sum) space has been discussed. Create a single dp array
of O(sum) space and mark the dp[a[0]] as true and the rest as false. Iterate for all the array
elements in the array and then iterate from 1 to sum for each element in the array and
mark all the dp[j] with true that satisfies the condition (arr[i] == j || dp[j] || dp[(j –
arr[i])]). At the end print all the index that are marked true. Since arr[i]==j denotes the
subset with single element and dp[(j – arr[i])] denotes the subset with element j-arr[i].
Below is the implementation of the above approach.

969
Chapter 130. Find all distinct subset (or subsequence) sums of an array | Set-2

// C++ program to find total sum of


// all distinct subset sums in O(sum) space.
#include <bits/stdc++.h>
using namespace std;
  
// Function to print all th distinct sum
void subsetSum(int arr[], int n, int maxSum)
{
  
    // Declare a boolean array of size
    // equal to total sum of the array
    bool dp[maxSum + 1];
    memset(dp, false, sizeof dp);
  
    // Fill the first row beforehand
    dp[arr[0]] = true;
  
    // dp[j] will be true only if sum j
    // can be formed by any possible
    // addition of numbers in given array
    // upto index i, otherwise false
    for (int i = 1; i < n; i++) {
  
        // Iterate from maxSum to 1
        // and avoid lookup on any other row
        for (int j = maxSum + 1; j >= 1; j--) {
  
            // Do not change the dp array
            // for j less than arr[i]
            if (arr[i] <= j) {
                if (arr[i] == j || dp[j] || dp[(j - arr[i])])
                    dp[j] = true;
  
                else
                    dp[j] = false;
            }
        }
    }
  
    // If dp [j] is true then print
    cout << 0 << " ";
    for (int j = 0; j <= maxSum + 1; j++) {
        if (dp[j] == true)
            cout << j << " ";
    }
}
  
// Function to find the total sum

970
Chapter 130. Find all distinct subset (or subsequence) sums of an array | Set-2

// and print the distinct sum


void printDistinct(int a[], int n)
{
    int maxSum = 0;
  
    // find the sum of array elements
  
    for (int i = 0; i < n; i++) {
        maxSum += a[i];
    }
  
    // Function to print all the distinct sum
    subsetSum(a, n, maxSum);
}
  
// Driver Code
int main()
{
    int arr[] = { 2, 3, 4, 5, 6 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printDistinct(arr, n);
    return 0;
}

Output:

0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 21

Time complexity O(sum*n)


Auxiliary Space: O(sum)

Source

https://www.geeksforgeeks.org/find-all-distinct-subset-or-subsequence-sums-of-an-array-set-2/

971
Chapter 131

Find if string is K-Palindrome


or not | Set 1

Find if string is K-Palindrome or not | Set 1 - GeeksforGeeks


Given a string, find out if the string is K-Palindrome or not. A k-palindrome string trans-
forms into a palindrome on removing at most k characters from it.
Examples :

Input : String - abcdecba, k = 1


Output : Yes
String can become palindrome by remo-
-ving 1 character i.e. either d or e)

Input : String - abcdeca, K = 2


Output : Yes
Can become palindrome by removing
2 characters b and e.

Input : String - acdcb, K = 1


Output : No
String can not become palindrome by
removing only one character.

If we carefully analyze the problem, the task is to transform the given string into its reverse
by removing at most K characters from it. The problem is basically a variation of Edit
Distance. We can modify the Edit Distance problem to consider given string and its reverse
as input and only operation allowed is deletion. Since given string is compared with its
reverse, we will do at most N deletions from first string and N deletions from second string
to make them equal. Therefore, for a string to be k-palindrome, 2*N <= 2*K should hold

972
Chapter 131. Find if string is K-Palindrome or not | Set 1

true. Below are the detailed steps of algorithm - Process all characters one by one staring
from either from left or right sides of both strings. Let us traverse from the right corner,
there are two possibilities for every pair of character being traversed.

1. If last characters of two strings are same, we ignore last characters and get count for
remaining strings. So we recur for lengths m-1 and n-1 where m is length of str1 and
n is length of str2.
2. If last characters are not same, we consider remove operation on last character of first
string and last character of second string, recursively compute minimum cost for the
operations and take minimum of two values.
• Remove last char from str1: Recur for m-1 and n.
• Remove last char from str2: Recur for m and n-1.

Below is Naive recursive implementation of above approach.

C++

// A Naive recursive C++ program to find


// if given string is K-Palindrome or not
#include<bits/stdc++.h>
using namespace std;
  
// find if given string is K-Palindrome or not
int isKPalRec(string str1, string str2, int m, int n)
{
    // If first string is empty, the only option is to
    // remove all characters of second string
    if (m == 0) return n;
  
    // If second string is empty, the only option is to
    // remove all characters of first string
    if (n == 0) return m;
  
    // If last characters of two strings are same, ignore
    // last characters and get count for remaining strings.
    if (str1[m-1] == str2[n-1])
        return isKPalRec(str1, str2, m-1, n-1);
  
    // If last characters are not same,
    // 1. Remove last char from str1 and recur for m-1 and n
    // 2. Remove last char from str2 and recur for m and n-1
    // Take minimum of above two operations
    return 1 + min(isKPalRec(str1, str2, m-1, n), // Remove from str1
                   isKPalRec(str1, str2, m, n-1)); // Remove from str2
}
  

973
Chapter 131. Find if string is K-Palindrome or not | Set 1

// Returns true if str is k palindrome.


bool isKPal(string str, int k)
{
    string revStr = str;
    reverse(revStr.begin(), revStr.end());
    int len = str.length();
  
    return (isKPalRec(str, revStr, len, len) <= k*2);
}
  
// Driver program
int main()
{
    string str = "acdcb";
    int k = 2;
    isKPal(str, k)? cout << "Yes" : cout << "No";
    return 0;
}

Python3

# A Naive recursive Python3 


# code to find if given string
# is K-Palindrome or not
  
# Find if given string
# is K-Palindrome or not
def isKPalRec(str1, str2, m, n):
      
    # If first string is empty, 
    # the only option is to remove
    # all characters of second string
    if not m: return n
  
    # If second string is empty,
    # the only option is to remove
    # all characters of first string
    if not n: return m
  
    # If last characters of two strings
    # are same, ignore last characters
    # and get count for remaining strings.
    if str1[m-1] == str2[n-1]:
        return isKPalRec(str1, str2, m-1, n-1)
  
    # If last characters are not same,
    # 1. Remove last char from str1 and recur for m-1 and n
    # 2. Remove last char from str2 and recur for m and n-1

974
Chapter 131. Find if string is K-Palindrome or not | Set 1

    # Take minimum of above two operations


    res = 1 + min(isKPalRec(str1, str2, m-1, n),  # Remove from str1
                 (isKPalRec(str1, str2, m, n-1))) # Remove from str2
                   
    return res
  
# Returns true if str is k palindrome.
def isKPal(string, k):
    revStr = string[::-1]
    l = len(string)
  
    return (isKPalRec(string, revStr, l, l) <= k * 2)
  
  
# Driver program
string = "acdcb"
k = 2
  
print("Yes" if isKPal(string, k) else "No")
  
  
# This code is contributed by Ansu Kumari.

Output :

Yes

The time complexity of above solution is exponential. In worst case, we may end up doing
O(2n ) operations. The worst case happens string contains all distinct characters.
This problem has both properties (see this and this) of a dynamic programming problem.
Like other typical Dynamic Programming(DP) problems, re-computations of same subprob-
lems can be avoided by constructing a temporary array that stores results of subproblems
.
Below is Bottom-up implementation of above recursive approach :
C++

// C++ program to find if given string is K-Palindrome or not


#include <bits/stdc++.h>
using namespace std;
  
// find if given string is K-Palindrome or not
int isKPalDP(string str1, string str2, int m, int n)
{
    // Create a table to store results of subproblems
    int dp[m + 1][n + 1];
  

975
Chapter 131. Find if string is K-Palindrome or not | Set 1

    // Fill dp[][] in bottom up manner


    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            // If first string is empty, only option is to
            // remove all characters of second string
            if (i == 0)
                dp[i][j] = j; // Min. operations = j
  
            // If second string is empty, only option is to
            // remove all characters of first string
            else if (j == 0)
                dp[i][j] = i; // Min. operations = i
  
            // If last characters are same, ignore last character
            // and recur for remaining string
            else if (str1[i - 1] == str2[j - 1])
                dp[i][j] = dp[i - 1][j - 1];
  
            // If last character are different, remove it
            // and find minimum
            else
             dp[i][j] = 1 + min(dp[i - 1][j], // Remove from str1
                             dp[i][j - 1]); // Remove from str2
        }
    }
  
    return dp[m][n];
}
  
// Returns true if str is k palindrome.
bool isKPal(string str, int k)
{
    string revStr = str;
    reverse(revStr.begin(), revStr.end());
    int len = str.length();
  
    return (isKPalDP(str, revStr, len, len) <= k*2);
}
  
// Driver program
int main()
{
    string str = "acdcb";
    int k = 2;
    isKPal(str, k)? cout << "Yes" : cout << "No";
    return 0;

976
Chapter 131. Find if string is K-Palindrome or not | Set 1

Python3

# Python program to find if given


# string is K-Palindrome or not
  
# Find if given string is
# K-Palindrome or not
def isKPalDP(str1, str2, m, n):
      
    # Create a table to store
    # results of subproblems
    dp = [[0] * (n + 1) for _ in range(m + 1)]
  
    # Fill dp[][] in bottom up manner
    for i in range(m + 1):
          
        for j in range(n + 1):
              
            # If first string is empty,
            # only option is to remove
            # all characters of second string
            if not i :
                dp[i][j] = j    # Min. operations = j
  
            # If second string is empty,
            # only option is to remove
            # all characters of first string
            elif not j :
                dp[i][j] = i    # Min. operations = i
  
            # If last characters are same,
            # ignore last character and
            # recur for remaining string
            elif (str1[i - 1] == str2[j - 1]):
                dp[i][j] = dp[i - 1][j - 1]
  
            # If last character are different, 
            # remove it and find minimum
            else:
                dp[i][j] = 1 + min(dp[i - 1][j],  # Remove from str1
                                  (dp[i][j - 1])) # Remove from str2
  
    return dp[m][n]
  
# Returns true if str
# is k palindrome.

977
Chapter 131. Find if string is K-Palindrome or not | Set 1

def isKPal(string, k):


      
    revStr = string[::-1]
    l = len(string)
      
    return (isKPalDP(string, revStr, l, l) <= k * 2)
  
  
# Driver program
string = "acdcb"
k = 2
print("Yes" if isKPal(string, k) else "No")
  
  
# This code is contributed by Ansu Kumari.

Output :

Yes

Time complexity of above solution is O(m x n). We can improve time complexity by making
use of the fact that only k deletions are allowed. Auxiliary space used is O(m x n).
Find if string is K-Palindrome or not | Set 2 (Using LCS)

Source

https://www.geeksforgeeks.org/find-if-string-is-k-palindrome-or-not/

978
Chapter 132

Find if string is K-Palindrome


or not | Set 2

Find if string is K-Palindrome or not | Set 2 - GeeksforGeeks


Given a string, find out if the string is K-Palindrome or not. A K-palindrome string trans-
forms into a palindrome on removing at most k characters from it.
Examples:

Input : String - abcdecba, k = 1


Output : Yes
String can become palindrome by removing
1 character i.e. either d or e

Input : String - abcdeca, K = 2


Output : Yes
Can become palindrome by removing
2 characters b and e (or b and d).

Input : String - acdcb, K = 1


Output : No
String can not become palindrome by
removing only one character.

We have discussed a DP solution in previous post where we saw that the problem is basically
a variation of Edit Distance problem. In this post, another interesting DP solution is
discussed.
The idea is to find the longest palindromic subsequence of the given string. If the difference
between longest palindromic subsequence and the original string is less than equal to k, then
the string is k-palindrome else it is not k-palindrome.

979
Chapter 132. Find if string is K-Palindrome or not | Set 2

For example, longest palindromic subsequence of string abcdeca is acdca(or aceca). The
characters which do not contribute to longest palindromic subsequence of the string should
be removed in order to make the string palindrome. So on removing b and d (or e) from
abcdeca, string will transform into a palindrome.
Longest palindromic subsequence of a string can easily be found using LCS. Following is the
two step solution for finding longest palindromic subsequence that uses LCS.

1. Reverse the given sequence and store the reverse in another array say rev[0..n-1]
2. LCS of the given sequence and rev[] will be the longest palindromic sequence.

Below is C++ implementation of above idea –


CPP

// C++ program to find if given string is K-Palindrome


// or not
#include <bits/stdc++.h>
using namespace std;
  
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int lcs( string X, string Y, int m, int n )
{
    int L[m + 1][n + 1];
  
    /* Following steps build L[m+1][n+1] in bottom up
        fashion. Note that L[i][j] contains length of
        LCS of X[0..i-1] and Y[0..j-1] */
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
            else if (X[i - 1] == Y[j - 1])
                L[i][j] = L[i - 1][j - 1] + 1;
            else
                L[i][j] = max(L[i - 1][j], L[i][j - 1]);
        }
    }
    // L[m][n] contains length of LCS for X and Y
    return L[m][n];
}
  
// find if given string is K-Palindrome or not
bool isKPal(string str, int k)
{
    int n = str.length();

980
Chapter 132. Find if string is K-Palindrome or not | Set 2

  
    // Find reverse of string
    string revStr = str;
    reverse(revStr.begin(), revStr.end());
  
    // find longest palindromic subsequence of
    // given string
    int lps = lcs(str, revStr, n, n);
  
    // If the difference between longest palindromic
    // subsequence and the original string is less
    // than equal to k, then the string is k-palindrome
    return (n - lps <= k);
}
  
// Driver program
int main()
{
    string str = "abcdeca";
    int k = 2;
    isKPal(str, k) ? cout << "Yes" : cout << "No";
  
    return 0;
}

Python3

# Python program to find


# if given string is K-Palindrome
# or not
  
# Returns length of LCS
# for X[0..m-1], Y[0..n-1] 
def lcs(X, Y, m, n ):
  
    L = [[0]*(n+1) for _ in range(m+1)]
  
    # Following steps build
        # L[m+1][n+1] in bottom up
        # fashion. Note that L[i][j]
        # contains length of
    # LCS of X[0..i-1] and Y[0..j-1] 
    for i in range(m+1):
        for j in range(n+1):
            if not i or not j:
                L[i][j] = 0
            elif X[i - 1] == Y[j - 1]:
                L[i][j] = L[i - 1][j - 1] + 1

981
Chapter 132. Find if string is K-Palindrome or not | Set 2

            else:
                L[i][j] = max(L[i - 1][j], L[i][j - 1])
  
    # L[m][n] contains length
        # of LCS for X and Y
    return L[m][n]
  
# find if given string is
# K-Palindrome or not
def isKPal(string, k):
  
    n = len(string)
  
    # Find reverse of string
    revStr = string[::-1]
  
    # find longest palindromic
        # subsequence of
    # given string
    lps = lcs(string, revStr, n, n)
  
    # If the difference between
        # longest palindromic
    # subsequence and the original
        # string is less
    # than equal to k, then
        # the string is k-palindrome
    return (n - lps <= k)
  
# Driver program
string = "abcdeca"
k = 2
  
print("Yes" if isKPal(string, k) else "No")
  
# This code is contributed
# by Ansu Kumari.

Output:

Yes

Time complexity of above solution is O(n2 ).


Auxiliary space used by the program is O(n2 ). It can further be reduced to O(n) by using
Space Optimized Solution of LCS.
Thanks to Ravi Teja Kaveti for suggesting above solution.

982
Chapter 132. Find if string is K-Palindrome or not | Set 2

Source

https://www.geeksforgeeks.org/find-if-string-is-k-palindrome-or-not-set-2/

983
Chapter 133

Find length of longest


subsequence of one string which
is substring of another string

Find length of longest subsequence of one string which is substring of another string -
GeeksforGeeks
Given two string X and Y. The task is to find the length of longest subsequence of string
X which is substring in sequence Y.
Examples:

Input : X = "ABCD", Y = "BACDBDCD"


Output : 3
"ACD" is longest subsequence of X which
is substring of Y.

Input : X = "A", Y = "A"


Output : 1

Method 1 (Brute Force):


Use brute force to find all the subsequence of X and for each subsequence check whether
it is substring of Y or not. If it is substring of Y, maintain a maximum length varible and
compare length with it.
Method 2: (Dynamic Programming):
Let n be length of X and m be length of Y. Create a 2D array ‘dp[][]’ of m + 1 rows and n +
1 columns. Value dp[i][j] is maximum length of subsequence of X[0….j] which is substring
of Y[0….i]. Now for each cell of dp[][] fill value as :

984
Chapter 133. Find length of longest subsequence of one string which is substring of
another string

for (i = 1 to m)
for (j = 1 to n)
if (x[i-1] == y[j - 1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = dp[i][j-1];

And finally, the length of the longest subsequence of x which is substring of y is max(dp[i][n])
where 1 <= i <= m.
Below is implementation this approach:
C/C++

// C++ program to find maximum length of


// subsequence of a string X such it is
// substring in another string Y.
#include <bits/stdc++.h>
#define MAX 1000
using namespace std;
  
// Return the maximum size of substring of
// X which is substring in Y.
int maxSubsequenceSubstring(char x[], char y[],
                            int n, int m)
{
    int dp[MAX][MAX];
  
    // Initialize the dp[][] to 0.
    for (int i = 0; i <= m; i++)
        for (int j = 0; j <= n; j++)
            dp[i][j] = 0;
  
    // Calculating value for each element.
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
  
            // If alphabet of string X and Y are
            // equal make dp[i][j] = 1 + dp[i-1][j-1]
            if (x[j - 1] == y[i - 1])
                dp[i][j] = 1 + dp[i - 1][j - 1];
  
            // Else copy the previous value in the
            // row i.e dp[i-1][j-1]
            else
                dp[i][j] = dp[i][j - 1];
        }
    }
  

985
Chapter 133. Find length of longest subsequence of one string which is substring of
another string

    // Finding the maximum length.


    int ans = 0;
    for (int i = 1; i <= m; i++)
        ans = max(ans, dp[i][n]);
  
    return ans;
}
  
// Driver Program
int main()
{
    char x[] = "ABCD";
    char y[] = "BACDBDCD";
    int n = strlen(x), m = strlen(y);
    cout << maxSubsequenceSubstring(x, y, n, m);
    return 0;
}

Java

// Java program to find maximum length of


// subsequence of a string X such it is
// substring in another string Y.
  
public class GFG 
{
    static final int MAX = 1000;
      
    // Return the maximum size of substring of
    // X which is substring in Y.
    static int maxSubsequenceSubstring(char x[], char y[],
                                int n, int m)
    {
        int dp[][] = new int[MAX][MAX];
       
        // Initialize the dp[][] to 0.
        for (int i = 0; i <= m; i++)
            for (int j = 0; j <= n; j++)
                dp[i][j] = 0;
       
        // Calculating value for each element.
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
       
                // If alphabet of string X and Y are
                // equal make dp[i][j] = 1 + dp[i-1][j-1]
                if (x[j - 1] == y[i - 1])
                    dp[i][j] = 1 + dp[i - 1][j - 1];

986
Chapter 133. Find length of longest subsequence of one string which is substring of
another string

       
                // Else copy the previous value in the
                // row i.e dp[i-1][j-1]
                else
                    dp[i][j] = dp[i][j - 1];
            }
        }
       
        // Finding the maximum length.
        int ans = 0;
        for (int i = 1; i <= m; i++)
            ans = Math.max(ans, dp[i][n]);
       
        return ans;
    }
      
    // Driver Method
    public static void main(String[] args)
    {
        char x[] = "ABCD".toCharArray();
        char y[] = "BACDBDCD".toCharArray();
        int n = x.length, m = y.length;
        System.out.println(maxSubsequenceSubstring(x, y, n, m));
    }
}

C#

// C# program to find maximum length of


// subsequence of a string X such it is
// substring in another string Y.
using System;
  
public class GFG 
{
    static int MAX = 1000;
      
    // Return the maximum size of substring of
    // X which is substring in Y.
    static int maxSubsequenceSubstring(string x, string y,
                                            int n, int m)
    {
        int[ ,]dp = new int[MAX, MAX];
      
        // Initialize the dp[][] to 0.
        for (int i = 0; i <= m; i++)
            for (int j = 0; j <= n; j++)
                dp[i, j] = 0;

987
Chapter 133. Find length of longest subsequence of one string which is substring of
another string

      
        // Calculating value for each element.
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
      
                // If alphabet of string X and Y are
                // equal make dp[i][j] = 1 + dp[i-1][j-1]
                if (x[j - 1] == y[i - 1])
                    dp[i, j] = 1 + dp[i - 1, j - 1];
      
                // Else copy the previous value in the
                // row i.e dp[i-1][j-1]
                else
                    dp[i, j] = dp[i, j - 1];
            }
        }
      
        // Finding the maximum length.
        int ans = 0;
          
        for (int i = 1; i <= m; i++)
            ans = Math.Max(ans, dp[i,n]);
      
        return ans;
    }
      
    // Driver Method
    public static void Main()
    {
        string x = "ABCD";
        string y = "BACDBDCD";
        int n = x.Length, m = y.Length;
          
        Console.WriteLine(maxSubsequenceSubstring(x,
                                            y, n, m));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to find maximum length of
// subsequence of a string X such it is
// substring in another string Y.
  
// Return the maximum size of substring of

988
Chapter 133. Find length of longest subsequence of one string which is substring of
another string

// X which is substring in Y.
function maxSubsequenceSubstring($x, $y,
                                 $n, $m)
{
    $dp;
  
    // Initialize the dp[][] to 0.
    for ($i = 0; $i <= $m; $i++)
        for ($j = 0; $j <= $n; $j++)
            $dp[$i][$j] = 0;
  
    // Calculating value for each element.
    for ($i = 1; $i <= $m; $i++) {
        for ( $j = 1; $j <= $n; $j++) {
  
            // If alphabet of string
            // X and Y are equal make
            // dp[i][j] = 1 + dp[i-1][j-1]
            if ($x[$j - 1] == $y[$i - 1])
                $dp[$i][$j] = 1 + $dp[$i - 1][$j - 1];
  
            // Else copy the previous
            // value in the
            // row i.e dp[i-1][j-1]
            else
                $dp[$i][$j] = $dp[$i][$j - 1];
        }
    }
  
    // Finding the maximum length.
    $ans = 0;
    for ( $i = 1; $i <= $m; $i++)
        $ans = max($ans, $dp[$i][$n]);
  
    return $ans;
}
  
// Driver Code
{
    $x = "ABCD";
    $y = "BACDBDCD";
    $n = strlen($x); $m = strlen($y);
    echo maxSubsequenceSubstring($x, $y, $n, $m);
    return 0;
}
  
// This code is contributed by nitin mittal
?>

989
Chapter 133. Find length of longest subsequence of one string which is substring of
another string

Output:

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/find-length-longest-subsequence-one-string-substring-another-string/

990
Chapter 134

Find length of the longest


consecutive path from a given
starting character

Find length of the longest consecutive path from a given starting character - GeeksforGeeks
Given a matrix of characters. Find length of the longest path from a given character, such
that all characters in the path are consecutive to each other, i.e., every character in path is
next to previous in alphabetical order. It is allowed to move in all 8 directions from a cell.

Example

991
Chapter 134. Find length of the longest consecutive path from a given starting character

Input: mat[][] = { {a, c, d},


{h, b, e},
{i, g, f}}
Starting Point = 'e'

Output: 5
If starting point is 'e', then longest path with consecutive
characters is "e f g h i".

Input: mat[R][C] = { {b, e, f},


{h, d, a},
{i, c, a}};
Starting Point = 'b'

Output: 1
'c' is not present in all adjacent cells of 'b'

We strongly recommend you to minimize your browser and try this yourself
first.
The idea is to first search given starting character in the given matrix. Do Depth First
Search (DFS) from all occurrences to find all consecutive paths. While doing DFS, we may
encounter many subproblems again and again. So we use dynamic programming to store
results of subproblems.
Below is the implementation of above idea.

C++

// C++ program to find the longest consecutive path


#include<bits/stdc++.h>
#define R 3
#define C 3
using namespace std;
  
// tool matrices to recur for adjacent cells.
int x[] = {0, 1, 1, -1, 1, 0, -1, -1};
int y[] = {1, 0, 1, 1, -1, -1, 0, -1};
  
// dp[i][j] Stores length of longest consecutive path
// starting at arr[i][j].
int dp[R][C];
  
// check whether mat[i][j] is a valid cell or not.
bool isvalid(int i, int j)
{
    if (i < 0 || j < 0 || i >= R || j >= C)

992
Chapter 134. Find length of the longest consecutive path from a given starting character

      return false;
    return true;
}
  
// Check whether current character is adjacent to previous
// character (character processed in parent call) or not.
bool isadjacent(char prev, char curr)
{
    return ((curr - prev) == 1);
}
  
// i, j are the indices of the current cell and prev is the
// character processed in the parent call.. also mat[i][j]
// is our current character.
int getLenUtil(char mat[R][C], int i, int j, char prev)
{
     // If this cell is not valid or current character is not
     // adjacent to previous one (e.g. d is not adjacent to b )
     // or if this cell is already included in the path than return 0.
    if (!isvalid(i, j) || !isadjacent(prev, mat[i][j]))
         return 0;
  
    // If this subproblem is already solved , return the answer
    if (dp[i][j] != -1)
        return dp[i][j];
  
    int ans = 0;  // Initialize answer
  
    // recur for paths with differnt adjacent cells and store
    // the length of longest path.
    for (int k=0; k<8; k++)
      ans = max(ans, 1 + getLenUtil(mat, i + x[k],
                                   j + y[k], mat[i][j]));
  
    // save the answer and return
    return dp[i][j] = ans;
}
  
// Returns length of the longest path with all characters consecutive
// to each other.  This function first initializes dp array that
// is used to store results of subproblems, then it calls
// recursive DFS based function getLenUtil() to find max length path
int getLen(char mat[R][C], char s)
{
    memset(dp, -1, sizeof dp);
    int ans = 0;
  
    for (int i=0; i<R; i++)

993
Chapter 134. Find length of the longest consecutive path from a given starting character

    {
        for (int j=0; j<C; j++)
        {
            // check for each possible starting point
            if (mat[i][j] == s) {
  
                // recur for all eight adjacent cells
                for (int k=0; k<8; k++)
                  ans = max(ans, 1 + getLenUtil(mat,
                                    i + x[k], j + y[k], s));
            }
        }
    }
    return ans;
}
  
// Driver program
int main() {
  
    char mat[R][C] = { {'a','c','d'},
                     { 'h','b','a'},
                     { 'i','g','f'}};
  
    cout << getLen(mat, 'a') << endl;
    cout << getLen(mat, 'e') << endl;
    cout << getLen(mat, 'b') << endl;
    cout << getLen(mat, 'f') << endl;
    return 0;
}

Java

class path
{
    // tool matrices to recur for adjacent cells.
    static int x[] = {0, 1, 1, -1, 1, 0, -1, -1};
    static int y[] = {1, 0, 1, 1, -1, -1, 0, -1};
    static int R = 3;
    static int C = 3;
    // dp[i][j] Stores length of longest consecutive path
    // starting at arr[i][j].
    static int dp[][] = new int[R][C];
       
    // check whether mat[i][j] is a valid cell or not.
    static boolean isvalid(int i, int j)
    {
        if (i < 0 || j < 0 || i >= R || j >= C)
          return false;

994
Chapter 134. Find length of the longest consecutive path from a given starting character

        return true;
    }
       
    // Check whether current character is adjacent to previous
    // character (character processed in parent call) or not.
    static boolean isadjacent(char prev, char curr)
    {
        return ((curr - prev) == 1);
    }
       
    // i, j are the indices of the current cell and prev is the
    // character processed in the parent call.. also mat[i][j]
    // is our current character.
    static int getLenUtil(char mat[][], int i, int j, char prev)
    {
         // If this cell is not valid or current character is not
         // adjacent to previous one (e.g. d is not adjacent to b )
         // or if this cell is already included in the path than return 0.
        if (!isvalid(i, j) || !isadjacent(prev, mat[i][j]))
             return 0;
       
        // If this subproblem is already solved , return the answer
        if (dp[i][j] != -1)
            return dp[i][j];
       
        int ans = 0;  // Initialize answer
       
        // recur for paths with differnt adjacent cells and store
        // the length of longest path.
        for (int k=0; k<8; k++)
          ans = Math.max(ans, 1 + getLenUtil(mat, i + x[k],
                                       j + y[k], mat[i][j]));
       
        // save the answer and return
        return dp[i][j] = ans;
    }
       
    // Returns length of the longest path with all characters consecutive
    // to each other.  This function first initializes dp array that
    // is used to store results of subproblems, then it calls
    // recursive DFS based function getLenUtil() to find max length path
    static int getLen(char mat[][], char s)
    {
        //assigning all dp values to -1
        for(int i = 0;i<R;++i)
            for(int j = 0;j<C;++j)
                dp[i][j] = -1;
          

995
Chapter 134. Find length of the longest consecutive path from a given starting character

        int ans = 0;
       
        for (int i=0; i<R; i++)
        {
            for (int j=0; j<C; j++)
            {
                // check for each possible starting point
                if (mat[i][j] == s) {
       
                    // recur for all eight adjacent cells
                    for (int k=0; k<8; k++)
                      ans = Math.max(ans, 1 + getLenUtil(mat,
                                        i + x[k], j + y[k], s));
                }
            }
        }
        return ans;
    }
    public static void main(String args[])
    {
        char mat[][] = { {'a','c','d'},
                           { 'h','b','a'},
                           { 'i','g','f'}};
   
        System.out.println(getLen(mat, 'a') );
        System.out.println(getLen(mat, 'e') );
        System.out.println(getLen(mat, 'b') );
        System.out.println(getLen(mat, 'f') );
    }
}/* This code is contributed by Rajat Mishra */

C#

// C# program to find the longest consecutive path


using System;
  
class GFG {
      
    // tool matrices to recur for adjacent cells.
    static int []x = {0, 1, 1, -1, 1, 0, -1, -1};
    static int []y = {1, 0, 1, 1, -1, -1, 0, -1};
    static int R = 3;
    static int C = 3;
      
    // dp[i][j] Stores length of longest 
    // consecutive path starting at arr[i][j].
    static int [,]dp = new int[R,C];
      

996
Chapter 134. Find length of the longest consecutive path from a given starting character

    // check whether mat[i][j] is a valid


    // cell or not.
    static bool isvalid(int i, int j)
    {
        if (i < 0 || j < 0 || i >= R || j >= C)
            return false;
        return true;
    }
      
    // Check whether current character is 
    // adjacent to previous character 
    // (character processed in parent call)
    // or not.
    static bool isadjacent(char prev, char curr)
    {
        return ((curr - prev) == 1);
    }
      
    // i, j are the indices of the current
    // cell and prev is the character processed
    // in the parent call.. also mat[i][j]
    // is our current character.
    static int getLenUtil(char [,]mat, int i,
                                int j, char prev)
    {
          
        // If this cell is not valid or current
        // character is not adjacent to previous
        // one (e.g. d is not adjacent to b )
        // or if this cell is already included
        // in the path than return 0.
        if (!isvalid(i, j) || !isadjacent(prev, 
                                       mat[i,j]))
            return 0;
      
        // If this subproblem is already solved,
        // return the answer
        if (dp[i,j] != -1)
            return dp[i,j];
      
        int ans = 0; // Initialize answer
      
        // recur for paths with differnt adjacent
        // cells and store the length of 
        // longest path.
        for (int k = 0; k < 8; k++)
        ans = Math.Max(ans, 1 + getLenUtil(mat,
                   i + x[k], j + y[k], mat[i,j]));

997
Chapter 134. Find length of the longest consecutive path from a given starting character

      
        // save the answer and return
        return dp[i,j] = ans;
    }
      
    // Returns length of the longest path
    // with all characters consecutive to
    // each other. This function first 
    // initializes dp array that is used
    // to store results of subproblems, 
    // then it calls recursive DFS based
    // function getLenUtil() to find max
    // length path
    static int getLen(char [,]mat, char s)
    {
          
        //assigning all dp values to -1
        for(int i = 0; i < R; ++i)
            for(int j = 0; j < C; ++j)
                dp[i,j] = -1;
          
        int ans = 0;
      
        for (int i=0; i<R; i++)
        {
            for (int j=0; j<C; j++)
            {
                  
                // check for each possible
                // starting point
                if (mat[i,j] == s) {
      
                    // recur for all eight 
                    // adjacent cells
                    for (int k = 0; k < 8; k++)
                        ans = Math.Max(ans, 1 + 
                             getLenUtil(mat, i + 
                             x[k], j + y[k], s));
                }
            }
        }
        return ans;
    }
      
    // Driver code`
    public static void Main()
    {
        char [,]mat = { {'a','c','d'},

998
Chapter 134. Find length of the longest consecutive path from a given starting character

                        { 'h','b','a'},
                        { 'i','g','f'}};
  
        Console.WriteLine(getLen(mat, 'a') );
        Console.WriteLine(getLen(mat, 'e') );
        Console.WriteLine(getLen(mat, 'b') );
        Console.WriteLine(getLen(mat, 'f') );
    }
}
  
// This code is contributed by nitin mittal.

Output:

4
0
3
4

Thanks to Gaurav Ahirwar for above solution.


Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/find-length-of-the-longest-consecutive-path-in-a-character-matrix/

999
Chapter 135

Find longest bitonic sequence


such that increasing and
decreasing parts are from two
different arrays

Find longest bitonic sequence such that increasing and decreasing parts are from two differ-
ent arrays - GeeksforGeeks
We are given two arrays, we need to find the longest possiblebitonic sequence such that
increasing part must be from first array and should be a subsequence of first array. Similarly,
decreasing part of must be from second array and should be a subsequence of it.
Examples:

Input : arr1[] = {1, 5, 2, 4, 3, 5},


arr2[] = {8, 6, 4, 7, 3, 2}
Output : 1, 2, 4, 5, 8, 6, 4, 3, 2

Input : arr1[] = {2, 0, 1, 3, 4},


arr2[] = {5, 3, 2, 1}
Output : 0, 1, 2, 3, 4, 5, 3, 2, 1

The idea is to use largest increasing sequence from array1 and largest decreasing sequence
from array2 and then combine both to get our result.

// CPP to find largest bitonic sequence such that


#include <bits/stdc++.h>
using namespace std;

1000
Chapter 135. Find longest bitonic sequence such that increasing and decreasing parts are
from two different arrays

  
vector<int> res;
  
// utility Binary search
int GetCeilIndex(int arr[], vector<int>& T, int l, 
                                   int r, int key)
{
    while (r - l > 1) {
        int m = l + (r - l) / 2;
        if (arr[T[m]] >= key)
            r = m;
        else
            l = m;
    }
    return r;
}
  
// function to find LIS in reverse form
void LIS(int arr[], int n)
{
    // Add boundary case, when array n is zero
    // Depend on smart pointers
    vector<int> tailIndices(n, 0); // Initialized with 0
    vector<int> prevIndices(n, -1); // initialized with -1
  
    int len = 1; // it will always point to empty location
    for (int i = 1; i < n; i++) {
  
        // new smallest value
        if (arr[i] < arr[tailIndices[0]])             
            tailIndices[0] = i;
  
        // arr[i] wants to extend largest subsequence
        else if (arr[i] > arr[tailIndices[len - 1]]) {            
            prevIndices[i] = tailIndices[len - 1];
            tailIndices[len++] = i;
        } 
           
        // arr[i] wants to be a potential candidate of
        // future subsequence
        // It will replace ceil value in tailIndices
        else {
            int pos = GetCeilIndex(arr, tailIndices, -1, 
                                        len - 1, arr[i]);
            prevIndices[i] = tailIndices[pos - 1];
            tailIndices[pos] = i;
        }
    }

1001
Chapter 135. Find longest bitonic sequence such that increasing and decreasing parts are
from two different arrays

  
    // put LIS into vector
    for (int i = tailIndices[len - 1]; i >= 0; i = prevIndices[i])
        res.push_back(arr[i]);
}
  
// function for finding longest bitonic seq
void longestBitonic(int arr1[], int n1, int arr2[], int n2)
{
    // find LIS of array 1 in reverse form
    LIS(arr1, n1);
  
    // reverse res to get LIS of first array
    reverse(res.begin(), res.end());
  
    // reverse array2 and find its LIS
    reverse(arr2, arr2 + n2);
    LIS(arr2, n2);
  
    // print result
    for (int i = 0; i < res.size(); i++)
        cout << res[i] << " ";
}
  
// driver preogram
int main()
{
    int arr1[] = { 1, 2, 4, 3, 2 };
    int arr2[] = { 8, 6, 4, 7, 8, 9 };
    int n1 = sizeof(arr1) / sizeof(arr1[0]);
    int n2 = sizeof(arr2) / sizeof(arr2[0]);
    longestBitonic(arr1, n1, arr2, n2);
    return 0;
}

Output:

1 2 3 8 6 4

Time Complexity : O(n Log n)


Please note that O(n Log n) implementation of LIS is used
Improved By : freeman1

Source
https://www.geeksforgeeks.org/find-longest-bitonic-sequence-increasing-decreasing-parts-two-different-arrays/

1002
Chapter 136

Find maximum length Snake


sequence

Find maximum length Snake sequence - GeeksforGeeks


Given a grid of numbers, find maximum length Snake sequence and print it. If multiple
snake sequences exists with the maximum length, print any one of them.
A snake sequence is made up of adjacent numbers in the grid such that for each number,
the number on the right or the number below it is +1 or -1 its value. For example, if you
are at location (x, y) in the grid, you can either move right i.e. (x, y+1) if that number is ±
1 or move down i.e. (x+1, y) if that number is ± 1.
For example,
9, 6, 5, 2
8, 7, 6, 5
7, 3, 1, 6
1, 1, 1, 7
In above grid, the longest snake sequence is: (9, 8, 7, 6, 5, 6, 7)
Below figure shows all possible paths –

1003
Chapter 136. Find maximum length Snake sequence

We strongly recommend you to minimize your browser and try this yourself
first.
The idea is to use Dynamic Programming. For each cell of the matrix, we keep maximum
length of a snake which ends in current cell. The maximum length snake sequence will have
maximum value. The maximum value cell will correspond to tail of the snake. In order to
print the snake, we need to backtrack from tail all the way back to snake’s head.
Let T[i][i] represent maximum length of a snake which ends at cell (i, j), then for given
matrix M, the DP relation is defined as –
T[0][0] = 0
T[i][j] = max(T[i][j], T[i][j – 1] + 1) if M[i][j] = M[i][j – 1] ± 1
T[i][j] = max(T[i][j], T[i – 1][j] + 1) if M[i][j] = M[i – 1][j] ± 1
Below is C++ implementation of the idea –

CPP

// C++ program to find maximum length


// Snake sequence and print it
#include <bits/stdc++.h>
using namespace std;
#define M 4
#define N 4
  
struct Point
{
    int x, y;
};
  
// Function to find maximum length Snake sequence path
// (i, j) corresponds to tail of the snake
list<Point> findPath(int grid[M][N], int mat[M][N],
                     int i, int j)
{

1004
Chapter 136. Find maximum length Snake sequence

    list<Point> path;
  
    Point pt = {i, j};
    path.push_front(pt);
  
    while (grid[i][j] != 0)
    {
       if (i > 0 &&
           grid[i][j] - 1 == grid[i - 1][j])
       {
           pt = {i - 1, j};
           path.push_front(pt);
           i--;
       }
       else if (j > 0 &&
                grid[i][j] - 1 == grid[i][j - 1])
       {
           pt = {i, j - 1};
           path.push_front(pt);
           j--;
       }
    }
  
    return path;
}
  
// Function to find maximum length Snake sequence
void findSnakeSequence(int mat[M][N])
{
    // table to store results of subproblems
    int lookup[M][N];
  
    // initialize by 0
    memset(lookup, 0, sizeof lookup);
  
    // stores maximum length of Snake sequence
    int max_len = 0;
  
    // store cordinates to snake's tail
    int max_row = 0;
    int max_col = 0;
  
    // fill the table in bottom-up fashion
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            // do except for (0, 0) cell

1005
Chapter 136. Find maximum length Snake sequence

            if (i || j)
            {
                // look above
                if (i > 0 &&
                    abs(mat[i - 1][j] - mat[i][j]) == 1)
                {
                    lookup[i][j] = max(lookup[i][j],
                               lookup[i - 1][j] + 1);
  
                    if (max_len < lookup[i][j])
                    {
                        max_len = lookup[i][j];
                        max_row = i, max_col = j;
                    }
                }
  
                // look left
                if (j > 0 &&
                    abs(mat[i][j - 1] - mat[i][j]) == 1)
                {
                    lookup[i][j] = max(lookup[i][j],
                                       lookup[i][j - 1] + 1);
                    if (max_len < lookup[i][j])
                    {
                        max_len = lookup[i][j];
                        max_row = i, max_col = j;
                    }
                }
            }
        }
    }
  
    cout << "Maximum length of Snake sequence is: "
         << max_len << endl;
  
    // find maximum length Snake sequence path
    list<Point> path = findPath(lookup, mat, max_row,
                                             max_col);
  
    cout << "Snake sequence is:";
    for (auto it = path.begin(); it != path.end(); it++)
        cout << endl << mat[it->x][it->y] << " ("
             << it->x << ", " << it->y << ")" ;
}
  
// Driver code
int main()
{

1006
Chapter 136. Find maximum length Snake sequence

    int mat[M][N] =
    {
        {9, 6, 5, 2},
        {8, 7, 6, 5},
        {7, 3, 1, 6},
        {1, 1, 1, 7},
    };
  
    findSnakeSequence(mat);
  
    return 0;
}

Python3

# Python program to find maximum length


# Snake sequence and print it
  
M = 4
N = 4
  
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
  
# Function to find maximum length Snake sequence path
# (i, j) corresponds to tail of the snake
def findPath(grid, mat, i, j):
    path = list()
  
    pt = Point(i, j)
    path.append(pt)
  
    while (grid[i][j] != 0):
        if (i > 0 and grid[i][j]-1 == grid[i-1][j]):
            pt = Point(i-1, j)
            path.append(pt)
            i -= 1
        elif (j > 0 and grid[i][j]-1 == grid[i][j-1]):
            pt = Point(i, j-1)
            path.append(pt)
            j -= 1
    return path
  
# Function to find maximum length Snake sequence
def findSnakeSequence(mat):
  

1007
Chapter 136. Find maximum length Snake sequence

    # table to store results of subproblems


    # initialize by 0
    lookup = [[0 for i in range(N)] for j in range(M)]
  
    # stores maximum length of Snake sequence
    max_len = 0
  
    # store cordinates to snake's tail
    max_row = 0
    max_col = 0
  
    # fill the table in bottom-up fashion
    for i in range(M):
        for j in range(N):
            # do except for (0, 0) cell
            if (i or j):
                # look above
                if (i > 0 and
                    abs(mat[i-1][j] - mat[i][j]) == 1):
                    lookup[i][j] = max(lookup[i][j],
                                       lookup[i-1][j] + 1)
                    if (max_len < lookup[i][j]):
                        max_len = lookup[i][j]
                        max_row = i
                        max_col = j
  
                # look left
                if (j > 0 and
                    abs(mat[i][j-1] - mat[i][j]) == 1):
                    lookup[i][j] = max(lookup[i][j],
                                       lookup[i][j-1] + 1)
                    if (max_len < lookup[i][j]):
                        max_len = lookup[i][j]
                        max_row = i
                        max_col = j
  
    print("Maximum length of Snake sequence is:", max_len)
  
    # find maximum length Snake sequence path
    path = findPath(lookup, mat, max_row, max_col)
  
    print("Snake sequence is:")
    for ele in reversed(path):
        print(mat[ele.x][ele.y],
              " (", ele.x, ", ", ele.y, ")", sep = "")
  
# Driver code
mat = [[9, 6, 5, 2],

1008
Chapter 136. Find maximum length Snake sequence

       [8, 7, 6, 5],
       [7, 3, 1, 6],
       [1, 1, 1, 7]]
  
findSnakeSequence(mat)
  
# This code is contributed
# by Soumen Ghosh

Output :

Maximum length of Snake sequence is: 6


Snake sequence is:
9 (0, 0)
8 (1, 0)
7 (1, 1)
6 (1, 2)
5 (1, 3)
6 (2, 3)
7 (3, 3)

Time complexity of above solution is O(M*N). Auxiliary space used by above solution is
O(M*N). If we are not required to print the snake, space can be further reduced to O(N)
as we only uses the result from last row.
Reference: Stack Overflow

Source

https://www.geeksforgeeks.org/find-maximum-length-snake-sequence/

1009
Chapter 137

Find maximum possible stolen


value from houses

Find maximum possible stolen value from houses - GeeksforGeeks


There are n houses build in a line, each of which contains some value in it. A thief is
going to steal the maximal value of these houses, but he can’t steal in two adjacent houses
because owner of the stolen houses will tell his two neighbour left and right side. What is
the maximum stolen value.
Examples:

Input : hval[] = {6, 7, 1, 3, 8, 2, 4}


Output : 19
Thief will steal 6, 1, 8 and 4 from house.

Input : hval[] = {5, 3, 4, 11, 2}


Output : 16
Thief will steal 5 and 11

While reaching house i thief has two options, either he robs it or leave it. Let dp[i] represents
the maximum value stolen so far on reaching house i. We can calculate the value of dp[i] as
following –

dp[i] = max (hval[i] + dp[i-2], dp[i-1])

hval[i] + dp[i-2] is the case when thief


decided to rob house i. In that situation
maximum value will be the current value of
house + maximum value stolen till last
robbery at house not adjacent to house

1010
Chapter 137. Find maximum possible stolen value from houses

i which will be house i-2.

dp[i-1] is the case when thief decided not


to rob house i. So he will check adjacent
house for maximum value stolen till now.

Thief will consider both options and decide whether to rob or not and maximum of both
values will be the maximum stolen value till reaching house i.
We can prepare dp in bottom up manner instead of recursively. Following is the program
for that –

C++

// CPP program to find the maximum stolen value


#include <iostream>
using namespace std;
  
// calculate the maximum stolen value
int maxLoot(int *hval, int n)
{
    if (n == 0)
        return 0;
    if (n == 1)
        return hval[0];
    if (n == 2)
        return max(hval[0], hval[1]);
  
    // dp[i] represent the maximum value stolen
    // so far after reaching house i.
    int dp[n];
  
    // Initialize the dp[0] and dp[1]
    dp[0] = hval[0];
    dp[1] = max(hval[0], hval[1]);
  
    // Fill remaining positions
    for (int i = 2; i<n; i++)
        dp[i] = max(hval[i]+dp[i-2], dp[i-1]);
  
    return dp[n-1];
}
  
// Driver to test above code
int main()
{
    int hval[] = {6, 7, 1, 3, 8, 2, 4};
    int n = sizeof(hval)/sizeof(hval[0]);

1011
Chapter 137. Find maximum possible stolen value from houses

    cout << "Maximum loot possible : "


        << maxLoot(hval, n);
    return 0;
}

Java

// Java program to find the maximum stolen value


import java.io.*;
  
class GFG 
{
    // Function to calculate the maximum stolen value
    static int maxLoot(int hval[], int n)
    {
        if (n == 0)
        return 0;
        if (n == 1)
            return hval[0];
        if (n == 2)
            return Math.max(hval[0], hval[1]);
   
        // dp[i] represent the maximum value stolen
        // so far after reaching house i.
        int[] dp = new int[n];
   
        // Initialize the dp[0] and dp[1]
        dp[0] = hval[0];
        dp[1] = Math.max(hval[0], hval[1]);
   
        // Fill remaining positions
        for (int i = 2; i<n; i++)
            dp[i] = Math.max(hval[i]+dp[i-2], dp[i-1]);
   
        return dp[n-1];
    }
      
    // Driver program
    public static void main (String[] args) 
    {
        int hval[] = {6, 7, 1, 3, 8, 2, 4};
        int n = hval.length;
        System.out.println("Maximum loot value : " + maxLoot(hval, n));
    }
}
  
// Contributed by Pramod Kumar

1012
Chapter 137. Find maximum possible stolen value from houses

Python

# Python3 program to find the maximum stolen value


  
# calculate the maximum stolen value
def maximize_loot(hval, n):
    if n == 0:
        return 0
    if n == 1:
        return hval[0]
    if n == 2:
        return max(hval[0], hval[1])
  
    # dp[i] represent the maximum value stolen so
    # for after reaching house i.
    dp = [0]*n
  
    # Initialize the dp[0] and dp[1]
    dp[0] = hval[0]
    dp[1] = max(hval[0], hval[1])
      
    # Fill remaining positions
    for i in range(2, n):
        dp[i] = max(hval[i]+dp[i-2], dp[i-1])
  
    return dp[-1]
  
# Driver to test above code 
def main():
  
    # Value of houses
    hval = [6, 7, 1, 3, 8, 2, 4]
  
    # number of houses
    n = len(hval)
    print("Maximum loot value : {}".
        format(maximize_loot(hval, n)))
  
if __name__ == '__main__':
    main()

C#

// C# program to find the 


// maximum stolen value
using System;
          

1013
Chapter 137. Find maximum possible stolen value from houses

class GFG 
{
   // Function to calculate the 
   // maximum stolen value
    static int maxLoot(int []hval, int n)
    {
        if (n == 0)
        return 0;
        if (n == 1)
            return hval[0];
        if (n == 2)
            return Math.Max(hval[0], hval[1]);
  
        // dp[i] represent the maximum value stolen
        // so far after reaching house i.
        int[] dp = new int[n];
  
        // Initialize the dp[0] and dp[1]
        dp[0] = hval[0];
        dp[1] = Math.Max(hval[0], hval[1]);
  
        // Fill remaining positions
        for (int i = 2; i<n; i++)
            dp[i] = Math.Max(hval[i]+dp[i-2], dp[i-1]);
  
        return dp[n-1];
    }
      
    // Driver program
    public static void Main () 
    {
        int []hval = {6, 7, 1, 3, 8, 2, 4};
        int n = hval.Length;
        Console.WriteLine("Maximum loot value : " + 
                                 maxLoot(hval, n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program to find 
// the maximum stolen value
  
// calculate the maximum
// stolen value

1014
Chapter 137. Find maximum possible stolen value from houses

function maxLoot($hval, $n)


{
    if ($n == 0)
        return 0;
    if ($n == 1)
        return $hval[0];
    if ($n == 2)
        return max($hval[0], 
                   $hval[1]);
  
    // dp[i] represent the maximum 
    // value stolen so far after 
    // reaching house i.
    $dp = array();
  
    // Initialize the 
    // dp[0] and dp[1]
    $dp[0] = $hval[0];
    $dp[1] = max($hval[0], 
                 $hval[1]);
  
    // Fill remaining positions
    for ($i = 2; $i < $n; $i++)
        $dp[$i] = max($hval[$i] + 
                      $dp[$i - 2], 
                      $dp[$i - 1]);
  
    return $dp[$n - 1];
}
  
// Driver Code
$hval = array(6, 7, 1, 
              3, 8, 2, 4);
$n = sizeof($hval);
echo "Maximum loot possible : ",
             maxLoot($hval, $n);
      
// This code is contributed by aj_36
?>

Output:

Maximum loot value : 19

Time complexity =

Space complexity =

1015
Chapter 137. Find maximum possible stolen value from houses

We can optimize extra space, by using two variables to store value dp[i-1] and dp[i-2].
Following is the program for that –

C++

// C++ program to find the maximum stolen value


#include <iostream>
using namespace std;
  
// calculate the maximum stolen value
int maxLoot(int *hval, int n)
{
    if (n == 0)
        return 0;
  
    int value1 = hval[0];
    if (n == 1)
        return value1;
  
    int value2 = max(hval[0], hval[1]);
    if (n == 2)
        return value2;
  
    // contains maximum stolen value at the end
    int max_val;
  
    // Fill remaining positions
    for (int i=2; i<n; i++)
    {
        max_val = max(hval[i]+value1, value2);
        value1 = value2;
        value2 = max_val;
    }
  
    return max_val;
}
  
// Driver to test above code
int main()
{
    // Value of houses
    int hval[] = {6, 7, 1, 3, 8, 2, 4};
    int n = sizeof(hval)/sizeof(hval[0]);
    cout << "Maximum loot possible : "
        << maxLoot(hval, n);
    return 0;
}

1016
Chapter 137. Find maximum possible stolen value from houses

Java

// Java program to find the maximum stolen value


import java.io.*;
  
class GFG 
{
    // Function to calculate the maximum stolen value
    static int maxLoot(int hval[], int n)
    {
        if (n == 0)
        return 0;
   
        int value1 = hval[0];
        if (n == 1)
            return value1;
   
        int value2 = Math.max(hval[0], hval[1]);
        if (n == 2)
            return value2;
    
        // contains maximum stolen value at the end
        int max_val = 0;
   
        // Fill remaining positions
        for (int i=2; i<n; i++)
        {
            max_val = Math.max(hval[i]+value1, value2);
            value1 = value2;
            value2 = max_val;
        }
   
        return max_val;
    }
      
    // driver program
    public static void main (String[] args) 
    {
        int hval[] = {6, 7, 1, 3, 8, 2, 4};
        int n = hval.length;
        System.out.println("Maximum loot value : " + maxLoot(hval, n));
    }
}
  
// Contributed by Pramod kumar

Python

1017
Chapter 137. Find maximum possible stolen value from houses

# Python3 program to find the maximum stolen value


  
# calculate the maximum stolen value
def maximize_loot(hval, n):
    if n == 0:
        return 0
  
    value1 = hval[0]
    if n == 1:
        return value1
  
    value2 = max(hval[0], hval[1])
    if n == 2:
        return value2
  
    # contains maximum stolen value at the end
    max_val = None
  
    # Fill remaining positions
    for i in range(2, n):
        max_val = max(hval[i]+value1, value2)
        value1 = value2
        value2 = max_val
  
    return max_val
  
# Driver to test above code 
def main():
  
    # Value of houses
    hval = [6, 7, 1, 3, 8, 2, 4]
  
    # number of houses
    n = len(hval)
    print("Maximum loot value : {}".format(maximize_loot(hval, n)))
  
if __name__ == '__main__':
    main()

C#

// C# program to find the 


// maximum stolen value
using System;
          
public class GFG 
{
    // Function to calculate the 

1018
Chapter 137. Find maximum possible stolen value from houses

    // maximum stolen value


    static int maxLoot(int []hval, int n)
    {
        if (n == 0)
        return 0;
  
        int value1 = hval[0];
        if (n == 1)
            return value1;
  
        int value2 = Math.Max(hval[0], hval[1]);
        if (n == 2)
            return value2;
      
        // contains maximum stolen value at the end
        int max_val = 0;
  
        // Fill remaining positions
        for (int i = 2; i < n; i++)
        {
            max_val = Math.Max(hval[i] + value1, value2);
            value1 = value2;
            value2 = max_val;
        }
  
        return max_val;
    }
      
    // Driver program
    public static void Main () 
    {
        int []hval = {6, 7, 1, 3, 8, 2, 4};
        int n = hval.Length;
        Console.WriteLine("Maximum loot value : " +
                                 maxLoot(hval, n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program to find 
// the maximum stolen value
  
// calculate the 
// maximum stolen value

1019
Chapter 137. Find maximum possible stolen value from houses

function maxLoot($hval, $n)


{
    if ($n == 0)
        return 0;
  
    $value1 = $hval[0];
    if ($n == 1)
        return $value1;
  
    $value2 = max($hval[0], 
                  $hval[1]);
    if ($n == 2)
        return $value2;
  
    // contains maximum 
    // stolen value at the end
    $max_val;
  
    // Fill remaining positions
    for ($i = 2; $i < $n; $i++)
    {
        $max_val = max($hval[$i] + 
                       $value1, $value2);
        $value1 = $value2;
        $value2 = $max_val;
    }
  
    return $max_val;
}
  
// Driver code
$hval = array(6, 7, 1, 3, 8, 2, 4);
$n = sizeof($hval);
echo "Maximum loot value : ",
          maxLoot($hval, $n);
      
// This code is contributed by ajit
?>

Output:

Maximum loot value : 19

Time complexity =

1020
Chapter 137. Find maximum possible stolen value from houses

Auxiliary Space =
Improved By : Sam007, jit_t

Source

https://www.geeksforgeeks.org/find-maximum-possible-stolen-value-houses/

1021
Chapter 138

Find maximum sum array of


length less than or equal to m

Find maximum sum array of length less than or equal to m - GeeksforGeeks


Given n arrays of different length consisting of integers, the target is to pick atmost one
subarray from an array such that the combined length of all picked subarrays does not
become greater than m and also sum of their elements is maximum.(also given that value
of n can not be more than 100)
Prerequisite : Knapsack Problem
Examples :

Input :
n = 5, m = 6
arr[][m] = {{3, 2, 3, 5},
{2, 7, -1},
{2, 8, 10},
{4, 5, 2, 6, 1},
{3, 2, 3, -2}};
Output : Maximum sum can be obtained is 39
Explanation : We are allowed to pick at most
one subarray from every array.
We get total sum 39 as ((5) + (7) + (8 + 10) +
(4 + 5))

Input :
n = 3, m = 4
arr[][m] = {{2, 3, 2},
{3, -1, 7, 10},
{4, 8, 10, -5, 3}};
Output : Maximum sum can be obtained is 35

1022
Chapter 138. Find maximum sum array of length less than or equal to m

This problem is similar to Knapsack problem.where you have to either pick an element or
leave it. We will have the same strategy here.
Given that the total number of elements in these n arrays is atmost 10^5. It is also known
that m is atmost 10^3 and the input arrays can contain negative numbers. First, make a
DP table (2D array) of size n * m and then, pre-compute the cumulative sum of an array
so that maximum sum of every length from 1 to n of that array can be easily computed, so
that for every given array there can be a maximum contiguous sum for length k, where k is
from 1 to length of the array.
In detail, process input arrays one by one. First, compute the maximum sum subarrays
of processed array for all sizes from 1 to length. Then, update our dynamic programming
table with these values and we start processing the next array.
Algorithm :

1. Pick one array from n arrays and start processing it.


2. Calculate maximum contiguous sum for length k, k is from 1 to length of the array
and save it in the array maxSum.
3. Now, fill the DP table by storing maximum sum possible for every length 0 to m.
4. In the last step we traverse last row(nth row) of DP table and pick maximum sum
possible and return it.

Source

https://www.geeksforgeeks.org/find-maximum-sum-array-length-less-equal-m/

1023
Chapter 139

Find minimum adjustment cost


of an array

Find minimum adjustment cost of an array - GeeksforGeeks


Given an array of positive integers, replace each element in the array such that the difference
between adjacent elements in the array is less than or equal to a given target. We need to
minimize the adjustment cost, that is the sum of differences between new and old values.
We basically need to minimize &Sum;|A[i] – Anew [i]| where 0 � i � n-1, n is size of A[] and
Anew [] is the array with adjacent difference less that or equal to target.
Assume all elements of the array is less than constant M = 100.
Examples:

Input: arr = [1, 3, 0, 3], target = 1


Output: Minimum adjustment cost is 3
Explanation: One of the possible solutions
is [2, 3, 2, 3]

Input: arr = [2, 3, 2, 3], target = 1


Output: Minimum adjustment cost is 0
Explanation: All adjacent elements in the input
array are already less than equal to given target

Input: arr = [55, 77, 52, 61, 39, 6,


25, 60, 49, 47], target = 10
Output: Minimum adjustment cost is 75
Explanation: One of the possible solutions is
[55, 62, 52, 49, 39, 29, 30, 40, 49, 47]

In order to minimize the adjustment cost &Sum;|A[i] – Anew [i]| for all index i in the array,
|A[i] – Anew [i]| should be as close to zero as possible. Also, |A[i] – Anew [i+1] ]| � Target.

1024
Chapter 139. Find minimum adjustment cost of an array

This problem can be solved by dynamic programming.


Let dp[i][j] defines minimal adjustment cost on changing A[i] to j, then the DP relation is
defined by –

dp[i][j] = min{dp[i - 1][k]} + |j - A[i]|


for all k's such that |k - j| � target

Here, 0 � i � n and 0 � j � M where n is number of elements in the array and M = 100. We


have to consider all k such that max(j – target, 0) � k � min(M, j + target)
Finally, the minimum adjustment cost of the array will be min{dp[n – 1][j]} for all 0 � j � M.
Below is the implementation of above idea –
C++

// C++ program to find minimum adjustment cost of an array


#include <bits/stdc++.h>
using namespace std;
  
#define M 100
  
// Function to find minimum adjustment cost of an array
int minAdjustmentCost(int A[], int n, int target)
{
    // dp[i][j] stores minimal adjustment cost on changing
    // A[i] to j
    int dp[n][M + 1];
  
    // handle first element of array seperately
    for (int j = 0; j <= M; j++)
        dp[0][j] = abs(j - A[0]);
  
    // do for rest elements of the array
    for (int i = 1; i < n; i++)
    {
        // replace A[i] to j and calculate minimal adjustment
        // cost dp[i][j]
        for (int j = 0; j <= M; j++)
        {
          // initialize minimal adjustment cost to INT_MAX
          dp[i][j] = INT_MAX;
  
          // consider all k such that k >= max(j - target, 0) and
          // k <= min(M, j + target) and take minimum
          for (int k = max(j-target,0); k <= min(M,j+target); k++)
             dp[i][j] = min(dp[i][j], dp[i - 1][k] + abs(A[i] - j));

1025
Chapter 139. Find minimum adjustment cost of an array

        }
    }    
  
    // return minimum value from last row of dp table
    int res = INT_MAX; 
    for (int j = 0; j <= M; j++)
        res = min(res, dp[n - 1][j]);
  
    return res;
}
  
// Driver Program to test above functions
int main()
{
    int arr[] = {55, 77, 52, 61, 39, 6, 25, 60, 49, 47};
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 10;
  
    cout << "Minimum adjustment cost is "
         << minAdjustmentCost(arr, n, target) << endl;
  
    return 0;
}

Java

// Java program to find minimum adjustment cost of an array


import java.io.*;
import java.util.*;
  
class GFG 
{
    public static int M = 100;
      
    // Function to find minimum adjustment cost of an array
    static int minAdjustmentCost(int A[], int n, int target)
    {
        // dp[i][j] stores minimal adjustment cost on changing
        // A[i] to j
        int[][] dp = new int[n][M + 1];
   
        // handle first element of array seperately
        for (int j = 0; j <= M; j++)
            dp[0][j] = Math.abs(j - A[0]);
   
        // do for rest elements of the array
        for (int i = 1; i < n; i++)
        {

1026
Chapter 139. Find minimum adjustment cost of an array

            // replace A[i] to j and calculate minimal adjustment


            // cost dp[i][j]
            for (int j = 0; j <= M; j++)
            {
                // initialize minimal adjustment cost to INT_MAX
                dp[i][j] = Integer.MAX_VALUE;
   
                // consider all k such that k >= max(j - target, 0) and
                // k <= min(M, j + target) and take minimum
                int k = Math.max(j-target,0);
                for ( ; k <= Math.min(M,j+target); k++)
                    dp[i][j] = Math.min(dp[i][j], dp[i - 1][k] +  
                                                Math.abs(A[i] - j));
            }
        }    
   
        // return minimum value from last row of dp table
        int res = Integer.MAX_VALUE; 
        for (int j = 0; j <= M; j++)
            res = Math.min(res, dp[n - 1][j]);
   
        return res;
    }
      
    // Driver program
    public static void main (String[] args) 
    {
        int arr[] = {55, 77, 52, 61, 39, 6, 25, 60, 49, 47};
        int n = arr.length;
        int target = 10;
   
        System.out.println("Minimum adjustment cost is "
                    +minAdjustmentCost(arr, n, target));
    }
}
  
// This code is contributed by Pramod Kumar

C#

// C# program to find minimum adjustment


// cost of an array
using System;
  
class GFG {
      
    public static int M = 100;
      

1027
Chapter 139. Find minimum adjustment cost of an array

    // Function to find minimum adjustment


    // cost of an array
    static int minAdjustmentCost(int []A, int n,
                                     int target)
    {
          
        // dp[i][j] stores minimal adjustment
        // cost on changing A[i] to j
        int[,] dp = new int[n,M + 1];
  
        // handle first element of array
        // seperately
        for (int j = 0; j <= M; j++)
            dp[0,j] = Math.Abs(j - A[0]);
  
        // do for rest elements of the array
        for (int i = 1; i < n; i++)
        {
            // replace A[i] to j and calculate
            // minimal adjustment cost dp[i][j]
            for (int j = 0; j <= M; j++)
            {
                // initialize minimal adjustment
                // cost to INT_MAX
                dp[i,j] = int.MaxValue;
  
                // consider all k such that 
                // k >= max(j - target, 0) and
                // k <= min(M, j + target) and
                // take minimum
                int k = Math.Max(j - target, 0);
                  
                for ( ; k <= Math.Min(M, j +
                                   target); k++)
                    dp[i,j] = Math.Min(dp[i,j],
                                   dp[i - 1,k]
                         + Math.Abs(A[i] - j));
            }
        } 
  
        // return minimum value from last
        // row of dp table
        int res = int.MaxValue; 
        for (int j = 0; j <= M; j++)
            res = Math.Min(res, dp[n - 1,j]);
  
        return res;
    }

1028
Chapter 139. Find minimum adjustment cost of an array

      
    // Driver program
    public static void Main () 
    {
        int []arr = {55, 77, 52, 61, 39,
                        6, 25, 60, 49, 47};
        int n = arr.Length;
        int target = 10;
  
        Console.WriteLine("Minimum adjustment"
                                 + " cost is "
         + minAdjustmentCost(arr, n, target));
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP program to find minimum 
// adjustment cost of an array
  
$M = 100;
  
// Function to find minimum 
// adjustment cost of an array
function minAdjustmentCost( $A, $n, $target)
{
      
    // dp[i][j] stores minimal 
    // adjustment cost on changing
    // A[i] to j
    global $M;
    $dp = array(array());
  
    // handle first element 
    // of array seperately
    for($j = 0; $j <= $M; $j++)
        $dp[0][$j] = abs($j - $A[0]);
  
    // do for rest 
    // elements of the array
    for($i = 1; $i < $n; $i++)
    {
          
        // replace A[i] to j and 
        // calculate minimal adjustment

1029
Chapter 139. Find minimum adjustment cost of an array

        // cost dp[i][j]


        for($j = 0; $j <= $M; $j++)
        {
              
            // initialize minimal adjustment
            // cost to INT_MAX
            $dp[$i][$j] = PHP_INT_MAX;
      
            // consider all k such that 
            // k >= max(j - target, 0) and
            // k <= min(M, j + target) and
            // take minimum
            for($k = max($j - $target, 0);
                $k <= min($M, $j + $target);
                                       $k++)
                $dp[$i][$j] = min($dp[$i][$j], 
                              $dp[$i - 1][$k] + 
                              abs($A[$i] - $j));
        }
    } 
  
    // return minimum value 
    // from last row of dp table
    $res = PHP_INT_MAX; 
    for($j = 0; $j <= $M; $j++)
        $res = min($res, $dp[$n - 1][$j]);
  
    return $res;
}
  
    // Driver Code
    $arr = array(55, 77, 52, 61, 39, 
                 6, 25, 60, 49, 47);
    $n = count($arr);
    $target = 10;
  
    echo "Minimum adjustment cost is "
        , minAdjustmentCost($arr, $n, $target);
  
// This code is contributed by anuj_67.
?>

Output:

Minimum adjustment cost is 75

Improved By : Sam007, vt_m

1030
Chapter 139. Find minimum adjustment cost of an array

Source

https://www.geeksforgeeks.org/find-minimum-adjustment-cost-of-an-array/

1031
Chapter 140

Find minimum number of coins


that make a given value

Find minimum number of coins that make a given value - GeeksforGeeks


Given a value V, if we want to make change for V cents, and we have infinite supply of each
of C = { C1, C2, .. , Cm} valued coins, what is the minimum number of coins to make the
change?
Examples:

Input: coins[] = {25, 10, 5}, V = 30


Output: Minimum 2 coins required
We can use one coin of 25 cents and one of 5 cents

Input: coins[] = {9, 6, 5, 1}, V = 11


Output: Minimum 2 coins required
We can use one coin of 6 cents and 1 coin of 5 cents

This problem is a variation of the problem discussed Coin Change Problem. Here instead
of finding total number of possible solutions, we need to find the solution with minimum
number of coins.
The minimum number of coins for a value V can be computed using below recursive formula.

If V == 0, then 0 coins required.


If V > 0
minCoin(coins[0..m-1], V) = min {1 + minCoins(V-coin[i])}
where i varies from 0 to m-1
and coin[i] <= V

1032
Chapter 140. Find minimum number of coins that make a given value

Below is recursive solution based on above recursive formula.

C++

// A Naive recursive C++ program to find minimum of coins


// to make a given change V
#include<bits/stdc++.h>
using namespace std;
  
// m is size of coins array (number of different coins)
int minCoins(int coins[], int m, int V)
{
   // base case
   if (V == 0) return 0;
  
   // Initialize result
   int res = INT_MAX;
  
   // Try every coin that has smaller value than V
   for (int i=0; i<m; i++)
   {
     if (coins[i] <= V)
     {
         int sub_res = minCoins(coins, m, V-coins[i]);
  
         // Check for INT_MAX to avoid overflow and see if
         // result can minimized
         if (sub_res != INT_MAX && sub_res + 1 < res)
            res = sub_res + 1;
     }
   }
   return res;
}
  
// Driver program to test above function
int main()
{
    int coins[] =  {9, 6, 5, 1};
    int m = sizeof(coins)/sizeof(coins[0]);
    int V = 11;
    cout << "Minimum coins required is "
         << minCoins(coins, m, V);
    return 0;
}

Java

// A Naive recursive JAVA program to find minimum of coins

1033
Chapter 140. Find minimum number of coins that make a given value

// to make a given change V


class coin
{
    // m is size of coins array (number of different coins)
    static int minCoins(int coins[], int m, int V)
    {
       // base case
       if (V == 0) return 0;
       
       // Initialize result
       int res = Integer.MAX_VALUE;
       
       // Try every coin that has smaller value than V
       for (int i=0; i<m; i++)
       {
         if (coins[i] <= V)
         {
             int sub_res = minCoins(coins, m, V-coins[i]);
       
             // Check for INT_MAX to avoid overflow and see if
             // result can minimized
             if (sub_res != Integer.MAX_VALUE && sub_res + 1 < res)
                res = sub_res + 1;
         }
       }
       return res;
    }
    public static void main(String args[])
    {
       int coins[] =  {9, 6, 5, 1};
       int m = coins.length;
       int V = 11;
       System.out.println("Minimum coins required is "+ minCoins(coins, m, V) );
    }
}/* This code is contributed by Rajat Mishra */

Python3

# A Naive recursive python program to find minimum of coins


# to make a given change V
  
import sys
  
# m is size of coins array (number of different coins)
def minCoins(coins, m, V):
  
    # base case
    if (V == 0):

1034
Chapter 140. Find minimum number of coins that make a given value

        return 0
  
    # Initialize result
    res = sys.maxsize
      
    # Try every coin that has smaller value than V
    for i in range(0, m):
        if (coins[i] <= V):
            sub_res = minCoins(coins, m, V-coins[i])
  
            # Check for INT_MAX to avoid overflow and see if
            # result can minimized
            if (sub_res != sys.maxsize and sub_res + 1 < res):
                res = sub_res + 1
  
    return res
  
# Driver program to test above function
coins = [9, 6, 5, 1]
m = len(coins)
V = 11
print("Minimum coins required is",minCoins(coins, m, V))
  
# This code is contributed by
# Smitha Dinesh Semwal

C#

// A Naive recursive C# program


// to find minimum of coins
// to make a given change V
using System;
class coin
{
      
    // m is size of coins array 
    // (number of different coins)
    static int minCoins(int []coins, int m, int V)
    {
          
        // base case
        if (V == 0) return 0;
          
        // Initialize result
        int res = int.MaxValue;
          
        // Try every coin that has
        // smaller value than V

1035
Chapter 140. Find minimum number of coins that make a given value

        for (int i = 0; i < m; i++)


        {
            if (coins[i] <= V)
            {
                int sub_res = minCoins(coins, m,
                                  V - coins[i]);
          
                // Check for INT_MAX to 
                // avoid overflow and see 
                // if result can minimized
                if (sub_res != int.MaxValue && 
                            sub_res + 1 < res)
                    res = sub_res + 1;
            }
        }
        return res;
    }
      
    // Driver Code
    public static void Main()
    {
        int []coins = {9, 6, 5, 1};
        int m = coins.Length;
        int V = 11;
        Console.Write("Minimum coins required is "+
                             minCoins(coins, m, V));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// A Naive recursive PHP 
// program to find minimum 
// of coins to make a given
// change V
  
// m is size of coins array 
// (number of different coins)
function minCoins($coins, 
                  $m, $V)
{
      
// base case
if ($V == 0) return 0;
  

1036
Chapter 140. Find minimum number of coins that make a given value

// Initialize result
$res = PHP_INT_MAX;
  
// Try every coin that has
// smaller value than V
for ($i = 0; $i < $m; $i++)
{
    if ($coins[$i] <= $V)
    {
        $sub_res = minCoins($coins, $m,
                            $V - $coins[$i]);
  
        // Check for INT_MAX to 
        // avoid overflow and see
        // if result can minimized
        if ($sub_res != PHP_INT_MAX && 
            $sub_res + 1 < $res)
            $res = $sub_res + 1;
    }
}
return $res;
}
  
// Driver Code
$coins = array(9, 6, 5, 1);
$m = sizeof($coins);
$V = 11;
echo "Minimum coins required is ",
         minCoins($coins, $m, $V);
      
// This code is contributed by ajit
?>

Output:

Minimum coins required is 2

The time complexity of above solution is exponential. If we draw the complete recursion
tree, we can observer that many subproblems are solved again and again. For example,
when we start from V = 11, we can reach 6 by subtracting one 5 times and by subtracting
5 one times. So the subproblem for 6 is called twice.
Since same suproblems are called again, this problem has Overlapping Subprolems property.
So the min coins problem has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, recomputations of
same subproblems can be avoided by constructing a temporary array table[][] in bottom up
manner. Below is Dynamic Programming based solution.

C++

1037
Chapter 140. Find minimum number of coins that make a given value

// A Dynamic Programming based C++ program to find minimum of coins


// to make a given change V
#include<bits/stdc++.h>
using namespace std;
  
// m is size of coins array (number of different coins)
int minCoins(int coins[], int m, int V)
{
    // table[i] will be storing the minimum number of coins
    // required for i value.  So table[V] will have result
    int table[V+1];
  
    // Base case (If given value V is 0)
    table[0] = 0;
  
    // Initialize all table values as Infinite
    for (int i=1; i<=V; i++)
        table[i] = INT_MAX;
  
    // Compute minimum coins required for all
    // values from 1 to V
    for (int i=1; i<=V; i++)
    {
        // Go through all coins smaller than i
        for (int j=0; j<m; j++)
          if (coins[j] <= i)
          {
              int sub_res = table[i-coins[j]];
              if (sub_res != INT_MAX && sub_res + 1 < table[i])
                  table[i] = sub_res + 1;
          }
    }
    return table[V];
}
  
// Driver program to test above function
int main()
{
    int coins[] =  {9, 6, 5, 1};
    int m = sizeof(coins)/sizeof(coins[0]);
    int V = 11;
    cout << "Minimum coins required is "
         << minCoins(coins, m, V);
    return 0;
}

Java

1038
Chapter 140. Find minimum number of coins that make a given value

// A Dynamic Programming based Java


// program to find minimum of coins
// to make a given change V
import java.io.*;
  
class GFG 
{
    // m is size of coins array 
    // (number of different coins)
    static int minCoins(int coins[], int m, int V)
    {
        // table[i] will be storing 
        // the minimum number of coins
        // required for i value. So 
        // table[V] will have result
        int table[] = new int[V + 1];
  
        // Base case (If given value V is 0)
        table[0] = 0;
  
        // Initialize all table values as Infinite
        for (int i = 1; i <= V; i++)
        table[i] = Integer.MAX_VALUE;
  
        // Compute minimum coins required for all
        // values from 1 to V
        for (int i = 1; i <= V; i++)
        {
            // Go through all coins smaller than i
            for (int j = 0; j < m; j++)
            if (coins[j] <= i)
            {
                int sub_res = table[i - coins[j]];
                if (sub_res != Integer.MAX_VALUE 
                       && sub_res + 1 < table[i])
                       table[i] = sub_res + 1;
                         
                  
            }
              
        }
        return table[V];
          
    }
  
    // Driver program 
    public static void main (String[] args) 
    {

1039
Chapter 140. Find minimum number of coins that make a given value

        int coins[] = {9, 6, 5, 1};


        int m = coins.length;
        int V = 11;
        System.out.println ( "Minimum coins required is " 
                            + minCoins(coins, m, V));
    }
}
  
//This article is contributed by vt_m.

C#

// A Dynamic Programming based 


// Java program to find minimum 
// of coins to make a given 
// change V
using System;
  
class GFG
{
  
// m is size of coins array 
// (number of different coins)
static int minCoins(int []coins,
                    int m, int V)
{
    // table[i] will be storing 
    // the minimum number of coins
    // required for i value. So 
    // table[V] will have result
    int []table = new int[V + 1];
  
    // Base case (If given
    // value V is 0)
    table[0] = 0;
  
    // Initialize all table
    // values as Infinite
    for (int i = 1; i <= V; i++)
    table[i] = int.MaxValue;
      
    // Compute minimum coins 
    // required for all
    // values from 1 to V
    for (int i = 1; i <= V; i++)
    {
        // Go through all coins
        // smaller than i

1040
Chapter 140. Find minimum number of coins that make a given value

        for (int j = 0; j < m; j++)


        if (coins[j] <= i)
        {
            int sub_res = table[i - coins[j]];
            if (sub_res != int.MaxValue && 
                sub_res + 1 < table[i])
                table[i] = sub_res + 1;
        }
    }
    return table[V];
      
}
  
// Driver Code 
static public void Main ()
{
    int []coins = {9, 6, 5, 1};
    int m = coins.Length;
    int V = 11;
    Console.WriteLine("Minimum coins required is " + 
                             minCoins(coins, m, V));
}
}
  
// This code is contributed 
// by akt_mit

PHP

<?php
// A Dynamic Programming based 
// PHP program to find minimum 
// of coins to make a given 
// change V.
  
// m is size of coins 
// array (number of different coins)
function minCoins($coins, $m, $V)
{
    // table[i] will be storing the
    // minimum number of coins
    // required for i value. So 
    // table[V] will have result
    $table[$V + 1] = array();
  
    // Base case (If given
    // value V is 0)
    $table[0] = 0;

1041
Chapter 140. Find minimum number of coins that make a given value

  
    // Initialize all table 
    // values as Infinite
    for ($i = 1; $i <= $V; $i++)
        $table[$i] = PHP_INT_MAX;
  
    // Compute minimum coins 
    // required for all
    // values from 1 to V
    for ($i = 1; $i <= $V; $i++)
    {
        // Go through all coins
        // smaller than i
        for ($j = 0; $j < $m; $j++)
        if ($coins[$j] <= $i)
        {
            $sub_res = $table[$i - $coins[$j]];
            if ($sub_res != PHP_INT_MAX && 
                $sub_res + 1 < $table[$i])
                $table[$i] = $sub_res + 1;
        }
    }
    return $table[$V];
}
  
// Driver Code
$coins = array(9, 6, 5, 1);
$m = sizeof($coins);
$V = 11;
echo "Minimum coins required is ",
    minCoins($coins, $m, $V);
  
// This code is contributed by ajit
?>

Output:

Minimum coins required is 2

Time complexity of the above solution is O(mV).


Thanks to Goku for suggesting above solution in a comment here and thanks to Vignesh
Mohan for suggesting this problem and initial solution.
Improved By : nitin mittal, jit_t

1042
Chapter 140. Find minimum number of coins that make a given value

Source

https://www.geeksforgeeks.org/find-minimum-number-of-coins-that-make-a-change/

1043
Chapter 141

Find minimum possible size of


array with given rules for
removing elements

Find minimum possible size of array with given rules for removing elements - GeeksforGeeks
Given an array of numbers and a constant k, minimize size of array with following rules for
removing elements.

• Exactly three elements can be removed at one go.


• The removed three elements must be adjacent in array, i.e., arr[i], arr[i+1], arr[i+2].
And the second element must be k greater than first and third element must be k
greater than second, i.e., arr[i+1] – arr[i] = k and arr[i+2]-arr[i+1] = k.

Example:

Input: arr[] = {2, 3, 4, 5, 6, 4}, k = 1


Output: 0
We can actually remove all elements.
First remove 4, 5, 6 => We get {2, 3, 4}
Now remove 2, 3, 4 => We get empty array {}

Input: arr[] = {2, 3, 4, 7, 6, 4}, k = 1


Output: 3
We can only remove 2 3 4

Source: https://code.google.com/codejam/contest/4214486/dashboard#s=p2
We strongly recommend you to minimize your browser and try this yourself
first.

1044
Chapter 141. Find minimum possible size of array with given rules for removing elements

For every element arr[i] there are two possibilities


1) Either the element is not removed.
2) OR element is removed (if it follows rules of removal). When an element is removed,
there are again two possibilities.
…..a) It may be removed directly, i.e., initial arr[i+1] is arr[i]+k and arr[i+2] is arr[i] + 2*k.
…..b) There exist x and y such that arr[x] – arr[i] = k, arr[y] – arr[x] = k, and subarrays
“arr[i+1…x-1]” & “arr[x+1…y-1]” can be completely removed.
Below is recursive algorithm based on above idea.

// Returns size of minimum possible size of arr[low..high]


// after removing elements according to given rules
findMinSize(arr[], low, high, k)

// If there are less than 3 elements in arr[low..high]


1) If high-low+1 < 3, return high-low+1

// Consider the case when 'arr[low]' is not considered as


// part of any triplet to be removed. Initialize result
// using this case
2) result = 1 + findMinSize(arr, low+1, high)

// Case when 'arr[low]' is part of some triplet and removed


// Try all possible triplets that have arr[low]
3) For all i from low+1 to high
For all j from i+1 to high
Update result if all of the following conditions are met
a) arr[i] - arr[low] = k
b) arr[j] - arr[i] = k
c) findMinSize(arr, low+1, i-1, k) returns 0
d) findMinSize(arr, i+1, j-1, k) also returns 0
e) Result calculated for this triplet (low, i, j)
is smaller than existing result.

4) Return result

The time complexity of above solution is exponential. If we draw the complete recursion
tree, we can observer that many subproblems are solved again and again. Since same
suproblems are called again, this problem has Overlapping Subprolems property. Like other
typical Dynamic Programming(DP) problems, recomputations of same subproblems can be
avoided by constructing a temporary array dp[][] to store results of the subproblems. Below
is Dynamic Programming based solution
Below is C++ implementation of above idea. The implementation is memoization based,
i.e., it is recursive and uses a lookup table dp[][] to check if a subproblem is already solved
or not.

// C++ program to find size of minimum possible array after

1045
Chapter 141. Find minimum possible size of array with given rules for removing elements

// removing elements according to given rules


#include <bits/stdc++.h>
using namespace std;
#define MAX 1000
  
// dp[i][j] denotes the minimum number of elements left in
// the subarray arr[i..j].
int dp[MAX][MAX];
  
int minSizeRec(int arr[], int low, int high, int k)
{
    // If already evaluated
    if (dp[low][high] != -1)
        return dp[low][high];
  
    // If size of array is less than 3
    if ( (high-low + 1) < 3)
        return high-low +1;
  
    // Initialize result as the case when first element is
    // separated (not removed using given rules)
    int res = 1 + minSizeRec(arr, low+1, high, k);
  
    // Now consider all cases when first element forms a triplet
    // and removed. Check for all possible triplets (low, i, j)
    for (int i = low+1; i<=high-1; i++)
    {
        for (int j = i+1; j <= high; j++ )
        {
            // Check if this triplet follows the given rules of
            // removal. And elements between 'low' and 'i' , and
            //  between 'i' and 'j' can be recursively removed.
            if (arr[i] == (arr[low] + k) &&
                arr[j] == (arr[low] + 2*k) &&
                minSizeRec(arr, low+1, i-1, k) == 0 &&
                minSizeRec(arr, i+1, j-1, k) == 0)
            {
                 res = min(res, minSizeRec(arr, j+1, high, k));
            }
        }
    }
  
    // Insert value in table and return result
    return (dp[low][high] = res);
}
  
// This function mainlu initializes dp table and calls
// recursive function minSizeRec

1046
Chapter 141. Find minimum possible size of array with given rules for removing elements

int minSize(int arr[], int n, int k)


{
    memset(dp, -1, sizeof(dp));
    return minSizeRec(arr, 0, n-1, k);
}
  
// Driver prrogram to test above function
int main()
{
    int arr[] = {2, 3, 4, 5, 6, 4};
    int n = sizeof(arr)/sizeof(arr[0]);
    int k = 1;
    cout << minSize(arr, n, k) << endl;
    return 0;
}

Output:

This article is contributed by Ekta Goel. Please write comments if you find anything incor-
rect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/find-minimum-possible-size-of-array-with-given-rules-for-removal/

1047
Chapter 142

Find minimum sum such that


one of every three consecutive
elements is taken

Find minimum sum such that one of every three consecutive elements is taken - Geeks-
forGeeks
Given an array of n non-negative numbers, the task is to find the minimum sum of elements
(picked from the array) such that at least one element is picked out of every 3 consecutive
elements in the array.
Examples :

Input : arr[] = {1, 2, 3}


Output : 1

Input : arr[] = {1, 2, 3, 6, 7, 1}


Output : 4
We pick 3 and 1 (3 + 1 = 4)
Note that there are following subarrays
of three consecutive elements
{1, 2, 3}, {2, 3, 6}, {3, 6, 7} and {6, 7, 1}
We have picked one element from every subarray.

Input : arr[] = {1, 2, 3, 6, 7, 1, 8, 6, 2,


7, 7, 1}
Output : 7
The result is obtained as sum of 3 + 1 + 2 + 1

Let sum(i) be the minimum possible sum when arr[i] is part of a solution sum (not necessarily
result) and is last picked element. Then our result is minimum of sum(n-1), sum(n-2) and

1048
Chapter 142. Find minimum sum such that one of every three consecutive elements is
taken

sum(n-3) [We must pick at least one of the last three elements].
We can recursively compute sum(i) as sum of arr[i] and minimum(sum(i-1), sum(i-2), sum(i-
3)). Since there are overlapping subproblems in recursive structure of problem, we can use
Dynamic Programming to solve this problem.
Below is the implementation of above idea.

C++

// A Dynamic Programming based C++ program to


// find minimum possible sum of elements of array
// such that an element out of every three
// consecutive is picked.
#include <iostream>
using namespace std;
  
// A utility function to find minimum of
// 3 elements
int minimum(int a, int b, int c)
{
    return min(min(a, b), c);
}
  
// Returns minimum possible sum of elements such
// that an element out of every three consecutive
// elements is picked.
int findMinSum(int arr[], int n)
{
    // Create a DP table to store results of
    // subproblems. sum[i] is going to store
    // minimum possible sum when arr[i] is
    // part of the solution.
    int sum[n];
  
    // When there are less than or equal to
    // 3 elements
    sum[0] = arr[0];
    sum[1] = arr[1];
    sum[2] = arr[2];
  
    // Iterate through all other elements
    for (int i=3; i<n; i++)
      sum[i] = arr[i] +
              minimum(sum[i-3], sum[i-2], sum[i-1]);
  
    return minimum(sum[n-1], sum[n-2], sum[n-3]);
}
  

1049
Chapter 142. Find minimum sum such that one of every three consecutive elements is
taken

// Driver code
int main()
{
    int arr[] = {1, 2, 3, 20, 2, 10, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Min Sum is " << findMinSum(arr, n);
    return 0;
}

Java

// A Dynamic Programming based java program to


// find minimum possible sum of elements of array
// such that an element out of every three
// consecutive is picked.
import java.io.*;
  
class GFG 
{
    // A utility function to find minimum of
    // 3 elements
    static int minimum(int a, int b, int c)
    {
        return Math. min(Math.min(a, b), c);
    }
      
    // Returns minimum possible sum of elements such
    // that an element out of every three consecutive
    // elements is picked.
    static int findMinSum(int arr[], int n)
    {
        // Create a DP table to store results of
        // subproblems. sum[i] is going to store
        // minimum possible sum when arr[i] is
        // part of the solution.
        int sum[] =new int[n];
      
        // When there are less than or equal to
        // 3 elements
        sum[0] = arr[0];
        sum[1] = arr[1];
        sum[2] = arr[2];
      
        // Iterate through all other elements
        for (int i = 3; i < n; i++)
        sum[i] = arr[i] + minimum(sum[i - 3], 
                         sum[i - 2], sum[i - 1]);
      

1050
Chapter 142. Find minimum sum such that one of every three consecutive elements is
taken

        return minimum(sum[n - 1], sum[n - 2], sum[n - 3]);


    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int arr[] = {1, 2, 3, 20, 2, 10, 1};
        int n = arr.length;
        System.out.println("Min Sum is " + findMinSum(arr, n));
              
    }
}
  
// This code is contributed by vt_m

Python3

# A Dynamic Programming based python 3 program to


# find minimum possible sum of elements of array
# such that an element out of every three
# consecutive is picked.
  
# A utility function to find minimum of
# 3 elements
def minimum(a, b, c):
    return min(min(a, b), c);
  
# Returns minimum possible sum of elements such
# that an element out of every three consecutive
# elements is picked.
def findMinSum(arr,n):
    # Create a DP table to store results of
    # subproblems. sum[i] is going to store
    # minimum possible sum when arr[i] is
    # part of the solution.
    sum = []
  
    # When there are less than or equal to
    # 3 elements
    sum.append(arr[0])
    sum.append(arr[1])
    sum.append(arr[2])
      
    # Iterate through all other elements
    for i in range(3, n):
        sum.append( arr[i] + minimum(sum[i-3],
                           sum[i-2], sum[i-1]))
  

1051
Chapter 142. Find minimum sum such that one of every three consecutive elements is
taken

    return minimum(sum[n-1], sum[n-2], sum[n-3])


  
# Driver code
arr = [1, 2, 3, 20, 2, 10, 1]
n = len(arr)
print( "Min Sum is ",findMinSum(arr, n))
  
# This code is contributed by Sam007

C#

// A Dynamic Programming based C# program to


// find minimum possible sum of elements of array
// such that an element out of every three
// consecutive is picked.
using System;
  
class GFG
{
    // A utility function to find minimum of
    // 3 elements
    static int minimum(int a, int b, int c)
    {
        return Math. Min(Math.Min(a, b), c);
    }
      
    // Returns minimum possible sum of elements such
    // that an element out of every three consecutive
    // elements is picked.
    static int findMinSum(int []arr, int n)
    {
        // Create a DP table to store results of
        // subproblems. sum[i] is going to store
        // minimum possible sum when arr[i] is
        // part of the solution.
        int []sum =new int[n];
      
        // When there are less than or equal to
        // 3 elements
        sum[0] = arr[0];
        sum[1] = arr[1];
        sum[2] = arr[2];
      
        // Iterate through all other elements
        for (int i = 3; i < n; i++)
        sum[i] = arr[i] + minimum(sum[i - 3], 
                     sum[i - 2], sum[i - 1]);
      

1052
Chapter 142. Find minimum sum such that one of every three consecutive elements is
taken

        return minimum(sum[n - 1], sum[n - 2], sum[n - 3]);


    }
      
    // Driver code
    public static void Main () 
    {
        int []arr = {1, 2, 3, 20, 2, 10, 1};
        int n = arr.Length;
        Console.WriteLine("Min Sum is " + findMinSum(arr, n));
              
    }
}
  
//This code is contributed by Sam007

PHP

<?php
// A Dynamic Programming based 
// PHP program to find minimum 
// possible sum of elements of
// array such that an element 
// out of every three consecutive
// is picked.
  
// function to find minimum of
// 3 elements
function minimum($a, $b, $c)
{
    return min(min($a, $b), $c);
}
  
// Returns minimum possible sum
// of elements such that an
// element out of every three
// consecutive elements is picked.
function findMinSum($arr, $n)
{
      
    // Create a DP table to store results of
    // subproblems. sum[i] is going to store
    // minimum possible sum when arr[i] is
    // part of the solution.
    $sum[$n] = 0;
  
    // When there are less 
    // than or equal to
    // 3 elements

1053
Chapter 142. Find minimum sum such that one of every three consecutive elements is
taken

    $sum[0] = $arr[0];
    $sum[1] = $arr[1];
    $sum[2] = $arr[2];
  
    // Iterate through all other elements
    for ($i = 3; $i < $n; $i++)
    $sum[$i] = $arr[$i] + minimum($sum[$i - 3],
                   $sum[$i - 2], $sum[$i - 1]);
  
    return minimum($sum[$n - 1], $sum[$n - 2], 
                                $sum[$n - 3]);
}
  
    // Driver code
    $arr = array(1, 2, 3, 20, 2, 10, 1);
    $n = sizeof($arr);
    echo "Min Sum is " , findMinSum($arr, $n);
      
// This code is contributed by nitin mittal. 
?>

Output:

Min Sum is 4

Time Complexity : O(n)


Auxiliary Space : O(n)
Improved By : Sam007, nitin mittal, SujanDutta

Source

https://www.geeksforgeeks.org/find-minimum-sum-one-every-three-consecutive-elements-taken/

1054
Chapter 143

Find n-th element from Stern’s


Diatomic Series

Find n-th element from Stern’s Diatomic Series - GeeksforGeeks


Given an integer n. we have to find the nth term of Stern’s Diatomic Series.
Stern’s diatomic series is the sequence which generates the following integer sequence 0,
1, 1, 2, 1, 3, 2, 3, 1, 4, 3, 5, 2, 5, 3, 4, ……. It arises in the Calkin-Wilf tree. It is sometimes
also known as the fusc function.
In mathematical terms, the sequence P(n) of Stern’s diatomic series is defined by the recur-
rence relation.

Examples :

Input : n = 7
Output : 3

1055
Chapter 143. Find n-th element from Stern’s Diatomic Series

Input : n = 15
Output : 4

Approach :
We solve this problem with a very simple concept of Dynamic programming which is used
in finding fibonacci numbers. After saving the base case of DP[0] = 0, DP[1] = 1, we have
to simply traverse from i = 2 to n and compute DP[i] as per explained definition of Stern’s
diatomic series. And finally return the value of DP[n].
Algorithm :

// SET the Base case


DP[0] = 0;
DP[1] = 1;

// Traversing the array from 2nd Element to nth Element


for (int i=2; i<=n; i++)
{
// Case 1: for even n
if (i%2 == 0)
DP[i] = DP[i/2];

// Case 2: for odd n


else
DP[i] = DP[(i-1)/2] + DP[(i+1)/2];
}
return DP[n];

C++

// Program to find the nth element 


// of Stern's Diatomic Series
#include <bits/stdc++.h>
using namespace std;
  
// function to find nth stern'
// diatomic series
int findSDSFunc(int n)
{
    // Initializing the DP array
    int DP[n+1];
  
    // SET the Base case
    DP[0] = 0;
    DP[1] = 1;
  
    // Traversing the array from 

1056
Chapter 143. Find n-th element from Stern’s Diatomic Series

    // 2nd Element to nth Element


    for (int i = 2; i <= n; i++) {
          
        // Case 1: for even n
        if (i % 2 == 0)
            DP[i] = DP[i / 2];
          
        // Case 2: for odd n
        else
            DP[i] = DP[(i - 1) / 2] +
                        DP[(i + 1) / 2];
    }
    return DP[n];
}
  
// Driver program
int main()
{
    int n = 15;    
    cout << findSDSFunc(n) << endl;    
    return 0;
}

Java

// Java program to find the nth element 


// of Stern's Diatomic Series
  
class GFG {
      
    // function to find nth stern'
    // diatomic series
    static int findSDSFunc(int n)
    {
          
        // Initializing the DP array
        int DP[] = new int[n+1];
      
        // SET the Base case
        DP[0] = 0;
        DP[1] = 1;
      
        // Traversing the array from 
        // 2nd Element to nth Element
        for (int i = 2; i <= n; i++)
        {
              
            // Case 1: for even n

1057
Chapter 143. Find n-th element from Stern’s Diatomic Series

            if (i % 2 == 0)
                DP[i] = DP[i / 2];
              
            // Case 2: for odd n
            else
                DP[i] = DP[(i - 1) / 2] +
                            DP[(i + 1) / 2];
        }
          
        return DP[n];
    }
      
    // Driver program
    public static void main(String[] args)
    {
        int n = 15;
          
        System.out.println(findSDSFunc(n));
    }
}
  
// This code is contributed by Smita Semwal.

Python 3

# Program to find the nth element 


# of Stern's Diatomic Series
  
# function to find nth stern'
# diatomic series
def findSDSFunc(n):
  
    # Initializing the DP array
    DP = [0] * (n+1)
  
    # SET the Base case
    DP[0] = 0
    DP[1] = 1
  
    # Traversing the array from 
    # 2nd Element to nth Element
    for i in range(2, n+1): 
          
        # Case 1: for even n
        if (int(i % 2) == 0):
            DP[i] = DP[int(i / 2)]
          
        # Case 2: for odd n

1058
Chapter 143. Find n-th element from Stern’s Diatomic Series

        else:
            DP[i] = (DP[int((i - 1) / 2)]
                  + DP[int((i + 1) / 2)])
      
    return DP[n]
  
  
# Driver program
n = 15
  
print(findSDSFunc(n))
  
# This code is contribute by
# Smitha Dinesh Semwal

C#

// C# program to find the nth element 


// of Stern's Diatomic Series
using System;
  
class GFG
{
    // function to find nth
    // stern' diatomic series
    static int findSDSFunc(int n)
    {
          
        // Initializing the DP array
        int []DP = new int[n + 1];
      
        // SET the Base case
        DP[0] = 0;
        DP[1] = 1;
      
        // Traversing the array from 
        // 2nd Element to nth Element
        for (int i = 2; i <= n; i++)
        {
              
            // Case 1: for even n
            if (i % 2 == 0)
                DP[i] = DP[i / 2];
              
            // Case 2: for odd n
            else
                DP[i] = DP[(i - 1) / 2] +
                        DP[(i + 1) / 2];

1059
Chapter 143. Find n-th element from Stern’s Diatomic Series

        }
          
        return DP[n];
    }
      
    // Driver Code
    static public void Main ()
    {
        int n = 15;
        Console.WriteLine(findSDSFunc(n));
    }
}
  
// This code is contributed by aj_36

PHP

<?php
// PHP Program to find the nth element 
// of Stern's Diatomic Series
  
// function to find nth stern'
// diatomic series
function findSDSFunc($n)
{
  
    // SET the Base case
    $DP[0] = 0;
    $DP[1] = 1;
  
    // Traversing the array from 
    // 2nd Element to nth Element
    for ($i = 2; $i <= $n; $i++)
    {
          
        // Case 1: for even n
        if ($i % 2 == 0)
            $DP[$i] = $DP[$i / 2];
          
        // Case 2: for odd n
        else
            $DP[$i] = $DP[($i - 1) / 2] +
                      $DP[($i + 1) / 2];
    }
    return $DP[$n];
}
  
// Driver Code

1060
Chapter 143. Find n-th element from Stern’s Diatomic Series

$n = 15; 
echo(findSDSFunc($n));
  
// This code is contributed by Ajit.
?>

Output:

Improved By : Smitha Dinesh Semwal, jit_t

Source

https://www.geeksforgeeks.org/find-n-th-element-from-sterns-diatomic-series/

1061
Chapter 144

Find number of endless points

Find number of endless points - GeeksforGeeks


Given a binary N x N matrix, we need to find the total number of matrix positions from
which there is an endless path. Any position (i, j) is said to have an endless path if and
only if all of the next positions in its row(i) and its column(j) should have value 1. If any
position next to (i,j) either in row(i) or in column(j) will have 0 then position (i,j) doesn’t
have any endless path.
Examples:

Input : 0 1 0
1 1 1
0 1 1
Output : 4
Endless points are (1, 1), (1, 2),
(2, 1) and (2, 2). For all other
points path to some corner is
blocked at some point.

Input : 0 1 1
1 1 0
0 1 0
Output : 1
Endless point is (0, 2).

Naive Approach :
We traverse all positions, for every position, we check that does this position has endless
path or not. If yes then count it otherwise ignore it. But as usual its time complexity seems
to be high.
Time complexity : O(n3 )

1062
Chapter 144. Find number of endless points

Advance Approach (Dynamic programming):


We can easily say that if there is a zero at any position, then it will block path for all the
positions left to it and top of it.

Also, we can say that any position (i,j) will have an endless row if (i,j+1) will have an endless
row and value of (i,j) is 1.
Similarly, we can say that any position (i,j) will have an endless column if (i+1,j) will have
an endless column and value of (i,j) is 1.

So we should maintain two matrices one for row and one for column. Always start from
right most position for row and bottom most position for column and only check for next
position whether it has endless path or not.
And Finally, if any position will have an endless path in both row and column matrix then
that position is said to have an endless path.
C++

// C++ program to find count of endless points

1063
Chapter 144. Find number of endless points

#include<bits/stdc++.h>
using namespace std;
  
const int MAX = 100;
  
// Returns count of endless points
int countEndless(bool input[][MAX], int n)
{
    bool row[n][n], col[n][n];
  
    // Fills column matrix. For every column, start
    // from every last row and fill every entry as
    // blockage after a 0 is found.
    for (int j=0; j<n; j++)
    {
        // flag which will be zero once we get a '0'
        // and it will be 1 otherwise
        bool isEndless = 1;
        for (int i=n-1; i>=0; i--)
        {
            // encountered a '0', set the isEndless
            // variable to false
            if (input[i][j] == 0)
                isEndless = 0;
            col[i][j] = isEndless;
        }
    }
  
    // Similarly, fill row matrix
    for (int i=0; i<n; i++)
    {
        bool isEndless = 1;
        for (int j= n-1; j>=0; j--)
        {
            if (input[i][j] == 0)
                isEndless = 0;
            row[i][j] = isEndless;
        }
    }
  
    // Calculate total count of endless points
    int ans = 0;
    for (int i=0; i<n; i++)
        for (int j=1; j<n; j++)
  
            // If there is NO blockage in row
            // or column after this point,
            // increment result.

1064
Chapter 144. Find number of endless points

            if (row[i][j] && col[i][j])


                ans++;
  
    return ans;
}
  
// Driver code
int main()
{
    bool input[][MAX] = { {1, 0, 1, 1},
                         {0, 1, 1, 1},
                         {1, 1, 1, 1},
                         {0, 1, 1, 0}};
    int n = 4;
  
    cout << countEndless(input, n);
    return 0;
}

Java

// Java program to find count of endless points


class GFG {
      
    static final int MAX = 100;
      
    // Returns count of endless points
    static int countEndless(boolean input[][], int n)
    {
          
        boolean row[][] = new boolean[n][n];
        boolean col[][] = new boolean[n][n];
      
        // Fills column matrix. For every column, 
        // start from every last row and fill every
        // entry as blockage after a 0 is found.
        for (int j = 0; j < n; j++)
        {
              
            // flag which will be zero once we get 
            // a '0' and it will be 1 otherwise
            boolean isEndless = true;
            for (int i = n-1; i >= 0; i--)
            {
                  
                // encountered a '0', set the 
                // isEndless variable to false
                if (input[i][j] == false)

1065
Chapter 144. Find number of endless points

                    isEndless = false;
                      
                col[i][j] = isEndless;
            }
        }
      
        // Similarly, fill row matrix
        for (int i = 0; i < n; i++)
        {
            boolean isEndless = true;
            for (int j = n-1; j >= 0; j--)
            {
                if (input[i][j] == false)
                    isEndless = false;
                row[i][j] = isEndless;
            }
        }
      
        // Calculate total count of endless points
        int ans = 0;
        for (int i = 0; i < n; i++)
            for (int j = 1; j < n; j++)
      
                // If there is NO blockage in row
                // or column after this point,
                // increment result.
                if (row[i][j] && col[i][j])
                    ans++;
      
        return ans;
    }
      
    //driver code
    public static void main(String arg[])
    {
        boolean input[][] = { 
                    {true, false, true, true},
                    {false, true, true, true},
                    {true, true, true, true},
                    {false, true, true, false}};
        int n = 4;
      
        System.out.print(countEndless(input, n));
    }
}
  
// This code is contributed by Anant Agarwal.

1066
Chapter 144. Find number of endless points

C#

// C# program to find count of


// endless points
using System;
  
public class GFG {
  
    // Returns count of endless points
    static int countEndless(bool [,]input, int n)
    {
          
        bool [,]row = new bool[n,n];
        bool [,]col = new bool[n,n];
      
        // Fills column matrix. For every
        // column, start from every last
        // row and fill every entry as 
        // blockage after a 0 is found.
        for (int j = 0; j < n; j++)
        {
              
            // flag which will be zero 
            // once we get a '0' and it
            // will be 1 otherwise
            bool isEndless = true;
            for (int i = n - 1; i >= 0; i--)
            {
                  
                // encountered a '0', set
                // the isEndless variable
                // to false
                if (input[i,j] == false)
                    isEndless = false;
                      
                col[i,j] = isEndless;
            }
        }
      
        // Similarly, fill row matrix
        for (int i = 0; i < n; i++)
        {
            bool isEndless = true;
            for (int j = n - 1; j >= 0; j--)
            {
                if (input[i,j] == false)
                    isEndless = false;
                row[i,j] = isEndless;

1067
Chapter 144. Find number of endless points

            }
        }
      
        // Calculate total count of
        // endless points
        int ans = 0;
        for (int i = 0; i < n; i++)
            for (int j = 1; j < n; j++)
      
                // If there is NO blockage
                // in row or column after
                // this point, increment
                // result.
                if (row[i,j] && col[i,j])
                    ans++;
      
        return ans;
    }
      
    //Driver code
    public static void Main()
    {
        bool [,]input = { 
                {true, false, true, true},
                {false, true, true, true},
                {true, true, true, true},
                {false, true, true, false}};
        int n = 4;
      
        Console.Write(countEndless(input, n));
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP program to find 
// count of endless points
  
// Returns count of 
// endless points
function countEndless($input, $n)
{
  
    // Fills column matrix. For 
    // every column, start from 

1068
Chapter 144. Find number of endless points

    // every last row and fill 


    // every entry as blockage 
    // after a 0 is found.
    for ($j = 0; $j < $n; $j++)
    {
        // flag which will be zero 
        // once we get a '0' and 
        // it will be 1 otherwise
        $isEndless = 1;
        for ($i = $n - 1; $i >= 0; $i--)
        {
            // encountered a '0', 
            // set the isEndless
            // variable to false
            if ($input[$i][$j] == 0)
                $isEndless = 0;
            $col[$i][$j] = $isEndless;
        }
    }
  
    // Similarly, fill row matrix
    for ($i = 0; $i < $n; $i++)
    {
        $isEndless = 1;
        for ($j = $n - 1; $j >= 0; $j--)
        {
            if ($input[$i][$j] == 0)
                $isEndless = 0;
            $row[$i][$j] = $isEndless;
        }
    }
  
    // Calculate total count
    // of endless points
    $ans = 0;
    for ($i = 0; $i < $n; $i++)
        for ($j = 1; $j < $n; $j++)
  
            // If there is NO blockage 
            // or column after this point,
            // increment result.
            if ($row[$i][$j] && 
                $col[$i][$j])
                $ans++;
  
    return $ans;
}
  

1069
Chapter 144. Find number of endless points

// Driver code
$input = array(array(1, 0, 1, 1),
               array(0, 1, 1, 1),
               array(1, 1, 1, 1),
               array(0, 1, 1, 0));
$n = 4;
  
echo countEndless($input, $n);
  
// This code is contributed 
// by shiv_bhakt. 
?>

Output:

Improved By : Sam007, shiv_bhakt

Source

https://www.geeksforgeeks.org/find-number-endless-points/

1070
Chapter 145

Find number of solutions of a


linear equation of n variables

Find number of solutions of a linear equation of n variables - GeeksforGeeks


Given a linear equation of n variables, find number of non-negative integer solutions of it.
For example,let the given equation be “x + 2y = 5”, solutions of this equation are “x = 1, y
= 2”, “x = 5, y = 0” and “x = 1. It may be assumed that all coefficients in given equation
are positive integers.
Example :

Input: coeff[] = {1, 2}, rhs = 5


Output: 3
The equation "x + 2y = 5" has 3 solutions.
(x=3,y=1), (x=1,y=2), (x=5,y=0)

Input: coeff[] = {2, 2, 3}, rhs = 4


Output: 3
The equation "2x + 2y + 3z = 4" has 3 solutions.
(x=0,y=2,z=0), (x=2,y=0,z=0), (x=1,y=1,z=0)

We strongly recommend you to minimize your browser and try this yourself
first.
We can solve this problem recursively. The idea is to subtract first coefficient from rhs and
then recur for remaining value of rhs.

If rhs = 0
countSol(coeff, 0, rhs, n-1) = 1
Else

1071
Chapter 145. Find number of solutions of a linear equation of n variables

countSol(coeff, 0, rhs, n-1) = &Sum;countSol(coeff, i, rhs-coeff[i], m-1)


where coeff[i]<=rhs and
i varies from 0 to n-1

Below is recursive implementation of above solution.


C++

// A naive recursive C++ program to 


// find number of non-negative solutions
// for a given linear equation
#include<bits/stdc++.h>
using namespace std;
  
// Recursive function thet returns 
// count of solutions for given rhs
// value and coefficients coeff[start..end]
int countSol(int coeff[], int start, 
             int end, int rhs)
{
    // Base case
    if (rhs == 0)
    return 1;
  
    // Initialize count
    // of solutions
    int result = 0; 
  
    // One by subtract all smaller or 
    // equal coefficiants and recur
    for (int i = start; i <= end; i++)
    if (coeff[i] <= rhs)
        result += countSol(coeff, i, end,
                           rhs - coeff[i]);
  
    return result;
}
  
// Driver Code
int main()
{
    int coeff[] = {2, 2, 5};
    int rhs = 4;
    int n = sizeof(coeff) / sizeof(coeff[0]);
    cout << countSol(coeff, 0, n - 1, rhs);
    return 0;
}

Java

1072
Chapter 145. Find number of solutions of a linear equation of n variables

// A naive recursive Java program 


// to find number of non-negative
// solutions for a given linear equation
import java.io.*;
  
class GFG 
{
          
    // Recursive function that returns 
    // count of solutions for given
    // rhs value and coefficients coeff[start..end]
    static int countSol(int coeff[], int start,
                        int end, int rhs)
    {
        // Base case
        if (rhs == 0)
        return 1;
      
        // Initialize count of solutions 
        int result = 0; 
      
        // One by subtract all smaller or
        // equal coefficiants and recur
        for (int i = start; i <= end; i++)
        if (coeff[i] <= rhs)
            result += countSol(coeff, i, end, 
                               rhs - coeff[i]);
      
        return result;
    }
      
    // Driver Code
    public static void main (String[] args)
    {
        int coeff[] = {2, 2, 5};
        int rhs = 4;
        int n = coeff.length;
        System.out.println (countSol(coeff, 0, 
                                     n - 1, rhs));
              
    }
}
  
// This code is contributed by vt_m.

Python3

# A naive recursive Python program

1073
Chapter 145. Find number of solutions of a linear equation of n variables

# to find number of non-negative 


# solutions for a given linear equation
  
# Recursive function that returns 
# count of solutions for given rhs
# value and coefficients coeff[stat...end]
def countSol(coeff, start, end, rhs):
  
    # Base case
    if (rhs == 0):
        return 1
  
    # Initialize count of solutions
    result = 0 
  
    # One by one subtract all smaller or 
    # equal coefficients and recur
    for i in range(start, end+1):
        if (coeff[i] <= rhs):
            result += countSol(coeff, i, end,
                               rhs - coeff[i])
  
    return result
  
# Driver Code
coeff = [2, 2, 5]
rhs = 4
n = len(coeff)
print(countSol(coeff, 0, n - 1, rhs))
  
# This code is contributed
# by Soumen Ghosh

C#

// A naive recursive C# program 


// to find number of non-negative
// solutions for a given linear equation
using System;
  
class GFG 
{
          
    // Recursive function that 
    // returns count of solutions 
    // for given RHS value and 
    // coefficients coeff[start..end]
    static int countSol(int []coeff, int start,

1074
Chapter 145. Find number of solutions of a linear equation of n variables

                        int end, int rhs)


    {
        // Base case
        if (rhs == 0)
        return 1;
      
        // Initialize count of solutions 
        int result = 0; 
      
        // One by subtract all smaller or
        // equal coefficiants and recur
        for (int i = start; i <= end; i++)
        if (coeff[i] <= rhs)
            result += countSol(coeff, i, end,
                               rhs - coeff[i]);
      
        return result;
    }
      
    // Driver Code
    public static void Main ()
    {
        int []coeff = {2, 2, 5};
        int rhs = 4;
        int n = coeff.Length;
        Console.Write (countSol(coeff, 0, 
                                n - 1, rhs));
              
    }
}
  
// This Code is contributed 
// by nitin mittal.

PHP

<?php
// A naive recursive PHP program to 
// find number of non-negative solutions 
// for a given linear equation
  
// Recursive function thet returns count
// of solutions for given rhs value and
// coefficients coeff[start..end]
  
function countSol($coeff, $start, $end, $rhs)
{
    // Base case

1075
Chapter 145. Find number of solutions of a linear equation of n variables

    if ($rhs == 0)
    return 1;
  
    // Initialize count of solutions
    $result = 0; 
  
    // One by subtract all smaller or
    // equal coefficiants and recur
    for ($i = $start; $i <= $end; $i++)
    if ($coeff[$i] <= $rhs)
        $result += countSol($coeff, $i, $end,
                            $rhs - $coeff[$i]);
  
    return $result;
}
  
// Driver Code
$coeff = array (2, 2, 5);
$rhs = 4;
$n = sizeof($coeff);
echo countSol($coeff, 0, $n - 1, $rhs);
  
// This code is contributed by ajit
?>

Output :

The time complexity of above solution is exponential. We can solve this problem in Pseudo
Polynomial Time (time complexity is dependent on numeric value of input) using Dynamic
Programming. The idea is similar to Dynamic Programming solution Subset Sum problem.
Below is Dynamic Programming based implementation.
C++

// A Dynamic programming based C++ 


// program to find number of non-negative
// solutions for a given linear equation
#include<bits/stdc++.h>
using namespace std;
  
// Returns count of solutions for 
// given rhs and coefficients coeff[0..n-1]
int countSol(int coeff[], int n, int rhs)
{
    // Create and initialize a table 
    // to store results of subproblems

1076
Chapter 145. Find number of solutions of a linear equation of n variables

    int dp[rhs + 1];


    memset(dp, 0, sizeof(dp));
    dp[0] = 1;
  
    // Fill table in bottom up manner
    for (int i = 0; i < n; i++)
    for (int j = coeff[i]; j <= rhs; j++)
        dp[j] += dp[j - coeff[i]];
  
    return dp[rhs];
}
  
// Driver Code
int main()
{
    int coeff[] = {2, 2, 5};
    int rhs = 4;
    int n = sizeof(coeff) / sizeof(coeff[0]);
    cout << countSol(coeff, n, rhs);
    return 0;
}

Java

// A Dynamic programming based Java program 


// to find number of non-negative solutions 
// for a given linear equation
import java.util.Arrays;
  
class GFG
{
    // Returns counr of solutions for given 
    // rhs and coefficients coeff[0..n-1]
    static int countSol(int coeff[], 
                        int n, int rhs)
    {
          
        // Create and initialize a table to 
        // store results of subproblems
        int dp[] = new int[rhs + 1];
        Arrays.fill(dp, 0);
        dp[0] = 1;
      
        // Fill table in bottom up manner
        for (int i = 0; i < n; i++)
        for (int j = coeff[i]; j <= rhs; j++)
            dp[j] += dp[j - coeff[i]];
      

1077
Chapter 145. Find number of solutions of a linear equation of n variables

        return dp[rhs];
    }
      
    // Driver code
    public static void main (String[] args)
    {
        int coeff[] = {2, 2, 5};
        int rhs = 4;
        int n = coeff.length;
        System.out.print(countSol(coeff, n, rhs));
    }
}
  
// This code is contributed by Anant Agarwal

Python3

# A Dynamic Programming based


# Python program to find number
# of non-negative solutions for
# a given linear equation
  
# Returns count of solutions for given
# rhs and coefficients coeff[0...n-1]
def countSol(coeff, n, rhs):
  
    # Create and initialize a table
    # to store results of subproblems
    dp = [0 for i in range(rhs + 1)]
    dp[0] = 1
  
    # Fill table in bottom up manner
    for i in range(n):
        for j in range(coeff[i], rhs + 1):
            dp[j] += dp[j - coeff[i]]
  
    return dp[rhs]
  
# Driver Code
coeff = [2, 2, 5]
rhs = 4
n = len(coeff)
print(countSol(coeff, n, rhs))
  
# This code is contributed
# by Soumen Ghosh

C#

1078
Chapter 145. Find number of solutions of a linear equation of n variables

// A Dynamic programming based 


// C# program to find number of 
// non-negative solutions for a
// given linear equation
using System;
  
class GFG
{
    // Returns counr of solutions 
    // for given rhs and coefficients 
    // coeff[0..n-1]
    static int countSol(int []coeff, 
                        int n, int rhs)
    {
          
        // Create and initialize a 
        // table to store results
        // of subproblems
        int []dp = new int[rhs + 1];
          
        // Arrays.fill(dp, 0);
        dp[0] = 1;
      
        // Fill table in
        // bottom up manner
        for (int i = 0; i < n; i++)
        for (int j = coeff[i]; j <= rhs; j++)
            dp[j] += dp[j - coeff[i]];
      
        return dp[rhs];
    }
      
    // Driver code
    public static void Main ()
    {
        int []coeff = {2, 2, 5};
        int rhs = 4;
        int n = coeff.Length;
        Console.Write(countSol(coeff, 
                               n, rhs));
    }
}
  
// This code is contributed
// by shiv_bhakt.

PHP

1079
Chapter 145. Find number of solutions of a linear equation of n variables

<?php
// PHP program to find number of 
// non-negative solutions for a
// given linear equation
  
// Returns count of solutions 
// for given rhs and coefficients
// coeff[0..n-1]
function countSol($coeff, $n, $rhs)
{
    // Create and initialize a table 
    // to store results of subproblems
    $dp = str_repeat ("\0", 256);
    $dp[0] = 1;
      
    // Fill table in 
    // bottom up manner
    for ($i = 0; $i < $n; $i++)
    for ($j = $coeff[$i]; 
         $j <= $rhs; $j++)
        $dp[$j] = $dp[$j] + ($dp[$j - 
                             $coeff[$i]]);
  
    return $dp[$rhs];
}
  
// Driver Code
$coeff = array(2, 2, 5);
$rhs = 4;
  
// $n = count($coeff);
$n = sizeof($coeff) / sizeof($coeff[0]);
echo countSol($coeff, $n, $rhs);
  
// This code is contributed 
// by shiv_bhakt.
?>

Output :

Time Complexity of above solution is O(n * rhs)


This article is contributed by Ashish Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal, jit_t, shiv_bhakt

1080
Chapter 145. Find number of solutions of a linear equation of n variables

Source

https://www.geeksforgeeks.org/find-number-of-solutions-of-a-linear-equation-of-n-variables/

1081
Chapter 146

Find number of times a string


occurs as a subsequence in given
string

Find number of times a string occurs as a subsequence in given string - GeeksforGeeks


Given two strings, find the number of times the second string occurs in the first string,
whether continuous or discontinuous.
Examples:

Input:
string a = "GeeksforGeeks"
string b = "Gks"

Output: 4

Explanation:
The four strings are - (Check characters marked in bold)
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks
GeeksforGeeks

If we carefully analyze the given problem, we can see that it can be easily divided into
sub-problems. The idea is to process all characters of both strings one by one staring from
either from left or right side. Let us traverse from right corner, there are two possibilities
for every pair of character being traversed.

1082
Chapter 146. Find number of times a string occurs as a subsequence in given string

m: Length of str1 (first string)


n: Length of str2 (second string)

If last characters of two strings are same,


1. We consider last characters and get count for remaining
strings. So we recur for lengths m-1 and n-1.
2. We can ignore last character of first string and
recurse for lengths m-1 and n.
else
If last characters are not same,
We ignore last character of first string and
recurse for lengths m-1 and n.

Below is the implementation of above Naive recursive solution –

C++

// A Naive recursive C++ program to find the number of


// times the second string occurs in the first string,
// whether continuous or discontinuous
#include <iostream>
using namespace std;
  
// Recursive function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
int count(string a, string b, int m, int n)
{
    // If both first and second string is empty,
    // or if second string is empty, return 1
    if ((m == 0 && n == 0) || n == 0)
        return 1;
  
    // If only first string is empty and second
    // string is not empty, return 0
    if (m == 0)
        return 0;
  
    // If last characters are same
    // Recur for remaining strings by
    // 1. considering last characters of both strings
    // 2. ignoring last character of first string
    if (a[m - 1] == b[n - 1])
        return count(a, b, m - 1, n - 1) +
               count(a, b, m - 1, n);
    else
        // If last characters are different, ignore 

1083
Chapter 146. Find number of times a string occurs as a subsequence in given string

        // last char of first string and recur for 


        // remaining string
        return count(a, b, m - 1, n);
}
  
// Driver code
int main()
{
    string a = "GeeksforGeeks";
    string b = "Gks";
  
    cout << count(a, b, a.size(), b.size()) << endl;
  
    return 0;
}

Java

// A Naive recursive java program to find the number of


// times the second string occurs in the first string,
// whether continuous or discontinuous
import java.io.*;
  
class GFG 
{
      
    // Recursive function to find the number of times
    // the second string occurs in the first string,
    // whether continuous or discontinuous
    static int count(String a, String b, int m, int n)
    {
        // If both first and second string is empty,
        // or if second string is empty, return 1
        if ((m == 0 && n == 0) || n == 0)
            return 1;
      
        // If only first string is empty and 
        // second string is not empty, return 0
        if (m == 0)
            return 0;
      
        // If last characters are same
        // Recur for remaining strings by
        // 1. considering last characters of 
        // both strings
        // 2. ignoring last character of 
        // first string
        if (a.charAt(m - 1) == b.charAt(n - 1))

1084
Chapter 146. Find number of times a string occurs as a subsequence in given string

            return count(a, b, m - 1, n - 1) +
                   count(a, b, m - 1, n);
        else
            // If last characters are different,  
            // ignore last char of first string 
            // and recur for  remaining string
            return count(a, b, m - 1, n);
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        String a = "GeeksforGeeks";
        String b = "Gks";
        System.out.println( count(a, b, a.length(), b.length())) ;
      
    }
}
  
// This code is contributed by vt_m

C#

// A Naive recursive C# program to find the number of


// times the second string occurs in the first string,
// whether continuous or discontinuous
using System;
   
class GFG 
{
       
    // Recursive function to find the number of times
    // the second string occurs in the first string,
    // whether continuous or discontinuous
    static int count(string a, string b, int m, int n)
    {
        // If both first and second string is empty,
        // or if second string is empty, return 1
        if ((m == 0 && n == 0) || n == 0)
            return 1;
       
        // If only first string is empty and 
        // second string is not empty, return 0
        if (m == 0)
            return 0;
       
        // If last characters are same
        // Recur for remaining strings by

1085
Chapter 146. Find number of times a string occurs as a subsequence in given string

        // 1. considering last characters of 


        // both strings
        // 2. ignoring last character of 
        // first string
        if (a[m - 1] == b[n - 1])
            return count(a, b, m - 1, n - 1) +
                   count(a, b, m - 1, n);
        else
            // If last characters are different,  
            // ignore last char of first string 
            // and recur for  remaining string
            return count(a, b, m - 1, n);
    }
       
    // Driver code
    public static void Main () 
    {
        string a = "GeeksforGeeks";
        string b = "Gks";
        Console.Write( count(a, b, a.Length, b.Length) );
       
    }
}
   
// This code is contributed by nitin mittal

Output:

The time complexity of above solution is exponential. If we carefully analyze, we can


see that many sub-problems are solved again and again. Since same sub-problems are
called again, this problem has Overlapping sub-problems property. So the problem has
both properties (see this and this) of a dynamic programming problem. Like other typical
Dynamic Programming problems, re-computations of same sub-problems can be avoided by
constructing a temporary array that stores results of sub-problems.
Below is its implementation using Dynamic Programming –

C++

// A Dynamic Programming based C++ program to find the


// number of times the second string occurs in the first
// string, whether continuous or discontinuous
#include <iostream>
using namespace std;

1086
Chapter 146. Find number of times a string occurs as a subsequence in given string

  
// Iterative DP function to find the number of times
// the second string occurs in the first string,
// whether continuous or discontinuous
int count(string a, string b)
{
    int m = a.length();
    int n = b.length();
  
    // Create a table to store results of sub-problems
    int lookup[m + 1][n + 1] = { { 0 } };
  
    // If first string is empty
    for (int i = 0; i <= n; ++i)
        lookup[0][i] = 0;
  
    // If second string is empty
    for (int i = 0; i <= m; ++i)
        lookup[i][0] = 1;
  
    // Fill lookup[][] in bottom up manner
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            // If last characters are same, we have two 
            // options -
            // 1. consider last characters of both strings
            //    in solution
            // 2. ignore last character of first string
            if (a[i - 1] == b[j - 1])
                lookup[i][j] = lookup[i - 1][j - 1] + 
                               lookup[i - 1][j];
                  
            else
                // If last character are different, ignore
                // last character of first string
                lookup[i][j] = lookup[i - 1][j];
        }
    }
  
    return lookup[m][n];
}
  
// Driver code
int main()
{
    string a = "GeeksforGeeks";

1087
Chapter 146. Find number of times a string occurs as a subsequence in given string

    string b = "Gks";
  
    cout << count(a, b);
  
    return 0;
}

Java

// A Dynamic Programming based 


// Java program to find the 
// number of times the second 
// string occurs in the first
// string, whether continuous 
// or discontinuous
import java.io.*;
  
class GFG 
{
      
// Iterative DP function to 
// find the number of times 
// the second string occurs
// in the first string, whether
// continuous or discontinuous
static int count(String a, String b)
{
    int m = a.length();
    int n = b.length();
  
    // Create a table to store
    // results of sub-problems
    int lookup[][] = new int[m + 1][n + 1];
  
    // If first string is empty
    for (int i = 0; i <= n; ++i)
        lookup[0][i] = 0;
  
    // If second string is empty
    for (int i = 0; i <= m; ++i)
        lookup[i][0] = 1;
  
    // Fill lookup[][] in 
    // bottom up manner
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {

1088
Chapter 146. Find number of times a string occurs as a subsequence in given string

            // If last characters are 


            // same, we have two options -
            // 1. consider last characters 
            //    of both strings in solution
            // 2. ignore last character
            //    of first string
            if (a.charAt(i - 1) == b.charAt(j - 1))
                lookup[i][j] = lookup[i - 1][j - 1] + 
                               lookup[i - 1][j];
                  
            else
                // If last character are 
                // different, ignore last
                // character of first string
                lookup[i][j] = lookup[i - 1][j];
        }
    }
  
    return lookup[m][n];
}
  
// Driver Code
public static void main (String[] args)
{
    String a = "GeeksforGeeks";
    String b = "Gks";
      
    System.out.println(count(a, b));
}
}
  
// This code is contributed by anuj_67.

Output:

Time complexity of above solutions is O(MN).


Auxiliary space used by the program is O(MN).
This article is contributed by Aditya Goel. If you like GeeksforGeeks and would like to
contribute, you can also write an article using contribute.GeeksforGeeks.org or mail your
article to [email protected]. See your article appearing on the GeeksforGeeks
main page and help other Geeks.
Improved By : nitin mittal, vt_m

1089
Chapter 146. Find number of times a string occurs as a subsequence in given string

Source

https://www.geeksforgeeks.org/find-number-times-string-occurs-given-string/

1090
Chapter 147

Find the Longest Increasing


Subsequence in Circular manner

Find the Longest Increasing Subsequence in Circular manner - GeeksforGeeks


Given an array, the task is to find to LIS (Longest Increasing Subsequence) in a circular
way.
Examples :

Input : arr[] = {5, 4, 3, 2, 1}


Output : 2
Although there is no LIS in a given array
but in a circular form there can be
{1, 5}, {2, 5}, ......

Input : arr[]= {5, 6, 7, 1, 2, 3}


Output : 6
{1, 2, 3, 5, 6, 7} will be the LIS in the
circular manner.

1. Append the same elements(i.e. whole array) with the given array.
2. For every window of size n(no. of elements in the given array), perform LIS.
3. Return maximum length.

For example : Given array is {1, 4, 6, 2, 3}

After appending elements resultant array


will be {1, 4, 6, 2, 3, 1, 4, 6, 2, 3}.

Now for every consecutive n elements perform LIS.

1091
Chapter 147. Find the Longest Increasing Subsequence in Circular manner

1- {1, 4, 6, 2, 3} --3 is length of LIS.


2- {4, 6, 2, 3, 1} --2 is length of LIS.
3- {6, 2, 3, 1, 4} --3
4- {2, 3, 1, 4, 6}-- 4 {2, 3, 4, 6}
5- {3, 1, 4, 6, 2} --3.
6- {1, 4, 6, 2, 3} Original list.

So, maximum length of LIS in circular manner is 4.

As in the last window we will have the same elements as in the given array which we
don’t need to compute again, so we can append only n-1 elements to reduce the number of
operations.

C++

// C++ implementation to find LIS in circular way


#include<bits/stdc++.h>
using namespace std;
  
// Utility function to find LIS using Dynamic programming
int computeLIS(int circBuff[], int start, int end, int n)
{
    int LIS[end-start];
  
    /* Initialize LIS values for all indexes */
    for (int i = start; i < end; i++)
        LIS[i] = 1;
  
    /* Compute optimized LIS values in bottom up manner */
    for (int i = start + 1; i < end; i++)
  
        // Set j on the basis of current window
        // i.e. first element of the current window
        for (int j = start; j < i; j++ )
            if (circBuff[i] > circBuff[j] && LIS[i] < LIS[j] + 1)
                LIS[i] = LIS[j] + 1;
  
    /* Pick maximum of all LIS values */
    int res = INT_MIN;
    for (int i = start; i < end; i++)
        res = max(res, LIS[i]);
  
    return res;
}
  
// Function to find Longest Increasing subsequence in
// Circular manner

1092
Chapter 147. Find the Longest Increasing Subsequence in Circular manner

int LICS(int arr[], int n)


{
    // Make a copy of given array by appending same
    // array elements  to itself
    int circBuff[2 * n];
    for (int i = 0; i<n; i++)
        circBuff[i] = arr[i];
    for (int i = n; i < 2*n; i++)
        circBuff[i] = arr[i-n];
  
    // Perform LIS for each window of size n
    int res = INT_MIN;
    for (int i=0; i<n; i++)
        res = max(computeLIS(circBuff, i, i + n, n), res);
  
    return res;
}
  
/* Driver program to test above function */
int main()
{
    int arr[] = { 1, 4, 6, 2, 3 };
    int n = sizeof(arr)/sizeof(arr[0]);
  
    cout << "Length of LICS is " << LICS( arr, n );
    return 0;
}

Java

// Java implementation to find LIS in circular way


  
class Test
{
    // Utility method to find LIS using Dynamic programming
    static int computeLIS(int circBuff[], int start, int end, int n)
    {
        int LIS[] = new int[n+end-start];
       
        /* Initialize LIS values for all indexes */
        for (int i = start; i < end; i++)
            LIS[i] = 1;
       
        /* Compute optimized LIS values in bottom up manner */
        for (int i = start + 1; i < end; i++)
       
            // Set j on the basis of current window
            // i.e. first element of the current window

1093
Chapter 147. Find the Longest Increasing Subsequence in Circular manner

            for (int j = start; j < i; j++ )


                if (circBuff[i] > circBuff[j] && LIS[i] < LIS[j] + 1)
                    LIS[i] = LIS[j] + 1;
       
        /* Pick maximum of all LIS values */
        int res = Integer.MIN_VALUE;
        for (int i = start; i < end; i++)
            res = Math.max(res, LIS[i]);
       
        return res;
    }
       
    // Function to find Longest Increasing subsequence in
    // Circular manner
    static int LICS(int arr[], int n)
    {
        // Make a copy of given array by appending same
        // array elements  to itself
        int circBuff[] = new int[2 * n];
        for (int i = 0; i<n; i++)
            circBuff[i] = arr[i];
        for (int i = n; i < 2*n; i++)
            circBuff[i] = arr[i-n];
       
        // Perform LIS for each window of size n
        int res = Integer.MIN_VALUE;
        for (int i=0; i<n; i++)
            res = Math.max(computeLIS(circBuff, i, i + n, n), res);
       
        return res;
    }
  
    // Driver method
    public static void main(String args[])
    {
         int arr[] = { 1, 4, 6, 2, 3 };
         System.out.println("Length of LICS is " + LICS( arr, arr.length));
    }
}

C#

// C# implementation to find 
// LIS in circular way
using System;
  
class Test
{

1094
Chapter 147. Find the Longest Increasing Subsequence in Circular manner

    // Utility method to find LIS


    // using Dynamic programming
    static int computeLIS(int []circBuff, int start, 
                                     int end, int n)
    {
        int []LIS = new int[n+end-start];
      
        /* Initialize LIS values for all indexes */
        for (int i = start; i < end; i++)
            LIS[i] = 1;
      
        /* Compute optimized LIS values 
           in bottom up manner */
        for (int i = start + 1; i < end; i++)
      
            // Set j on the basis of current window
            // i.e. first element of the current window
            for (int j = start; j < i; j++ )
                if (circBuff[i] > circBuff[j] && 
                            LIS[i] < LIS[j] + 1)
                    LIS[i] = LIS[j] + 1;
      
        /* Pick maximum of all LIS values */
        int res = int.MinValue;
        for (int i = start; i < end; i++)
            res = Math.Max(res, LIS[i]);
      
        return res;
    }
      
    // Function to find Longest Increasing 
    // subsequence in Circular manner
    static int LICS(int []arr, int n)
    {
        // Make a copy of given array by 
        // appending same array elements to itself
        int []circBuff = new int[2 * n];
          
        for (int i = 0; i<n; i++)
            circBuff[i] = arr[i];
        for (int i = n; i < 2*n; i++)
            circBuff[i] = arr[i-n];
      
        // Perform LIS for each window of size n
        int res = int.MinValue;
        for (int i=0; i<n; i++)
            res = Math.Max(computeLIS(circBuff, i, i + n, n), res);
      

1095
Chapter 147. Find the Longest Increasing Subsequence in Circular manner

        return res;
    }
  
    // Driver method
    public static void Main()
    {
        int []arr = {1, 4, 6, 2, 3};
        Console.Write("Length of LICS is " + 
                    LICS( arr, arr.Length));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP implementation to
// find LIS in circular way
  
// Utility function to find 
// LIS using Dynamic programming
function computeLIS($circBuff, 
                    $start, 
                    $end, $n)
{
    $LIS = Array();
  
    /* Initialize LIS values
    for all indexes */
    for ($i = $start; $i < $end; $i++)
        $LIS[$i] = 1;
  
    /* Compute optimized LIS 
    values in bottom up manner */
    for ($i = $start + 1; $i < $end; $i++)
  
        // Set j on the basis of
        // current window
        // i.e. first element of
        // the current window
        for ( $j = $start; $j < $i; $j++ )
            if ($circBuff[$i] > $circBuff[$j] && 
                     $LIS[$i] < $LIS[$j] + 1)
                $LIS[$i] = $LIS[$j] + 1;
  
    /* Pick maximum of
    all LIS values */

1096
Chapter 147. Find the Longest Increasing Subsequence in Circular manner

    $res = PHP_INT_MIN;
    for ($i = $start; $i < $end; $i++)
        $res = max($res, $LIS[$i]);
  
    return $res;
}
  
// Function to find LIS 
// in Circular manner
function LICS($arr, $n)
{
    // Make a copy of given array
    // by appending same array
    // elements to itself
    for ($i = 0; $i < $n; $i++)
        $circBuff[$i] = $arr[$i];
    for ($i = $n; $i < 2 * $n; $i++)
        $circBuff[$i] = $arr[$i - $n];
  
    // Perform LIS for each 
    // window of size n
    $res = PHP_INT_MIN;
    for ($i = 0; $i < $n; $i++)
        $res = max(computeLIS($circBuff, $i, 
                              $i + $n, $n), 
                              $res);
  
    return $res;
}
  
// Driver Code
$arr = array(1, 4, 6, 2, 3);
$n = sizeof($arr);
  
echo "Length of LICS is " , 
            LICS($arr, $n);
      
// This code is contributed by aj_36
?>

Output :

Length of LICS is 4

Time complexity of above solution is O(n3 ). It can be reduced O(n2 Log n) using O(n Log
n) algorithm to find LIS.

1097
Chapter 147. Find the Longest Increasing Subsequence in Circular manner

Reference :
https://www.careercup.com/question?id=5942735794077696
Improved By : nitin mittal, jit_t

Source

https://www.geeksforgeeks.org/find-longest-increasing-subsequence-circular-manner/

1098
Chapter 148

Find the largest area


rectangular sub-matrix whose
sum is equal to k

Find the largest area rectangular sub-matrix whose sum is equal to k - GeeksforGeeks
Given a 2D matrix mat[][] and a value k. Find the largest rectangular sub-matrix whose
sum is equal to k.
Example:

Input : mat = { { 1, 7, -6, 5 },


{ -8, 6, 7, -2 },
{ 10, -15, 3, 2 },
{ -5, 2, 0, 9 } }
k = 7

Output : (Top, Left): (0, 1)


(Bottom, Right): (2, 3)
7 -6 5
6 7 -2
-15 3 2

Naive Approach: Check every possible rectangle in given 2D array having sum equal to
‘k’ and print the largest one. This solution requires 4 nested loops and time complexity of
this solution would be O(n^4).
Efficient Approach: Longest sub-array having sum k for 1-D array can be used to reduce
the time complexity to O(n^3). The idea is to fix the left and right columns one by one
and find the longest sub-array having sum equal to ‘k’ for contiguous rows for every left and
right column pair. We basically find top and bottom row numbers (which are part of the

1099
Chapter 148. Find the largest area rectangular sub-matrix whose sum is equal to k

largest sub-matrix) for every fixed left and right column pair. To find the top and bottom
row numbers, calculate sum of elements in every row from left to right and store these sums
in an array say temp[]. So temp[i] indicates sum of elements from left to right in row i.
Now, apply Longest sub-array having sum k 1D algorithm on temp[], and get the longest
sub-array having sum equal to ‘k’ of temp[]. This length would be the maximum possible
length with left and right as boundary columns. Set the ‘top’ and ‘bottom’ row indexes for
the left right column pair and calculate the area. In similar manner get the top, bottom,
left, right indexes for other sub-matrices having sum equal to ‘k’ and print the one having
maximum area.

// C++ implementation to find the largest area rectangular


// sub-matrix whose sum is equal to k
#include <bits/stdc++.h>
using namespace std;
  
const int MAX = 100;
  
// This function basically finds largest 'k'
// sum subarray in arr[0..n-1]. If 'k' sum
// doesn't exist, then it returns false. Else
// it returns true and sets starting and
// ending indexes as start and end.
bool sumEqualToK(int arr[], int& start,
                 int& end, int n, int k)
{
    // unordered_map 'um' implemented
    // as hash table
    unordered_map<int, int> um;
    int sum = 0, maxLen = 0;
  
    // traverse the given array
    for (int i = 0; i < n; i++) {
  
        // accumulate sum
        sum += arr[i];
  
        // when subarray starts from index '0'
        // update maxLength and start and end points
        if (sum == k) {
            maxLen = i + 1;
            start = 0;
            end = i;
        }
  
        // make an entry for 'sum' if it is
        // not present in 'um'
        if (um.find(sum) == um.end())
            um[sum] = i;

1100
Chapter 148. Find the largest area rectangular sub-matrix whose sum is equal to k

  
        // check if 'sum-k' is present in 'um'
        // or not
        if (um.find(sum - k) != um.end()) {
  
            // update maxLength and start and end points
            if (maxLen < (i - um[sum - k])) {
                maxLen = i - um[sum - k];
                start = um[sum - k] + 1;
                end = i;
            }
        }
    }
  
    // Return true if maximum length is non-zero
    return (maxLen != 0);
}
  
// function to find the largest area rectangular
// sub-matrix whose sum is equal to k
void sumZeroMatrix(int mat[][MAX], int row, int col, int k)
{
    // Variables to store the temporary values
    int temp[row], area;
    bool sum;
    int up, down;
  
    // Variables to store the final output
    int fup = 0, fdown = 0, fleft = 0, fright = 0;
    int maxArea = INT_MIN;
  
    // Set the left column
    for (int left = 0; left < col; left++) {
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
  
        // Set the right column for the left column
        // set by outer loop
        for (int right = left; right < col; right++) {
            // Calculate sum between current left
            // and right column for every row 'i'
            for (int i = 0; i < row; i++)
                temp[i] += mat[i][right];
  
            // Find largest subarray with 'k' sum in
            // temp[]. The sumEqualToK() function also
            // sets values of 'up' and 'down;'. So
            // if 'sum' is true then rectangle exists between

1101
Chapter 148. Find the largest area rectangular sub-matrix whose sum is equal to k

            // (up, left) and (down, right) which are the


            // boundary values.
            sum = sumEqualToK(temp, up, down, row, k);
            area = (down - up + 1) * (right - left + 1);
  
            // Compare no. of elements with previous
            // no. of elements in sub-Matrix.
            // If new sub-matrix has more elements
            // then update maxArea and final boundaries
            // like fup, fdown, fleft, fright
            if (sum && maxArea < area) {
                fup = up;
                fdown = down;
                fleft = left;
                fright = right;
                maxArea = area;
            }
        }
    }
  
    // If there is no change in boundaries
    // than check if mat[0][0] equals 'k'
    // If it is not equal to 'k' then print
    // that no such k-sum sub-matrix exists
    if (fup == 0 && fdown == 0 && fleft == 0 &&
        fright == 0 && mat[0][0] != k) {
        cout << "No sub-matrix with sum " << k << " exists";
        return;
    }
  
    // Print final values
  
    cout << "(Top, Left): "
         << "(" << fup << ", " << fleft
         << ")" << endl;
  
    cout << "(Bottom, Right): "
         << "(" << fdown << ", " << fright
         << ")" << endl;
  
    for (int j = fup; j <= fdown; j++) {
        for (int i = fleft; i <= fright; i++)
            cout << mat[j][i] << " ";
        cout << endl;
    }
}
  
// Driver program to test above

1102
Chapter 148. Find the largest area rectangular sub-matrix whose sum is equal to k

int main()
{
    int mat[][MAX] = { { 1, 7, -6, 5 },
                       { -8, 6, 7, -2 },
                       { 10, -15, 3, 2 },
                       { -5, 2, 0, 9 } };
  
    int row = 4, col = 4;
    int k = 7;
    sumZeroMatrix(mat, row, col, k);
    return 0;
}

Output:

(Top, Left): (0, 1)


(Bottom, Right): (2, 3)
7 -6 5
6 7 -2
-15 3 2

Time Complexity: O(n^3).


Auxiliary Space: O(n).

Source

https://www.geeksforgeeks.org/find-the-largest-area-rectangular-sub-matrix-whose-sum-is-equal-to-k/

1103
Chapter 149

Find the longest path in a


matrix with given constraints

Find the longest path in a matrix with given constraints - GeeksforGeeks


Given a n*n matrix where all numbers are distinct, find the maximum length path (starting
from any cell) such that all cells along the path are in increasing order with a difference of
1.
We can move in 4 directions from a given cell (i, j), i.e., we can move to (i+1, j) or (i, j+1)
or (i-1, j) or (i, j-1) with the condition that the adjacent cells have a difference of 1.
Example:

Input: mat[][] = {{1, 2, 9}


{5, 3, 8}
{4, 6, 7}}
Output: 4
The longest path is 6-7-8-9.

The idea is simple, we calculate longest path beginning with every cell. Once we have
computed longest for all cells, we return maximum of all longest paths. One important
observation in this approach is many overlapping subproblems. Therefore this problem can
be optimally solved using Dynamic Programming.
Below is Dynamic Programming based implementation that uses a lookup table dp[][] to
check if a problem is already solved or not.
C/C++

#include<bits/stdc++.h>
#define n 3
using namespace std;

1104
Chapter 149. Find the longest path in a matrix with given constraints

  
// Returns length of the longest path beginning with mat[i][j].
// This function mainly uses lookup table dp[n][n]
int findLongestFromACell(int i, int j, int mat[n][n], int dp[n][n])
{
    // Base case
    if (i<0 || i>=n || j<0 || j>=n)
        return 0;
  
    // If this subproblem is already solved
    if (dp[i][j] != -1)
        return dp[i][j];
  
    // Since all numbers are unique and in range from 1 to n*n,
    // there is atmost one possible direction from any cell
    if (j<n-1 && ((mat[i][j] +1) == mat[i][j+1]))
       return dp[i][j] = 1 + findLongestFromACell(i,j+1,mat,dp);
  
    if (j>0 && (mat[i][j] +1 == mat[i][j-1]))
       return dp[i][j] = 1 + findLongestFromACell(i,j-1,mat,dp);
  
    if (i>0 && (mat[i][j] +1 == mat[i-1][j]))
       return dp[i][j] = 1 + findLongestFromACell(i-1,j,mat,dp);
  
    if (i<n-1 && (mat[i][j] +1 == mat[i+1][j]))
       return dp[i][j] = 1 + findLongestFromACell(i+1,j,mat,dp);
  
    // If none of the adjacent fours is one greater
    return dp[i][j] = 1;
}
  
// Returns length of the longest path beginning with any cell
int finLongestOverAll(int mat[n][n])
{
    int result = 1;  // Initialize result
  
    // Create a lookup table and fill all entries in it as -1
    int dp[n][n];
    memset(dp, -1, sizeof dp);
  
    // Compute longest path beginning from all cells
    for (int i=0; i<n; i++)
    {
      for (int j=0; j<n; j++)
       {
          if (dp[i][j] == -1)
             findLongestFromACell(i, j, mat, dp);
  

1105
Chapter 149. Find the longest path in a matrix with given constraints

          //  Update result if needed


          result = max(result, dp[i][j]);
       }
     }
  
     return result;
}
  
// Driver program
int main()
{
   int  mat[n][n] = {{1, 2, 9},
                    {5, 3, 8},
                    {4, 6, 7}};
   cout << "Length of the longest path is "
        << finLongestOverAll(mat);
   return 0;
}

Java

// Java program to find the longest path in a matrix


// with given constraints
  
class GFG 
{
    public static int n = 3;
      
    // Function that returns length of the longest path 
    // beginning with mat[i][j]
    // This function mainly uses lookup table dp[n][n]
    static int findLongestFromACell(int i, int j, int mat[][], int dp[][])
    {
        // Base case
        if (i<0 || i>=n || j<0 || j>=n)
            return 0;
   
        // If this subproblem is already solved
        if (dp[i][j] != -1)
            return dp[i][j];
   
        // Since all numbers are unique and in range from 1 to n*n,
        // there is atmost one possible direction from any cell
        if (j<n-1 && ((mat[i][j] +1) == mat[i][j+1]))
            return dp[i][j] = 1 + findLongestFromACell(i,j+1,mat,dp);
   
        if (j>0 && (mat[i][j] +1 == mat[i][j-1]))
            return dp[i][j] = 1 + findLongestFromACell(i,j-1,mat,dp);

1106
Chapter 149. Find the longest path in a matrix with given constraints

   
        if (i>0 && (mat[i][j] +1 == mat[i-1][j]))
            return dp[i][j] = 1 + findLongestFromACell(i-1,j,mat,dp);
   
        if (i<n-1 && (mat[i][j] +1 == mat[i+1][j]))
            return dp[i][j] = 1 + findLongestFromACell(i+1,j,mat,dp);
   
        // If none of the adjacent fours is one greater
        return dp[i][j] = 1;
    }
      
    // Function that returns length of the longest path
    // beginning with any cell
    static int finLongestOverAll(int mat[][])
    {
        // Initialize result
        int result = 1;  
   
        // Create a lookup table and fill all entries in it as -1
        int[][] dp = new int[n][n];
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                dp[i][j] = -1;
   
        // Compute longest path beginning from all cells
        for (int i=0; i<n; i++)
        {
            for (int j=0; j<n; j++)
            {
                if (dp[i][j] == -1)
                    findLongestFromACell(i, j, mat, dp);
   
                //  Update result if needed
                result = Math.max(result, dp[i][j]);
            }
        }
   
        return result;
    }
      
    // driver program
    public static void main (String[] args) 
    {
        int  mat[][] = { {1, 2, 9},
                         {5, 3, 8},
                         {4, 6, 7} };
        System.out.println("Length of the longest path is " + 
                            finLongestOverAll(mat));

1107
Chapter 149. Find the longest path in a matrix with given constraints

    }
}
  
// Contributed by Pramod Kumar

Output:

Length of the longest path is 4

Time complexity of the above solution is O(n2 ). It may seem more at first look. If we take
a closer look, we can notice that all values of dp[i][j] are computed only once.
This article is contributed by Ekta Goel. Please write comments if you find anything incor-
rect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/find-the-longest-path-in-a-matrix-with-given-constraints/

1108
Chapter 150

Find the minimum cost to reach


destination using a train

Find the minimum cost to reach destination using a train - GeeksforGeeks


There are N stations on route of a train. The train goes from station 0 to N-1. The ticket
cost for all pair of stations (i, j) is given where j is greater than i. Find the minimum cost
to reach the destination.
Consider the following example:

Input:
cost[N][N] = { {0, 15, 80, 90},
{INF, 0, 40, 50},
{INF, INF, 0, 70},
{INF, INF, INF, 0}
};
There are 4 stations and cost[i][j] indicates cost to reach j
from i. The entries where j < i are meaningless.

Output:
The minimum cost is 65
The minimum cost can be obtained by first going to station 1
from 0. Then from station 1 to station 3.

We strongly recommend to minimize your browser and try this yourself first.
The minimum cost to reach N-1 from 0 can be recursively written as following:

minCost(0, N-1) = MIN { cost[0][n-1],


cost[0][1] + minCost(1, N-1),

1109
Chapter 150. Find the minimum cost to reach destination using a train

minCost(0, 2) + minCost(2, N-1),


........,
minCost(0, N-2) + cost[N-2][n-1] }

The following is the implementation of above recursive formula.


C++

// A naive recursive solution to find min cost path from station 0


// to station N-1
#include<iostream>
#include<climits>
using namespace std;
  
// infinite value
#define INF INT_MAX
  
// Number of stations
#define N 4
  
// A recursive function to find the shortest path from
// source 's' to destination 'd'.
int minCostRec(int cost[][N], int s, int d)
{
    // If source is same as destination
    // or destination is next to source
    if (s == d || s+1 == d)
      return cost[s][d];
  
    // Initialize min cost as direct ticket from
    // source 's' to destination 'd'.
    int min = cost[s][d];
  
    // Try every intermediate vertex to find minimum
    for (int i = s+1; i<d; i++)
    {
        int c = minCostRec(cost, s, i) +
                minCostRec(cost, i, d);
        if (c < min)
           min = c;
    }
    return min;
}
  
// This function returns the smallest possible cost to
// reach station N-1 from station 0. This function mainly
// uses minCostRec().
int minCost(int cost[][N])

1110
Chapter 150. Find the minimum cost to reach destination using a train

{
    return minCostRec(cost, 0, N-1);
}
  
// Driver program to test above function
int main()
{
    int cost[N][N] = { {0, 15, 80, 90},
                      {INF, 0, 40, 50},
                      {INF, INF, 0, 70},
                      {INF, INF, INF, 0}
                    };
    cout << "The Minimum cost to reach station "
          << N << " is " << minCost(cost);
    return 0;
}

Java

// A naive recursive solution to find min cost path from station 0


// to station N-1
class shortest_path
{
  
    static int INF = Integer.MAX_VALUE,N = 4;
    // A recursive function to find the shortest path from
    // source 's' to destination 'd'.
    static int minCostRec(int cost[][], int s, int d)
    {
        // If source is same as destination
        // or destination is next to source
        if (s == d || s+1 == d)
          return cost[s][d];
       
        // Initialize min cost as direct ticket from
        // source 's' to destination 'd'.
        int min = cost[s][d];
       
        // Try every intermediate vertex to find minimum
        for (int i = s+1; i<d; i++)
        {
            int c = minCostRec(cost, s, i) +
                    minCostRec(cost, i, d);
            if (c < min)
               min = c;
        }
        return min;
    }

1111
Chapter 150. Find the minimum cost to reach destination using a train

       
    // This function returns the smallest possible cost to
    // reach station N-1 from station 0. This function mainly
    // uses minCostRec().
    static int minCost(int cost[][])
    {
        return minCostRec(cost, 0, N-1);
    }
  
    public static void main(String args[])
    {
        int cost[][] = { {0, 15, 80, 90},
                      {INF, 0, 40, 50},
                      {INF, INF, 0, 70},
                      {INF, INF, INF, 0}
                    };
        System.out.println("The Minimum cost to reach station "+ N+
                                               " is "+minCost(cost));
    }
  
}/* This code is contributed by Rajat Mishra */

Python

# Python program to find min cost path 


# from station 0 to station N-1
  
global N
N = 4
def minCostRec(cost, s, d):
  
    if s == d or s+1 == d:
        return cost[s][d]
  
    min = cost[s][d]
  
    for i in range(s+1, d):
        c = minCostRec(cost,s, i) + minCostRec(cost, i, d)
        if c < min:
            min = c
    return min
  
def minCost(cost):
    return minCostRec(cost, 0, N-1)
cost = [ [0, 15, 80, 90],
         [float("inf"), 0, 40, 50],
         [float("inf"), float("inf"), 0, 70],
         [float("inf"), float("inf"), float("inf"), 0]

1112
Chapter 150. Find the minimum cost to reach destination using a train

        ]
print "The Minimum cost to reach station %d is %d" % \
                                    (N, minCost(cost))
                                      
# This code is contributed by Divyanshu Mehta

C#

// A naive recursive solution to find min


// cost path from station 0 to station N-1
using System;
  
class GFG {
      
    static int INF = int.MaxValue, N = 4;
      
    // A recursive function to find the
    // shortest path from source 's' to
    // destination 'd'.
    static int minCostRec(int [,]cost, int s, int d)
    {
          
        // If source is same as destination
        // or destination is next to source
        if (s == d || s + 1 == d)
        return cost[s,d];
      
        // Initialize min cost as direct
        // ticket from source 's' to 
        // destination 'd'.
        int min = cost[s,d];
      
        // Try every intermediate vertex to
        // find minimum
        for (int i = s + 1; i < d; i++)
        {
            int c = minCostRec(cost, s, i) +
                       minCostRec(cost, i, d);
                         
            if (c < min)
            min = c;
        }
          
        return min;
    }
      
    // This function returns the smallest
    // possible cost to reach station N-1 

1113
Chapter 150. Find the minimum cost to reach destination using a train

    // from station 0. This function mainly


    // uses minCostRec().
    static int minCost(int [,]cost)
    {
        return minCostRec(cost, 0, N-1);
    }
  
    // Driver code
    public static void Main()
    {
        int [,]cost = { {0, 15, 80, 90},
                        {INF, 0, 40, 50},
                        {INF, INF, 0, 70},
                        {INF, INF, INF, 0} };
        Console.WriteLine("The Minimum cost to"
                         + " reach station "+ N
                        + " is "+minCost(cost));
    }
}
  
// This code is contributed by Sam007.

Output:

The Minimum cost to reach station 4 is 65

Time complexity of the above implementation is exponential as it tries every possible path
from 0 to N-1. The above solution solves same subrpoblems multiple times (it can be seen
by drawing recursion tree for minCostPathRec(0, 5).
Since this problem has both properties of dynamic programming problems ((see thisand
this). Like other typical Dynamic Programming(DP) problems, re-computations of same
subproblems can be avoided by storing the solutions to subproblems and solving problems
in bottom up manner.
One dynamic programming solution is to create a 2D table and fill the table using above
given recursive formula. The extra space required in this solution would be O(N2 ) and time
complexity would be O(N3 )
We can solve this problem using O(N) extra space and O(N2 ) time. The idea is based on
the fact that given input matrix is a Directed Acyclic Graph (DAG). The shortest path in
DAG can be calculated using the approach discussed in below post.
Shortest Path in Directed Acyclic Graph
We need to do less work here compared to above mentioned post as we know topological
sorting of the graph. The topological sorting of vertices here is 0, 1, ..., N-1. Following is
the idea once topological sorting is known.
The idea in below code is to first calculate min cost for station 1, then for station 2, and so
on. These costs are stored in an array dist[0...N-1].

1114
Chapter 150. Find the minimum cost to reach destination using a train

1) The min cost for station 0 is 0, i.e., dist[0] = 0


2) The min cost for station 1 is cost[0][1], i.e., dist[1] = cost[0][1]
3) The min cost for station 2 is minimum of following two.
a) dist[0] + cost[0][2]
b) dist[1] + cost[1][2]
3) The min cost for station 3 is minimum of following three.
a) dist[0] + cost[0][3]
b) dist[1] + cost[1][3]
c) dist[2] + cost[2][3]
Similarly, dist[4], dist[5], ... dist[N-1] are calculated.
Below is the implementation of above idea.

C++

// A Dynamic Programming based solution to find min cost


// to reach station N-1 from station 0.
#include<iostream>
#include<climits>
using namespace std;
  
#define INF INT_MAX
#define N 4
  
// This function returns the smallest possible cost to
// reach station N-1 from station 0.
int minCost(int cost[][N])
{
    // dist[i] stores minimum cost to reach station i
    // from station 0.
    int dist[N];
    for (int i=0; i<N; i++)
       dist[i] = INF;
    dist[0] = 0;
  
    // Go through every station and check if using it
    // as an intermediate station gives better path
    for (int i=0; i<N; i++)
       for (int j=i+1; j<N; j++)
          if (dist[j] > dist[i] + cost[i][j])
             dist[j] = dist[i] + cost[i][j];
  
    return dist[N-1];
}
  
// Driver program to test above function

1115
Chapter 150. Find the minimum cost to reach destination using a train

int main()
{
    int cost[N][N] = { {0, 15, 80, 90},
                      {INF, 0, 40, 50},
                      {INF, INF, 0, 70},
                      {INF, INF, INF, 0}
                    };
    cout << "The Minimum cost to reach station "
          << N << " is " << minCost(cost);
    return 0;
}

Java

// A Dynamic Programming based solution to find min cost


// to reach station N-1 from station 0.
class shortest_path
{
  
    static int INF = Integer.MAX_VALUE,N = 4;
    // A recursive function to find the shortest path from
    // source 's' to destination 'd'.
      
    // This function returns the smallest possible cost to
    // reach station N-1 from station 0.
    static int minCost(int cost[][])
    {
        // dist[i] stores minimum cost to reach station i
        // from station 0.
        int dist[] = new int[N];
        for (int i=0; i<N; i++)
           dist[i] = INF;
        dist[0] = 0;
       
        // Go through every station and check if using it
        // as an intermediate station gives better path
        for (int i=0; i<N; i++)
           for (int j=i+1; j<N; j++)
              if (dist[j] > dist[i] + cost[i][j])
                 dist[j] = dist[i] + cost[i][j];
       
        return dist[N-1];
    }
       
  
    public static void main(String args[])
    {
        int cost[][] = { {0, 15, 80, 90},

1116
Chapter 150. Find the minimum cost to reach destination using a train

                      {INF, 0, 40, 50},


                      {INF, INF, 0, 70},
                      {INF, INF, INF, 0}
                    };
        System.out.println("The Minimum cost to reach station "+ N+
                                              " is "+minCost(cost));
    }
  
}/* This code is contributed by Rajat Mishra */

Python3

# A Dynamic Programming based


# solution to find min cost
# to reach station N-1
# from station 0.
  
INF = 2147483647
N = 4
   
# This function returns the
# smallest possible cost to
# reach station N-1 from station 0.
def minCost(cost):
  
    # dist[i] stores minimum
    # cost to reach station i
    # from station 0.
    dist=[0 for i in range(N)]
    for i in range(N):
        dist[i] = INF
    dist[0] = 0
   
    # Go through every station
    # and check if using it
    # as an intermediate station
    # gives better path
    for i in range(N):
        for j in range(i+1,N):
            if (dist[j] > dist[i] + cost[i][j]):
                dist[j] = dist[i] + cost[i][j]
   
    return dist[N-1]
  
   
# Driver program to
# test above function
  

1117
Chapter 150. Find the minimum cost to reach destination using a train

cost= [ [0, 15, 80, 90],


            [INF, 0, 40, 50],
            [INF, INF, 0, 70],
            [INF, INF, INF, 0]]
              
print("The Minimum cost to reach station ",
           N," is ",minCost(cost))
  
# This code is contributed
# by Anant Agarwal.

C#

// A Dynamic Programming based solution


// to find min cost to reach station N-1
// from station 0.
using System;
  
class GFG {
      
    static int INF = int.MaxValue, N = 4;
    // A recursive function to find the
    // shortest path from source 's' to
    // destination 'd'.
      
    // This function returns the smallest
    // possible cost to reach station N-1
    // from station 0.
    static int minCost(int [,]cost)
    {
          
        // dist[i] stores minimum cost
        // to reach station i from 
        // station 0.
        int []dist = new int[N];
          
        for (int i = 0; i < N; i++)
            dist[i] = INF;
              
        dist[0] = 0;
      
        // Go through every station and check
        // if using it as an intermediate
        // station gives better path
        for (int i = 0; i < N; i++)
            for (int j = i + 1; j < N; j++)
                if (dist[j] > dist[i] + cost[i,j])
                    dist[j] = dist[i] + cost[i,j];

1118
Chapter 150. Find the minimum cost to reach destination using a train

      
        return dist[N-1];
    }
      
  
    public static void Main()
    {
        int [,]cost = { {0, 15, 80, 90},
                        {INF, 0, 40, 50},
                        {INF, INF, 0, 70},
                        {INF, INF, INF, 0} };
        Console.WriteLine("The Minimum cost to"
                        + " reach station "+ N
                       + " is "+minCost(cost));
    }
}
  
// This code is contributed by Sam007.

Output:

The Minimum cost to reach station 4 is 65

This article is contributed by Udit Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : Sam007

Source

https://www.geeksforgeeks.org/find-the-minimum-cost-to-reach-a-destination-where-every-station-is-connected-in-

1119
Chapter 151

Find the probability of reaching


all points after N moves from
point N

Find the probability of reaching all points after N moves from point N - GeeksforGeeks
Given N which denotes the initial position of the person on the number line. Also given
L which is the probability of the person of going left. Find the probability of reaching all
points on the number line after N moves from point N. Each move can be either to the left
or to the right.
Examples:

Input: n = 2, l = 0.5
Output: 0.2500 0.0000 0.5000 0.0000 0.2500
The person can reach n-1th position and n+1th position in 2 passes, hence the
probability is 0. The person can reach 0th position by only moving 2 steps
left from index 2, hence the probability of reaching 0th index is 05*0.5=0.25.
Similarly for 2n index, the probability is 0.25.
Input: n = 3, l = 0.1
Output: 0.0010 0.0000 0.0270 0.0000 0.2430 0.0000 0.7290
The person can reach n-1th in three ways, i.e., (llr, lrl, rll) where l denotes left
and r denotes right. Hence the probability of n-1th index is 0.027. Similarly
probabilties for all other points are also calculated.

Approach: Construct an array arr[n+1][2n+1] where each row represents a pass and the
columns represent the points on the line. The maximum a person can move from index N
is to 0th index at left or to 2nth index at right. Initially the probabilities after one pass will
be right for arr[1][n-1] and left for arr[1][n+1]. The n-1 moves which are left will be done,
hence the two possible moves will either be n steps to the right or n steps to the left. So
the recurrence relations for right and left moves for all will be:

1120
Chapter 151. Find the probability of reaching all points after N moves from point N

arr[i][j] += (arr[i – 1][j – 1] * right)


arr[i][j] += (arr[i – 1][j + 1] * left)

The summation of probabilities for all possible moves for any index will be stored in arr[n][i].
Below is the implementation of the above approach:

// Java program to calculate the


// probability of reaching all points
// after N moves from point N
import java.util.*;
class GFG {
  
    // Function to calculate the probabilities
    static void printProbabilities(int n, double left)
    {
        double right = 1 - left;
  
        // Array where row represent the pass and the
        // coloumn represents the points on the line
        double[][] arr = new double[n + 1][2 * n + 1];
  
        // Initially the person can reach left
        // or right with one move
        arr[1][n + 1] = right;
        arr[1][n - 1] = left;
  
        // Calculate probabilities for N-1 moves
        for (int i = 2; i <= n; i++) {
  
            // when the person moves from ith index in
            // right direction when i moves has been done
            for (int j = 1; j <= 2 * n; j++) {
                arr[i][j] += (arr[i - 1][j - 1] * right);
            }
  
            // when the person moves from ith index in
            // left direction when i moves has been done
            for (int j = 2 * n - 1; j >= 0; j--) {
                arr[i][j] += (arr[i - 1][j + 1] * left);
            }
        }
        // Calling function to print the array with probabilities
        printArray(arr, n);
    }
  
    // Function that prints the array
    static void printArray(double[][] arr, int n)

1121
Chapter 151. Find the probability of reaching all points after N moves from point N

    {
        for (int i = 0; i < arr[0].length; i++) {
            System.out.printf("%5.4f ", arr[n][i]);
        }
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int n = 2;
        double left = 0.5;
        printProbabilities(n, left);
    }
}

Output:

0.2500 0.0000 0.5000 0.0000 0.2500

Time Complexity: O(N2 )


Auxiliary Space: O(N2 )

Source

https://www.geeksforgeeks.org/find-the-probability-of-reaching-all-points-after-n-moves-from-point-n/

1122
Chapter 152

Finding the maximum square


sub-matrix with all equal
elements

Finding the maximum square sub-matrix with all equal elements - GeeksforGeeks
Given a N x N matrix, determine the maximum K such that K x K is a submatrix with all
equal elements i.e., all the elements in this submatrix must be same.
Constraints:
1 <= N <= 1000
0 <= Ai , j <= 109
Examples:

Input : a[][] = {{2, 3, 3},


{2, 3, 3},
{2, 2, 2}}
Output : 2
Explanation: A 2x2 matrix is formed from index
A0,1 to A1,2

Input : a[][] = {{9, 9, 9, 8},


{9, 9, 9, 6},
{9, 9, 9, 3},
{2, 2, 2, 2}
Output : 3
Explanation : A 3x3 matrix is formed from index
A0,0 to A2,2

Method I ( Naive approach )


We can easily find all the square submatrices in O(n3 ) time and check whether each subma-

1123
Chapter 152. Finding the maximum square sub-matrix with all equal elements

trix contains equal elements or not in O(n2 ) time Which makes the total running time of
the algorithm as O(n5 ).
Method II ( Dynamic Programming )
For each cell (i, j), we store the largest value of K such that K x K is a submatrix with all
equal elements and position of (i, j) being the bottom-right most element.
And DPi,j depends upon {DPi-1, j , DPi, j-1 , DPi-1, j-1 }

If Ai, j is equal to {Ai-1, j, Ai, j-1, Ai-1, j-1},


all the three values:
DPi, j = min(DPi-1, j, DPi, j-1, DPi-1, j-1) + 1
Else
DPi, j = 1 // Matrix Size 1

The answer would be the maximum of all DPi, j's

Below is the implementation of above steps.

C++

// C++ program to find maximum K such that K x K


// is a submatrix with equal elements.
#include<bits/stdc++.h>
#define Row 6
#define Col 6
using namespace std;
  
// Returns size of the largest square sub-matrix
// with all same elements.
int largestKSubmatrix(int a[][Col])
{
    int dp[Row][Col];
    memset(dp, sizeof(dp), 0);
  
    int result = 0;
    for (int i = 0 ; i < Row ; i++)
    {
        for (int j = 0 ; j < Col ; j++)
        {
            // If elements is at top row or first
            // column, it wont form a  square
            // matrix's bottom-right
            if (i == 0 || j == 0)
                dp[i][j] = 1;
  
            else

1124
Chapter 152. Finding the maximum square sub-matrix with all equal elements

            {
                // Check if adjacent elements are equal
                if (a[i][j] == a[i-1][j] &&
                    a[i][j] == a[i][j-1] &&
                    a[i][j] == a[i-1][j-1] )
                    dp[i][j] = min(min(dp[i-1][j], dp[i][j-1]),
                                      dp[i-1][j-1] ) + 1;
  
                // If not equal, then it will form a 1x1
                // submatrix
                else dp[i][j] = 1;
            }
  
            // Update result at each (i,j)
            result = max(result, dp[i][j]);
        }
    }
  
    return result;
}
  
// Driven Program
int main()
{
    int a[Row][Col] = { 2, 2, 3, 3, 4, 4,
                        5, 5, 7, 7, 7, 4,
                        1, 2, 7, 7, 7, 4,
                        4, 4, 7, 7, 7, 4,
                        5, 5, 5, 1, 2, 7,
                        8, 7, 9, 4, 4, 4
                      };
  
    cout << largestKSubmatrix(a) << endl;
  
    return 0;
}

Java

// Java program to find maximum 


// K such that K x K is a 
// submatrix with equal elements.
class GFG 
{
    static int Row = 6, Col = 6;
      
    // Returns size of the largest 
    // square sub-matrix with

1125
Chapter 152. Finding the maximum square sub-matrix with all equal elements

    // all same elements.


    static int largestKSubmatrix(int [][]a)
    {
        int [][]dp = new int [Row][Col];
        int result = 0;
        for (int i = 0 ; 
                 i < Row ; i++)
        {
            for (int j = 0 ;
                     j < Col ; j++)
            {
                // If elements is at top 
                // row or first column, 
                // it wont form a square
                // matrix's bottom-right
                if (i == 0 || j == 0)
                    dp[i][j] = 1;
  
                else
                {
                    // Check if adjacent
                    // elements are equal
                    if (a[i][j] == a[i - 1][j] && 
                        a[i][j] == a[i][j - 1] && 
                        a[i][j] == a[i - 1][j - 1])
                    {
                    dp[i][j] = (dp[i - 1][j] > dp[i][j - 1] &&
                                dp[i - 1][j] > dp[i - 1][j - 1] + 1) ? 
                                                        dp[i - 1][j] :
                               (dp[i][j - 1] > dp[i - 1][j] && 
                                dp[i][j - 1] > dp[i - 1][j - 1] + 1) ? 
                                                        dp[i][j - 1] :
                                                 dp[i - 1][j - 1] + 1;
                    }             
  
                    // If not equal, then it
                    // will form a 1x1 submatrix
                    else dp[i][j] = 1;
                }
              
                // Update result at each (i,j)
                result = result > dp[i][j] ?
                                    result : dp[i][j];
            }
        }
        return result;
    }
  

1126
Chapter 152. Finding the maximum square sub-matrix with all equal elements

    // Driver code


    public static void main(String[] args) 
    {
        int [][]a = {{2, 2, 3, 3, 4, 4},
                     {5, 5, 7, 7, 7, 4},
                     {1, 2, 7, 7, 7, 4},
                     {4, 4, 7, 7, 7, 4},
                     {5, 5, 5, 1, 2, 7},
                      {8, 7, 9, 4, 4, 4}};
  
        System.out.println(largestKSubmatrix(a));
  
    }
}
  
// This code is contributed
// by ChitraNayal

C#

// C# program to find maximum 


// K such that K x K is a
// submatrix with equal elements.
using System;
  
class GFG 
{
    static int Row = 6, Col = 6;
      
    // Returns size of the 
    // largest square sub-matrix
    // with all same elements.
    static int largestKSubmatrix(int[,] a)
    {
        int[,] dp = new int [Row, Col];
        int result = 0;
        for (int i = 0 ; i < Row ; i++)
        {
            for (int j = 0 ; 
                     j < Col ; j++)
            {
                // If elements is at top 
                // row or first column, 
                // it wont form a square
                // matrix's bottom-right
                if (i == 0 || j == 0)
                    dp[i, j] = 1;
  

1127
Chapter 152. Finding the maximum square sub-matrix with all equal elements

                else
                {
                    // Check if adjacent 
                    // elements are equal
                    if (a[i, j] == a[i - 1, j] && 
                        a[i, j] == a[i, j - 1] && 
                        a[i, j] == a[i - 1, j - 1])
                    {
                     dp[i, j] = (dp[i - 1, j] > dp[i, j - 1] && 
                                 dp[i - 1, j] > dp[i - 1, j - 1] + 1) ? 
                                                         dp[i - 1, j] : 
                                 (dp[i, j - 1] > dp[i - 1, j] &&
                                  dp[i, j - 1] > dp[i - 1, j - 1] + 1) ? 
                                                          dp[i, j - 1] : 
                                                   dp[i - 1, j - 1] + 1;
                    }             
  
                    // If not equal, then 
                    // it will form a 1x1
                    // submatrix
                    else dp[i, j] = 1;
                }
              
                // Update result at each (i,j)
                result = result > dp[i, j] ? 
                                    result : dp[i, j];
            }
        }
        return result;
    }
  
    // Driver Code
    public static void Main() 
    {
        int[,] a = {{2, 2, 3, 3, 4, 4},
                    {5, 5, 7, 7, 7, 4},
                    {1, 2, 7, 7, 7, 4},
                    {4, 4, 7, 7, 7, 4},
                    {5, 5, 5, 1, 2, 7},
                    {8, 7, 9, 4, 4, 4}};
  
        Console.Write(largestKSubmatrix(a));
    }
}
  
// This code is contributed
// by ChitraNayal

1128
Chapter 152. Finding the maximum square sub-matrix with all equal elements

Python 3

# Python 3 program to find 


# maximum K such that K x K
# is a submatrix with equal 
# elements.
Row = 6
Col = 6
  
# Returns size of the 
# largest square sub-matrix
# with all same elements.
def largestKSubmatrix(a):
    dp = [[0 for x in range(Row)]
             for y in range(Col)]
  
    result = 0
    for i in range(Row ):
        for j in range(Col):
              
            # If elements is at top 
            # row or first column, 
            # it wont form a square
            # matrix's bottom-right
            if (i == 0 or j == 0):
                dp[i][j] = 1
  
            else:
                  
                # Check if adjacent 
                # elements are equal
                if (a[i][j] == a[i - 1][j] and
                    a[i][j] == a[i][j - 1] and
                    a[i][j] == a[i - 1][j - 1]):
                      
                    dp[i][j] = min(min(dp[i - 1][j], 
                                       dp[i][j - 1]),
                                       dp[i - 1][j - 1] ) + 1
  
                # If not equal, then  
                # it will form a 1x1
                # submatrix
                else:
                    dp[i][j] = 1
  
            # Update result at each (i,j)
            result = max(result, dp[i][j])
              

1129
Chapter 152. Finding the maximum square sub-matrix with all equal elements

    return result
  
# Driver Code
a = [[ 2, 2, 3, 3, 4, 4],
     [ 5, 5, 7, 7, 7, 4],
     [ 1, 2, 7, 7, 7, 4],
     [ 4, 4, 7, 7, 7, 4],
     [ 5, 5, 5, 1, 2, 7],
     [ 8, 7, 9, 4, 4, 4]];
  
print(largestKSubmatrix(a))
  
# This code is contributed
# by ChitraNayal

PHP

<?php 
// Java program to find maximum 
// K such that K x K is a
// submatrix with equal elements.
$Row = 6;
$Col = 6;
  
// Returns size of the largest
// square sub-matrix with 
// all same elements.
function largestKSubmatrix(&$a)
{
    global $Row, $Col;
  
    $result = 0;
    for ($i = 0 ; 
         $i < $Row ; $i++)
    {
        for ($j = 0 ; 
             $j < $Col ; $j++)
        {
            // If elements is at 
            // top row or first
            // column, it wont form
            // a square matrix's 
            // bottom-right
            if ($i == 0 || $j == 0)
                $dp[$i][$j] = 1;
  
            else
            {

1130
Chapter 152. Finding the maximum square sub-matrix with all equal elements

                // Check if adjacent 


                // elements are equal
                if ($a[$i][$j] == $a[$i - 1][$j] &&
                    $a[$i][$j] == $a[$i][$j - 1] &&
                    $a[$i][$j] == $a[$i - 1][$j - 1] )
                    $dp[$i][$j] = min(min($dp[$i - 1][$j], 
                                          $dp[$i][$j - 1]),
                                          $dp[$i - 1][$j - 1] ) + 1;
  
                // If not equal, then it 
                // will form a 1x1 submatrix
                else $dp[$i][$j] = 1;
            }
  
            // Update result at each (i,j)
            $result = max($result, 
                          $dp[$i][$j]);
        }
    }
  
    return $result;
}
  
// Driver Code
$a = array(array(2, 2, 3, 3, 4, 4),
           array(5, 5, 7, 7, 7, 4),
           array(1, 2, 7, 7, 7, 4),
           array(4, 4, 7, 7, 7, 4),
           array(5, 5, 5, 1, 2, 7),
           array(8, 7, 9, 4, 4, 4));
  
echo largestKSubmatrix($a);
  
// This code is contributed
// by ChitraNayal
?>

Output:

Time Complexity : O(Row * Col)


Auxiliary Space : O(Row * Col)
Improved By : ChitraNayal

1131
Chapter 152. Finding the maximum square sub-matrix with all equal elements

Source

https://www.geeksforgeeks.org/finding-the-maximum-square-sub-matrix-with-all-equal-elements/

1132
Chapter 153

Friends Pairing Problem

Friends Pairing Problem - GeeksforGeeks


Given n friends, each one can remain single or can be paired up with some other friend.
Each friend can be paired only once. Find out the total number of ways in which friends
can remain single or can be paired up.
Examples :

Input : n = 3
Output : 4

Explanation
{1}, {2}, {3} : all single
{1}, {2,3} : 2 and 3 paired but 1 is single.
{1,2}, {3} : 1 and 2 are paired but 3 is single.
{1,3}, {2} : 1 and 3 are paired but 2 is single.
Note that {1,2} and {2,1} are considered same.

f(n) = ways n people can remain single


or pair up.

For n-th person there are two choices:


1) n-th person remains single, we recur
for f(n - 1)
2) n-th person pairs up with any of the
remaining n - 1 persons. We get (n - 1) * f(n - 2)

Therefore we can recursively write f(n) as:


f(n) = f(n - 1) + (n - 1) * f(n - 2)

1133
Chapter 153. Friends Pairing Problem

Since above recursive formula has overlapping subproblems, we can solve it using Dynamic
Programming.

C++

// C++ program solution friends pairing problem


// C++ program for solution of
// friends pairing problem
#include <bits/stdc++.h>
using namespace std;
  
// Returns count of ways n people 
// can remain single or paired up.
int countFriendsPairings(int n)
{
    int dp[n + 1];
  
    // Filling dp[] in bottom-up manner using
    // recursive formula explained above.
    for (int i = 0; i <= n; i++)
    {
        if (i <= 2)
        dp[i] = i;
        else
        dp[i] = dp[i - 1] + (i - 1) * dp[i - 2];
    }
  
    return dp[n];
}
  
// Driver code
int main()
{
    int n = 4;
    cout << countFriendsPairings(n) << endl;
    return 0;
}

Java

// Java program for solution of 


// friends pairing problem
import java.io.*;
  
class GFG 
{
      

1134
Chapter 153. Friends Pairing Problem

    // Returns count of ways n people


    // can remain single or paired up.
    static int countFriendsPairings(int n)
    {
        int dp[] = new int[n + 1];
      
        // Filling dp[] in bottom-up manner using
        // recursive formula explained above.
        for (int i = 0; i <= n; i++)
        {
            if (i <= 2)
                dp[i] = i;
            else
                dp[i] = dp[i - 1] + (i - 1) 
                                * dp[i - 2];
        }
      
        return dp[n];
    }
      
    // Driver code
    public static void main (String[] args)
    {
        int n = 4;
        System.out.println (countFriendsPairings(n));
      
    }
}
  
// This code is contributed by vt_m

Python3

# Python program solution of


# friends pairing problem
  
# Returns count of ways
# n people can remain
# single or paired up.
def countFriendsPairings(n):
  
    dp = [0 for i in range(n + 1)]
  
    # Filling dp[] in bottom-up manner using
    # recursive formula explained above.
    for i in range(n + 1):
  
        if(i <= 2):

1135
Chapter 153. Friends Pairing Problem

            dp[i] = i
        else:
            dp[i] = dp[i - 1] + (i - 1) * dp[i - 2]
  
    return dp[n]
  
# Driver code
n = 4
print(countFriendsPairings(n))
  
# This code is contributed
# by Soumen Ghosh.

C#

// C# program solution for 


// friends pairing problem
using System;
  
class GFG  
{
      
    // Returns count of ways n people
    // can remain single or paired up.
    static int countFriendsPairings(int n)
    {
        int []dp = new int[n + 1];
      
        // Filling dp[] in bottom-up manner using
        // recursive formula explained above.
        for (int i = 0; i <= n; i++)
        {
            if (i <= 2)
                dp[i] = i;
            else
                dp[i] = dp[i - 1] + (i - 1) 
                                * dp[i - 2];
        }
      
        return dp[n];
    }
      
    // Driver code
    public static void Main ()
    {
        int n = 4;
        Console.Write(countFriendsPairings(n));
      

1136
Chapter 153. Friends Pairing Problem

    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program solution for 
// friends pairing problem
  
// Returns count of ways n people 
// can remain single or paired up.
function countFriendsPairings($n)
{
    $dp[$n + 1] = 0;
  
    // Filling dp[] in bottom-up 
    // manner using recursive formula 
    // explained above.
    for ($i = 0; $i <= $n; $i++)
    {
        if ($i <= 2)
        $dp[$i] = $i;
        else
        $dp[$i] = $dp[$i - 1] + 
                     ($i - 1) * 
                   $dp[$i - 2];
    }
  
    return $dp[$n];
}
  
// Driver code
$n = 4;
echo countFriendsPairings($n) ;
      
// This code is contributed 
// by nitin mittal.
?>

Output :

10

1137
Chapter 153. Friends Pairing Problem

Time Complexity : O(n)


Auxiliary Space : O(n)
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/friends-pairing-problem/

1138
Chapter 154

G-Fact 21 | Collatz Sequence

G-Fact 21 | Collatz Sequence - GeeksforGeeks


Starting with any positive integer N, we define the Collatz sequence corresponding to N as
the numbers formed by the following operations:

N → N/2 ( if N is even)
N → 3N + 1 (if N is odd)

i.e. If N is even, divide it by 2 to get N/2.


If N is odd, multiply it by 3 and add 1 to obtain 3N + 1.

It is conjectured but not yet proven that no matter which positive integer
we start with; we always end up with 1.
For example, 10 → 5 → 16 → 8 → 4 → 2 → 1
A Coding Practice Question on Collatz Sequence

Source

https://www.geeksforgeeks.org/collatz-sequence/

1139
Chapter 155

Generate all unique partitions


of an integer

Generate all unique partitions of an integer - GeeksforGeeks


Given a positive integer n, generate all possible unique ways to represent n as sum of positive
integers.
Examples:

Input: n = 2
Output:
2
1 1

Input: n = 3
Output:
3
2 1
1 1 1
Note: 2+1 and 1+2 are considered as duplicates.

Input: n = 4
Output:
4
3 1
2 2
2 1 1
1 1 1 1

Solution: We print all partition in sorted order and numbers within a partition are also
printed in sorted order (as shown in the above examples). The idea is to get next partition

1140
Chapter 155. Generate all unique partitions of an integer

using the values in current partition. We store every partition in an array p[]. We initialize
p[] as n where n is the input number. In every iteration. we first print p[] and then update
p[] to store the next partition. So the main problem is to get next partition from a given
partition.
Steps to get next partition from current partition:
We are given current partition in p[] and its size. We need to update p[] to store next
partition. Values in p[] must be sorted in non-increasing order.

1. Find the rightmost non-one value in p[] and store the count of 1’s encountered before
a non-one value in a variable rem_val (It indicates sum of values on right side to be
updated). Let the index of non-one value be k.
2. Decrease the value of p[k] by 1 and increase rem_val by 1. Now there may be two
cases:
• a) If
3. b) Else (This is a interesting case, take initial p[] as {3, 1, 1, 1}, p[k] is decreased
from 3 to 2, rem_val is increased from 3 to 4, the next partition should be {2, 2, 2}).
4. Copy p[k] to next position, increment k and reduce count by p[k] while p[k] is less than
rem_val. Finally, put rem_val at p[k+1] and p[0…k+1] is our new partition. This
step is like dividing rem_val in terms of p[k] (4 is divided in 2’s).

Following is the implementation of above algorithm:

C/C++

// CPP program to generate all unique


// partitions of an integer
#include<iostream>
using namespace std;
  
// A utility function to print an array p[] of size 'n'
void printArray(int p[], int n)
{
    for (int i = 0; i < n; i++)
       cout << p[i] << " ";
    cout << endl;
}
  
void printAllUniqueParts(int n)
{
    int p[n]; // An array to store a partition
    int k = 0;  // Index of last element in a partition
    p[k] = n;  // Initialize first partition as number itself
  
    // This loop first prints current partition, then generates next
    // partition. The loop stops when the current partition has all 1s

1141
Chapter 155. Generate all unique partitions of an integer

    while (true)
    {
        // print current partition
        printArray(p, k+1);
  
        // Generate next partition
  
        // Find the rightmost non-one value in p[]. Also, update the
        // rem_val so that we know how much value can be accommodated
        int rem_val = 0;
        while (k >= 0 && p[k] == 1)
        {
            rem_val += p[k];
            k--;
        }
  
        // if k < 0, all the values are 1 so there are no more partitions
        if (k < 0)  return;
  
        // Decrease the p[k] found above and adjust the rem_val
        p[k]--;
        rem_val++;
  
  
        // If rem_val is more, then the sorted order is violated.  Divide
        // rem_val in different values of size p[k] and copy these values at
        // different positions after p[k]
        while (rem_val > p[k])
        {
            p[k+1] = p[k];
            rem_val = rem_val - p[k];
            k++;
        }
  
        // Copy rem_val to next position and increment position
        p[k+1] = rem_val;
        k++;
    }
}
  
// Driver program to test above functions
int main()
{
    cout << "All Unique Partitions of 2 \n";
    printAllUniqueParts(2);
  
    cout << "\nAll Unique Partitions of 3 \n";
    printAllUniqueParts(3);

1142
Chapter 155. Generate all unique partitions of an integer

  
    cout << "\nAll Unique Partitions of 4 \n";
    printAllUniqueParts(4);
  
    return 0;
}

Java

// Java program to generate all unique


// partitions of an integer
import java.io.*;
  
class GFG 
{
    // Function to print an array p[] of size n
    static void printArray(int p[], int n)
    {
        for (int i = 0; i < n; i++)
            System.out.print(p[i]+" ");
        System.out.println();
    }
      
    // Function to generate all unique partitions of an integer
    static void printAllUniqueParts(int n)
    {
        int[] p = new int[n]; // An array to store a partition
        int k = 0;  // Index of last element in a partition
        p[k] = n;  // Initialize first partition as number itself
   
        // This loop first prints current partition, then generates next
        // partition. The loop stops when the current partition has all 1s
        while (true)
        {
            // print current partition
            printArray(p, k+1);
   
            // Generate next partition
   
            // Find the rightmost non-one value in p[]. Also, update the
            // rem_val so that we know how much value can be accommodated
            int rem_val = 0;
            while (k >= 0 && p[k] == 1)
            {
                rem_val += p[k];
                k--;
            }
   

1143
Chapter 155. Generate all unique partitions of an integer

            // if k < 0, all the values are 1 so there are no more partitions
            if (k < 0)  return;
   
            // Decrease the p[k] found above and adjust the rem_val
            p[k]--;
            rem_val++;
   
   
            // If rem_val is more, then the sorted order is violeted.  Divide
            // rem_val in differnt values of size p[k] and copy these values at
            // different positions after p[k]
            while (rem_val > p[k])
            {
                p[k+1] = p[k];
                rem_val = rem_val - p[k];
                k++;
            }
   
            // Copy rem_val to next position and increment position
            p[k+1] = rem_val;
            k++;
        }
    }
      
    // Driver program
    public static void main (String[] args) 
    {
        System.out.println("All Unique Partitions of 2");
        printAllUniqueParts(2);
          
        System.out.println("All Unique Partitions of 3");
        printAllUniqueParts(3);
          
        System.out.println("All Unique Partitions of 4");
        printAllUniqueParts(4);
    }
}
  
// Contributed by Pramod Kumar

C#

// C# program to generate all unique


// partitions of an integer
using System;
  
class GFG {
      

1144
Chapter 155. Generate all unique partitions of an integer

    // Function to print an array p[] 


    // of size n
    static void printArray(int []p, int n)
    {
        for (int i = 0; i < n; i++)
            Console.Write(p[i]+" ");
              
        Console.WriteLine();
    }
      
    // Function to generate all unique 
    // partitions of an integer
    static void printAllUniqueParts(int n)
    {
          
        // An array to store a partition
        int[] p = new int[n]; 
          
        // Index of last element in a 
        // partition
        int k = 0; 
          
        // Initialize first partition as 
        // number itself
        p[k] = n; 
  
        // This loop first prints current 
        // partition, then generates next
        // partition. The loop stops when 
        // the current partition has all 1s
        while (true)
        {
              
            // print current partition
            printArray(p, k+1);
  
            // Generate next partition
  
            // Find the rightmost non-one 
            // value in p[]. Also, update 
            // the rem_val so that we know
            // how much value can be 
            // accommodated
            int rem_val = 0;
              
            while (k >= 0 && p[k] == 1)
            {
                rem_val += p[k];

1145
Chapter 155. Generate all unique partitions of an integer

                k--;
            }
  
            // if k < 0, all the values are 1 so
            // there are no more partitions
            if (k < 0) 
                return;
  
            // Decrease the p[k] found above 
            // and adjust the rem_val
            p[k]--;
            rem_val++;
  
  
            // If rem_val is more, then the sorted
            // order is violeted. Divide rem_val in
            // differnt values of size p[k] and copy
            // these values at different positions
            // after p[k]
            while (rem_val > p[k])
            {
                p[k+1] = p[k];
                rem_val = rem_val - p[k];
                k++;
            }
  
            // Copy rem_val to next position and 
            // increment position
            p[k+1] = rem_val;
            k++;
        }
    }
      
    // Driver program
    public static void Main () 
    {
        Console.WriteLine("All Unique Partitions of 2");
        printAllUniqueParts(2);
          
        Console.WriteLine("All Unique Partitions of 3");
        printAllUniqueParts(3);
          
        Console.WriteLine("All Unique Partitions of 4");
        printAllUniqueParts(4);
    }
}
  
// This code is contributed by Sam007.

1146
Chapter 155. Generate all unique partitions of an integer

PHP

<?php
// PHP program to generate 
// all unique partitions 
// of an integer
  
// A utility function to 
// print an array p[] of 
// size 'n'
function printArray( $p, $n)
{
    for ($i = 0; $i < $n; $i++)
    echo $p[$i] , " ";
    echo "\n";
}
  
function printAllUniqueParts($n)
{
    // An array to store
    // a partition
    $p[$n] = array(0); 
      
    // Index of last element
    // in a partition
    $k = 0; 
      
    // Initialize first 
    // partition as number 
    // itself
    $p[$k] = $n; 
  
    // This loop first prints 
    // current partition, then 
    // generates next partition. 
    // The loop stops when the 
    // current partition has all 1s
    while (true)
    {
        // print current partition
        printArray($p, $k + 1);
  
        // Generate next partition
  
        // Find the rightmost non-one
        // value in p[]. Also, update 
        // the rem_val so that we know 
        // how much value can be accommodated

1147
Chapter 155. Generate all unique partitions of an integer

        $rem_val = 0;
        while ($k >= 0 && $p[$k] == 1)
        {
            $rem_val += $p[$k];
            $k--;
        }
  
        // if k < 0, all the values
        // are 1 so there are no 
        // more partitions
        if ($k < 0) return;
  
        // Decrease the p[k] found 
        // above and adjust the
        // rem_val
        $p[$k]--;
        $rem_val++;
  
  
        // If rem_val is more, then 
        // the sorted order is violated. 
        // Divide rem_val in different
        // values of size p[k] and copy 
        // these values at different
        // positions after p[k]
        while ($rem_val > $p[$k])
        {
            $p[$k + 1] = $p[$k];
            $rem_val = $rem_val - $p[$k];
            $k++;
        }
  
        // Copy rem_val to next
        // position and increment
        // position
        $p[$k + 1] = $rem_val;
        $k++;
    }
}
  
// Driver Code
echo "All Unique Partitions of 2 \n";
printAllUniqueParts(2);
  
echo "\nAll Unique Partitions of 3 \n";
printAllUniqueParts(3);
  
echo "\nAll Unique Partitions of 4 \n";

1148
Chapter 155. Generate all unique partitions of an integer

printAllUniqueParts(4);
  
// This code is contributed 
// by akt_mit
?>

Output:

All Unique Partitions of 2


2
1 1

All Unique Partitions of 3


3
2 1
1 1 1

All Unique Partitions of 4


4
3 1
2 2
2 1 1
1 1 1 1

This article is contributed by Hariprasad NG. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : jit_t

Source

https://www.geeksforgeeks.org/generate-unique-partitions-of-an-integer/

1149
Chapter 156

Given a large number, check if a


subsequence of digits is divisible
by 8

Given a large number, check if a subsequence of digits is divisible by 8 - GeeksforGeeks


Given a number of at most 100 digits. We have to check if it is possible, after removing
certain digits, to obtain a number of at least one digit which is divisible by 8. We are
forbidden to rearrange the digits.
Examples :

Input : 1787075866
Output : Yes
There exist more one or more subsequences
divisible by 8. Example subsequences are
176, 16 and 8.

Input : 6673177113
Output : No
No subsequence is divisible by 8.

Input : 3144
Output : Yes
The subsequence 344 is divisible by 8.

Property of the divisibility by eight : number can be divided by eight if and only if its last
three digits form a number that can be divided by eight. Thus, it is enough to test only
numbers that can be obtained from the original one by crossing out and that contain at
most three digits i.e we check all one digits, two digits and three digit number combinations.

1150
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

Method 1 (Brute Force):


We apply the brute force approach. We permute all possible single digit, double digit
and triple digit combinations using iterative ladder. If we encounter a single digit number
divisible by 8 or a double digit number combination divisible by 8 or a triple digit number
combination divisible by 8, then that will be the solution to our problem.
CPP

// CPP program to check if a subsequence of digits


// is divisible by 8.
#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate any permutation divisible
// by 8. If such permutation exists, the function
// will return that permutation else it will return -1
bool isSubSeqDivisible(string str)
{
    // Generating all possible permutations and checking
    // if any such permutation is divisible by 8
    for (int i = 0; i < l; i++) {
        for (int j = i; j < l; j++) {
            for (int k = j; k < l; k++) {
                if (arr[i] % 8 == 0)
                    return true;
  
                else if ((arr[i] * 10 + arr[j]) % 8 == 0 && i != j)
                    return true;
  
                else if ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0 && i != j && j != k && i
                    return true;
            }
        }
    }
    return false;
}
  
// Driver function
int main()
{
    string str = "3144";
    if (isSubSeqDivisible(str))
        cout << "Yes";
    else
        cout << "No";
    return 0;
}

1151
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

Java

// Java program to check if a subsequence


// of digits is divisible by 8.
import java.io.*;
  
class GFG {
  
    // Function to calculate any permutation
    // divisible by 8. If such permutation
    // exists, the function will return
    // that permutation else it will return -1
    static boolean isSubSeqDivisible(String str)
    {
  
        int i, j, k, l = str.length();
        int arr[] = new int[l];
  
        // Generating all possible permutations
        // and checking if any such
        // permutation is divisible by 8
        for (i = 0; i < l; i++) {
            for (j = i; j < l; j++) {
                for (k = j; k < l; k++) {
                    if (arr[i] % 8 == 0)
                        return true;
  
                    else if ((arr[i] * 10 + arr[j]) % 8 == 0 && i != j)
                        return true;
  
                    else if ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0
                             && i != j && j != k && i != k)
                        return true;
                }
            }
        }
        return false;
    }
  
    // Driver function
    public static void main(String args[])
    {
  
        String str = "3144";
        if (isSubSeqDivisible(str))
            System.out.println("Yes");
        else
            System.out.println("No");

1152
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

    }
}
  
// This code is contributed by Nikita Tiwari.

Python3

# Python 3 program to
# check if a subsequence of digits
# is divisible by 8.
  
# Function to calculate any
# permutation divisible
# by 8. If such permutation
# exists, the function
# will return that permutation
# else it will return -1
def isSubSeqDivisible(st) :
  
    l = len(st)
    arr = [0] * l
  
    # Generating all possible
    # permutations and checking
    # if any such permutation
    # is divisible by 8
    for i in range(0, l) :
        for j in range(i, l) :
            for k in range(j, l) :
                if (arr[i] % 8 == 0) :
                    return True
   
                elif ((arr[i]*10 + arr[j])% 8 == 0 and i != j) :
                    return True
   
                elif ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0 and i != j and j != k and i
                    return True
             
    return False
   
# Driver function
  
st = "3144"
if (isSubSeqDivisible(st)) :
    print("Yes")
else :
    print("No")
  

1153
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

# This code is contributed


# by Nikita Tiwari.

C#

// C# program to check if a subsequence


// of digits is divisible by 8.
using System;
  
class GFG {
  
    // Function to calculate any permutation
    // divisible by 8. If such permutation
    // exists, the function will return
    // that permutation else it will return -1
    static bool isSubSeqDivisible(string str)
    {
        int i, j, k, l = str.Length;
        int[] arr = new int[l];
  
        // Generating all possible permutations
        // and checking if any such
        // permutation is divisible by 8
        for (i = 0; i < l; i++) {
            for (j = i; j < l; j++) {
                for (k = j; k < l; k++) {
                    if (arr[i] % 8 == 0)
                        return true;
  
                    else if ((arr[i] * 10 + arr[j])
                                     % 8
                                 == 0
                             && i != j)
                        return true;
  
                    else if ((arr[i] * 100 + arr[j] * 10 + arr[k]) % 8 == 0
                             && i != j && j != k
                             && i != k)
                        return true;
                }
            }
        }
  
        return false;
    }
  
    // Driver function
    public static void Main()

1154
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

    {
        string str = "3144";
  
        if (isSubSeqDivisible(str))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to check if 
// a subsequence of digits
// is divisible by 8.
  
// Function to calculate any 
// permutation divisible
// by 8. If such permutation
// exists, the function
// will return that permutation 
// else it will return -1
  
function isSubSeqDivisible($str)
{
    // Generating all possible 
    // permutations and checking
    // if any such permutation 
    // is divisible by 8
    $l = strlen($str);
    for ( $i = 0; $i < $l ; $i++) 
    {
        for ($j = $i; $j <$l; $j++) 
        {
            for ($k = $j; $k < $l; $k++) 
            {
                if ($arr[$i] % 8 == 0)
                    return true;
  
                else if (($arr[$i] * 10 + 
                          $arr[$j]) % 8 == 0 && 
                          $i != $j)
                    return true;
  
                else if (($arr[$i] * 100 + $arr[$j] *

1155
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

                          10 + $arr[$k]) % 8 == 0 && 


                          $i != $j && $j != $k && 
                          $i != $k)
                    return true;
            }
        }
    }
    return false;
}
  
// Driver Code
$str = "3144";
if (isSubSeqDivisible($str))
echo "Yes";
else
echo "No";
  
// This code is contributed by aj_36
?>

Output :

Yes

Method 2 (Dynamic Programming):


Though we have only 100 digit number, but for longer examples larger than that, our
program might exceed the given time limit.
Thus, we optimize our code by using dynamic programmingapproach.
Let be the ith digit of the sample. We generate a matrix dp[i][j], 1<=i<=n and
0<=j<8. The value of dp is true if we can cross out some digits from the prefix of length
i such that the remaining number gives j modulo eight, and false otherwise. For broad
understanding of the concept, if at an index, we find element 8 for that index we put the

value of
For all other numbers, we build on a simple concept that either addition of that digit will
contribute in formation of a number divisible by 8, or it shall be left out.
Note: We also have to keep it in mind that we cannot change the order
Now,

if we add the current digit to the previous result.

if we exclude the current digit in our formation.


Now, if such a number shall exist, we will get a “true” for any i in dp[i][0]

1156
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

C++

// C++ program to find if there is a subsequence


// of digits divisible by 8.
#include <bits/stdc++.h>
using namespace std;
  
// Function takes in an array of numbers,
// dynamically goes on the location and
// makes combination of numbers.
bool isSubSeqDivisible(string str)
{
    int n = str.length();
    int dp[n + 1][10];
    memset(dp, 0, sizeof(dp));
  
    // Converting string to integer array for ease
    // of computations (Indexing in arr[] is
    // considered to be starting from 1)
    int arr[n + 1];
    for (int i = 1; i <= n; i++)
        arr[i] = str[i - 1] - '0';
  
    for (int i = 1; i <= n; i++) {
  
        dp[i][arr[i] % 8] = 1;
        for (int j = 0; j < 8; j++) {
  
            // If we consider the number in our combination,
            // we add it to the previous combination
            if (dp[i - 1][j] > dp[i][(j * 10 + arr[i]) % 8])
                dp[i][(j * 10 + arr[i]) % 8] = dp[i - 1][j];
  
            // If we exclude the number from our combination
            if (dp[i - 1][j] > dp[i][j])
                dp[i][j] = dp[i - 1][j];
        }
    }
  
    for (int i = 1; i <= n; i++) {
  
        // If at dp[i][0], we find value 1/true, it shows
        // that the number exists at the value of 'i'
        if (dp[i][0] == 1)
            return true;
    }
  
    return false;

1157
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

}
  
// Driver function
int main()
{
    string str = "3144";
    if (isSubSeqDivisible(str))
        cout << "Yes";
    else
        cout << "No";
    return 0;
}

Java

// Java program to find if there is a


// subsequence of digits divisible by 8.
import java.io.*;
import java.util.*;
  
class GFG {
  
    // Function takes in an array of numbers,
    // dynamically goes on the location and
    // makes combination of numbers.
    static boolean isSubSeqDivisible(String str)
    {
  
        int n = str.length();
        int dp[][] = new int[n + 1][10];
  
        // Converting string to integer array
        // for ease of computations (Indexing in
        // arr[] is considered to be starting
        // from 1)
        int arr[] = new int[n + 1];
        for (int i = 1; i <= n; i++)
            arr[i] = (int)(str.charAt(i - 1) - '0');
  
        for (int i = 1; i <= n; i++) {
  
            dp[i][arr[i] % 8] = 1;
            for (int j = 0; j < 8; j++) {
  
                // If we consider the number in
                // our combination, we add it to
                // the previous combination
                if (dp[i - 1][j] > dp[i][(j * 10

1158
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

                                          + arr[i])
                                         % 8])
                    dp[i][(j * 10 + arr[i]) % 8]
                        = dp[i - 1][j];
  
                // If we exclude the number from
                // our combination
                if (dp[i - 1][j] > dp[i][j])
                    dp[i][j] = dp[i - 1][j];
            }
        }
  
        for (int i = 1; i <= n; i++) {
  
            // If at dp[i][0], we find value 1/true,
            // it shows that the number exists at
            // the value of 'i'
            if (dp[i][0] == 1)
                return true;
        }
  
        return false;
    }
  
    // Driver function
    public static void main(String args[])
    {
        String str = "3144";
        if (isSubSeqDivisible(str))
            System.out.println("Yes");
        else
            System.out.println("No");
    }
}
  
/* This code is contributed by Nikita Tiwari.*/

C#

// C# program to find if there is a


// subsequence of digits divisible by 8.
using System;
  
class GFG {
  
    // Function takes in an array of numbers,
    // dynamically goes on the location and
    // makes combination of numbers.

1159
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

    static bool isSubSeqDivisible(String str)


    {
  
        int n = str.Length;
        int[, ] dp = new int[n + 1, 10];
  
        // Converting string to integer array
        // for ease of computations (Indexing in
        // arr[] is considered to be starting
        // from 1)
        int[] arr = new int[n + 1];
        for (int i = 1; i <= n; i++)
            arr[i] = (int)(str[i - 1] - '0');
  
        for (int i = 1; i <= n; i++) {
            dp[i, arr[i] % 8] = 1;
            for (int j = 0; j < 8; j++) {
  
                // If we consider the number in
                // our combination, we add it to
                // the previous combination
                if (dp[i - 1, j] > dp[i, (j * 10
                                          + arr[i])
                                             % 8])
                    dp[i, (j * 10 + arr[i]) % 8]
                        = dp[i - 1, j];
  
                // If we exclude the number from
                // our combination
                if (dp[i - 1, j] > dp[i, j])
                    dp[i, j] = dp[i - 1, j];
            }
        }
  
        for (int i = 1; i <= n; i++) {
  
            // If at dp[i][0], we find value
            // 1/true, it shows that the number
            // exists at the value of 'i'
            if (dp[i, 0] == 1)
                return true;
        }
  
        return false;
    }
  
    // Driver function
    public static void Main()

1160
Chapter 156. Given a large number, check if a subsequence of digits is divisible by 8

    {
        string str = "3144";
  
        if (isSubSeqDivisible(str))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("No");
    }
}
  
// This code is contributed by vt_m.

Output :

Yes

Using the dynamic approach, our time complexity cuts down to , where 8 is
from which the number should be divisible and n is the length of our input. Therefore, the

overall complexity is .
Improved By : vt_m, jit_t

Source

https://www.geeksforgeeks.org/given-large-number-check-subsequence-digits-divisible-8/

1161
Chapter 157

Gold Mine Problem

Gold Mine Problem - GeeksforGeeks


Given a gold mine of n*m dimensions. Each field in this mine contains a positive integer
which is the amount of gold in tons. Initially the miner is at first column but can be at any
row. He can move only (right->,right up /,right down\) that is from a given cell, the miner
can move to the cell diagonally up towards the right or right or diagonally down towards
the right. Find out maximum amount of gold he can collect.
Examples:

Input : mat[][] = {{1, 3, 3},


{2, 1, 4},
{0, 6, 4}};
Output : 12
{(1,0)->(2,1)->(2,2)}

Input: mat[][] = { {1, 3, 1, 5},


{2, 2, 4, 1},
{5, 0, 2, 3},
{0, 6, 1, 2}};
Output : 16
(2,0) -> (1,1) -> (1,2) -> (0,3) OR
(2,0) -> (3,1) -> (2,2) -> (2,3)

Input : mat[][] = {{10, 33, 13, 15},


{22, 21, 04, 1},
{5, 0, 2, 3},
{0, 6, 14, 2}};
Output : 83

Source Flipkart Interview

1162
Chapter 157. Gold Mine Problem

Create a 2-D matrix goldTable[][]) of the same as given matrix mat[][]. If we observe the
question closely, we can notice following.

1. Amount of gold is positive, so we would like to cover maximum cells of maximum


values under given constraints.
2. In every move, we move one step toward right side. So we always end up in last
column. If we are at the last column, then we are unable to move right

If we are at the first row or last column, then we are unable to move right-up so just assign
0 otherwise assign the value of goldTable[row-1][col+1] to right_up. If we are at the last
row or last column, then we are unable to move right down so just assign 0 otherwise assign
the value of goldTable[row+1][col+1] to right up.
Now find the maximum of right, right_up, and right_down and then add it with that
mat[row][col]. At last, find the maximum of all rows and first column and return it.
CPP

// C++ program to solve Gold Mine problem


#include<bits/stdc++.h>
using namespace std;
  
const int MAX = 100;
  
// Returns maximum amount of gold that can be collected
// when journey started from first column and moves
// allowed are right, right-up and right-down
int getMaxGold(int gold[][MAX], int m, int n)
{
    // Create a table for storing intermediate results
    // and initialize all cells to 0. The first row of
    // goldMineTable gives the maximum gold that the miner
    // can collect when starts that row
    int goldTable[m][n];
    memset(goldTable, 0, sizeof(goldTable));
  
    for (int col=n-1; col>=0; col--)
    {
        for (int row=0; row<m; row++)
        {
            // Gold collected on going to the cell on the right(->)
            int right = (col==n-1)? 0: goldTable[row][col+1];
  
            // Gold collected on going to the cell to right up (/)
            int right_up = (row==0 || col==n-1)? 0:
                            goldTable[row-1][col+1];
  
            // Gold collected on going to the cell to right down (\)
            int right_down = (row==m-1 || col==n-1)? 0:

1163
Chapter 157. Gold Mine Problem

                             goldTable[row+1][col+1];
  
            // Max gold collected from taking either of the
            // above 3 paths
            goldTable[row][col] = gold[row][col] +
                              max(right, max(right_up, right_down));
                                                      
        }
    }
  
    // The max amount of gold collected will be the max
    // value in first column of all rows
    int res = goldTable[0][0];
    for (int i=1; i<m; i++)
        res = max(res, goldTable[i][0]);
    return res;
}
  
// Driver Code
int main()
{
    int gold[MAX][MAX]= { {1, 3, 1, 5},
        {2, 2, 4, 1},
        {5, 0, 2, 3},
        {0, 6, 1, 2}
    };
    int m = 4, n = 4;
    cout << getMaxGold(gold, m, n);
    return 0;
}

Java

// Java program to solve Gold Mine problem


import java.util.Arrays;
  
class GFG {
      
    static final int MAX = 100;
      
    // Returns maximum amount of gold that 
    // can be collected when journey started 
    // from first column and moves allowed 
    // are right, right-up and right-down
    static int getMaxGold(int gold[][], 
                              int m, int n)
    {
          

1164
Chapter 157. Gold Mine Problem

        // Create a table for storing 


        // intermediate results and initialize
        // all cells to 0. The first row of
        // goldMineTable gives the maximum 
        // gold that the miner can collect 
        // when starts that row
        int goldTable[][] = new int[m][n];
          
        for(int[] rows:goldTable)
            Arrays.fill(rows, 0);
      
        for (int col = n-1; col >= 0; col--)
        {
            for (int row = 0; row < m; row++)
            {
                  
                // Gold collected on going to 
                // the cell on the right(->)
                int right = (col == n-1) ? 0 
                        : goldTable[row][col+1];
      
                // Gold collected on going to 
                // the cell to right up (/)
                int right_up = (row == 0 ||
                               col == n-1) ? 0 :
                        goldTable[row-1][col+1];
      
                // Gold collected on going to 
                // the cell to right down (\)
                int right_down = (row == m-1 
                            || col == n-1) ? 0 :
                          goldTable[row+1][col+1];
      
                // Max gold collected from taking
                // either of the above 3 paths
                goldTable[row][col] = gold[row][col]
                 + Math.max(right, Math.max(right_up, 
                                       right_down));
                                                        ;
            }
        }
      
        // The max amount of gold collected will be
        // the max value in first column of all rows
        int res = goldTable[0][0];
          
        for (int i = 1; i < m; i++)
            res = Math.max(res, goldTable[i][0]);

1165
Chapter 157. Gold Mine Problem

              
        return res;
    }
      
    //driver code
    public static void main(String arg[])
    {
        int gold[][]= { {1, 3, 1, 5},
                        {2, 2, 4, 1},
                        {5, 0, 2, 3},
                        {0, 6, 1, 2} };
                          
        int m = 4, n = 4;
          
        System.out.print(getMaxGold(gold, m, n));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python program to solve


# Gold Mine problem
  
MAX = 100
  
# Returns maximum amount of
# gold that can be collected
# when journey started from
# first column and moves
# allowed are right, right-up
# and right-down
def getMaxGold(gold, m, n):
  
    # Create a table for storing
    # intermediate results
    # and initialize all cells to 0.
    # The first row of
    # goldMineTable gives the
    # maximum gold that the miner
    # can collect when starts that row
    goldTable = [[0 for i in range(n)]
                        for j in range(m)]
  
    for col in range(n-1, -1, -1):
        for row in range(m):
  

1166
Chapter 157. Gold Mine Problem

            # Gold collected on going to


            # the cell on the rigth(->)
            if (col == n-1):
                right = 0
            else:
                right = goldTable[row][col+1]
  
            # Gold collected on going to
            # the cell to right up (/)
            if (row == 0 or col == n-1):
                right_up = 0
            else:
                right_up = goldTable[row-1][col+1]
  
            # Gold collected on going to
            # the cell to right down (\)
            if (row == m-1 or col == n-1):
                right_down = 0
            else:
                right_down = goldTable[row+1][col+1]
  
            # Max gold collected from taking
            # either of the above 3 paths
            goldTable[row][col] = gold[row][col] + max(right, right_up, right_down)
                                                             
    # The max amount of gold
    # collected will be the max
    # value in first column of all rows
    res = goldTable[0][0]
    for i in range(1, m):
        res = max(res, goldTable[i][0])
  
    return res
      
# Driver code
gold = [[1, 3, 1, 5],
    [2, 2, 4, 1],
    [5, 0, 2, 3],
    [0, 6, 1, 2]]
  
m = 4
n = 4
  
print(getMaxGold(gold, m, n))
  
# This code is contributed
# by Soumen Ghosh.              

1167
Chapter 157. Gold Mine Problem

Output:

16

Time Complexity :O(m*n)


Space Complexity :O(m*n)

Source

https://www.geeksforgeeks.org/gold-mine-problem/

1168
Chapter 158

Golomb sequence

Golomb sequence - GeeksforGeeks


In mathematics, the Golomb sequence is a non-decreasing integer sequence where n-th
term is equal to number of times n appears in the sequence.
The first few values are
1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, ……
Explanation of few terms:
Third term is 2, note that three appears 2 times.
Second term is 2, note that two appears 2 times.
Fourth term is 3, note that four appears 3 times.
Given a positive integer n. The task is to find the first n terms of Golomb sequence.

Examples :

Input : n = 4
Output : 1 2 2 3

Input : n = 6
Output : 1 2 2 3 3 4

The recurrence relation to find the nth term of Golomb sequence:


a(1) = 1
a(n + 1) = 1 + a(n + 1 – a(a(n)))
Below is the implementation using Recursion:
C++

// C++ Program to find first


// n terms of Golomb sequence.

1169
Chapter 158. Golomb sequence

#include <bits/stdc++.h>
using namespace std;
  
// Return the nth element
// of Golomb sequence
int findGolomb(int n)
{
    // base case
    if (n == 1)
        return 1;
  
    // Recursive Step
    return 1 + findGolomb(n - 
               findGolomb(findGolomb(n - 1)));
}
  
// Print the first n 
// term of Golomb Sequence
void printGolomb(int n)
{
    // Finding first n 
    // terms of Golomb Sequence.
    for (int i = 1; i <= n; i++) 
        cout << findGolomb(i) << " "; 
}
  
// Driver Code
int main()
{
    int n = 9;
    printGolomb(n);
    return 0;
}

Java

// Java Program to find first  


// n terms of Golomb sequence.
import java.util.*;
  
class GFG
{
    public static int findGolomb(int n)
    {
          
        // base case
        if (n == 1)
            return 1;

1170
Chapter 158. Golomb sequence

      
        // Recursive Step
        return 1 + findGolomb(n - 
        findGolomb(findGolomb(n - 1)));
    }
      
      
    // Print the first n term of 
    // Golomb Sequence 
    public static void printGolomb(int n)
    {
          
        // Finding first n terms of 
        // Golomb Sequence.
        for (int i = 1; i <= n; i++) 
            System.out.print(findGolomb(i) + 
                                       " "); 
    }
      
    // Driver Code
    public static void main (String[] args)
    {
        int n = 9;
          
        printGolomb(n);
    }
}
  
// This code is conttributed by Akash Singh

Python 3

# Python 3 Program to find first 


# n terms of Golomb sequence.
  
# Return the nth element of 
# Golomb sequence
def findGolomb(n):
  
    # base case
    if (n == 1):
        return 1
  
    # Recursive Step
    return 1 + findGolomb(n -
    findGolomb(findGolomb(n - 1)))
  
  

1171
Chapter 158. Golomb sequence

# Print the first n term 


# of Golomb Sequence
def printGolomb(n):
  
    # Finding first n terms of
    # Golomb Sequence.
    for i in range(1, n + 1): 
        print(findGolomb(i), end=" ") 
  
# Driver Code
n = 9
  
printGolomb(n)
  
# This code is contributed by 
# Smitha Dinesh Semwal

C#

// C# Program to find first n  


// terms of Golomb sequence.
using System;
  
class GFG 
{
      
    // Return the nth element 
    // of Golomb sequence
    static int findGolomb(int n)
    {
          
        // base case
        if (n == 1)
            return 1;
      
        // Recursive Step
        return 1 + findGolomb(n - 
        findGolomb(findGolomb(n - 1)));
    }
      
    // Print the first n term  
    // of Golomb Sequence
    static void printGolomb(int n)
    {
        // Finding first n terms of 
        // Golomb Sequence.
        for (int i = 1; i <= n; i++) 
            Console .Write(findGolomb(i) + 

1172
Chapter 158. Golomb sequence

                                     " "); 
    }
      
    // Driver Code
    public static void Main ()
    {
          
        int n = 9;
          
        printGolomb(n);
          
    }
}
  
// This code is contributed by vt_m

PHP

<?php
// PHP Program to find first 
// n terms of Golomb sequence.
  
// Return the nth element
// of Golomb sequence
function findGolomb($n)
{
      
    // base case
    if ($n == 1)
        return 1;
  
    // Recursive Step
    return 1 + findGolomb($n - 
        findGolomb(findGolomb($n - 1)));
}
  
// Print the first n 
// term of Golomb Sequence
function printGolomb($n)
{
      
    // Finding first n terms
    // of Golomb Sequence.
    for ($i = 1; $i <= $n; $i++) 
        echo findGolomb($i) , " "; 
}
  
// Driver Code

1173
Chapter 158. Golomb sequence

$n = 9;
printGolomb($n);
  
// This code is contributed by anuj_67.
?>

Output :

1 2 2 3 3 4 4 4 5

Below is the implementation using Dynamic Programming:

C++

// C++ Program to find first


// n terms of Golomb sequence.
#include <bits/stdc++.h>
using namespace std;
  
// Print the first n term 
// of Golomb Sequence
void printGolomb(int n)
{
    int dp[n + 1];
  
    // base cases
    dp[1] = 1;
    cout << dp[1] << " ";
  
    // Finding and printing first 
    // n terms of Golomb Sequence.
    for (int i = 2; i <= n; i++) 
    {
        dp[i] = 1 + dp[i - dp[dp[i - 1]]];
        cout << dp[i] << " ";
    }
}
// Driver Code
int main()
{
    int n = 9;
  
    printGolomb(n);
    return 0;
}

1174
Chapter 158. Golomb sequence

Java

// Java Program to find first 


// n terms of Golomb sequence.
import java.util.*;
  
class GFG 
{
      
    public static void printGolomb(int n)
    {
        int dp[] = new int[n + 1];
      
        // base cases
        dp[1] = 1;
        System.out.print(dp[1] + " ");
      
        // Finding and printing first n 
        // terms of Golomb Sequence.
        for (int i = 2; i <= n; i++) 
        {
            dp[i] = 1 + dp[i - dp[dp[i - 1]]];
              
        System.out.print(dp[i] + " ");
        }
    }
          
    // Driver code
    public static void main (String[] args)
    {
        int n = 9; 
          
        printGolomb(n);
    }
}
  
// This code is contributed by Akash Singh

C#

// C# Program to find first n 


// terms of Golomb sequence.
using System;
  
class GFG 
{
      

1175
Chapter 158. Golomb sequence

    // Print the first n term of 


    // Golomb Sequence
    static void printGolomb(int n)
    {
        int []dp = new int[n + 1];
      
        // base cases
        dp[1] = 1;
        Console.Write(dp[1] + " ");
      
        // Finding and printing first n 
        // terms of Golomb Sequence.
        for (int i = 2; i <= n; i++)
        {
            dp[i] = 1 + dp[i - dp[dp[i - 1]]];
            Console.Write( dp[i] + " ");
        }
    }
      
    // Driver Code
    public static void Main ()
    {
          
        int n = 9;
          
        printGolomb(n);
    }
}
  
// This code is contributed by vt_m

PHP

<?php
// PHP Program to find first
// n terms of Golomb sequence.
  
// Print the first n term
// of Golomb Sequence
function printGolomb($n)
{
    // base cases
    $dp[1] = 1;
    echo $dp[1], " ";
  
    // Finding and printing first 
    // n terms of Golomb Sequence.
    for ($i = 2; $i <= $n; $i++) 

1176
Chapter 158. Golomb sequence

    {
        $dp[$i] = 1 + $dp[$i - 
                          $dp[$dp[$i - 1]]];
        echo $dp[$i], " ";
    }
}
// Driver Code
$n = 9;
  
printGolomb($n);
  
// This code is contributed by ajit.
?>

Output :

1 2 2 3 3 4 4 4 5

Improved By : Smitha Dinesh Semwal, vt_m, jit_t

Source

https://www.geeksforgeeks.org/golomb-sequence/

1177
Chapter 159

Highway Billboard Problem

Highway Billboard Problem - GeeksforGeeks


Consider a highway of M miles. The task is to place billboards on the highway such that
revenue is maximized. The possible sites for billboards are given by number x1 < x2 <
….. < xn-1 < xn , specifying positions in miles measured from one end of the road. If we
place a billboard at position xi , we receive a revenue of ri > 0. There is a restriction that
no two billboards can be placed within t miles or less than it.
Note : All possible sites from x1 to xn are in range from 0 to M as need to place billboards
on a highway of M miles.
Examples:

Input : M = 20
x[] = {6, 7, 12, 13, 14}
revenue[] = {5, 6, 5, 3, 1}
t = 5
Output: 10
By placing two billboards at 6 miles and 12
miles will produce the maximum revenue of 10.

Input : M = 15
x[] = {6, 9, 12, 14}
revenue[] = {5, 6, 3, 7}
t = 2
Output : 18

Let maxRev[i], 1 <= i <= M, be the maximum revenue generated from beginning to i miles
on the highway. Now for each mile on the highway, we need to check whether this mile
has the option for any billboard, if not then the maximum revenue generated till that mile
would be same as maximum revenue generated till one mile before. But if that mile has the
option for billboard then we have 2 options:

1178
Chapter 159. Highway Billboard Problem

1. Either we will place the billboard, ignore the billboard in previous t miles, and add the
revenue of the billboard placed.
2. Ignore this billboard. So maxRev[i] = max(maxRev[i-t-1] + revenue[i], maxRev[i-1])
Below is implementation of this approach:
C++

// C++ program to find maximum revenue by placing


// billboard on the highway with given constarints.
#include<bits/stdc++.h>
using namespace std;
  
int maxRevenue(int m, int x[], int revenue[], int n,
                                              int t)
{
    // Array to store maximum revenue at each miles.
    int maxRev[m+1];
    memset(maxRev, 0, sizeof(maxRev));
  
    // actual minimum distance between 2 billboards.
    int nxtbb = 0;
    for (int i = 1; i <= m; i++)
    {
        // check if all billboards are already placed.
        if (nxtbb < n)
        {
            // check if we have billboard for that particular
            // mile. If not, copy the previous maximum revenue.
            if (x[nxtbb] != i)
                maxRev[i] = maxRev[i-1];
  
            // we do have billboard for this mile.
            else
            {
                // We have 2 options, we either take current 
                // or we ignore current billboard.
  
                // If current position is less than or equal to
                // t, then we can have only one billboard.
                if (i <= t)
                    maxRev[i] = max(maxRev[i-1], revenue[nxtbb]);
  
                // Else we may have to remove previously placed
                // billboard
                else
                    maxRev[i] = max(maxRev[i-t-1]+revenue[nxtbb],
                                                  maxRev[i-1]);
  

1179
Chapter 159. Highway Billboard Problem

                nxtbb++;
            }
        }
        else
            maxRev[i] = maxRev[i - 1];
    }
  
    return maxRev[m];
}
  
// Driven Program
int main()
{
    int m = 20;
    int x[] = {6, 7, 12, 13, 14};
    int revenue[] = {5, 6, 5, 3, 1};
    int n = sizeof(x)/sizeof(x[0]);
    int t = 5;
    cout << maxRevenue(m, x, revenue, n, t) << endl;
    return 0;
}

PHP

<?php
// PHP program to find 
// maximum revenue by
// placing billboard on 
// the highway with given
// constraints.
  
function maxRevenue($m, $x, 
                    $revenue, 
                    $n, $t)
                                              
{
    // Array to store maximum
    // revenue at each miles.
    $maxRev = array_fill(0, $m + 1, 
                            false);
      
    // actual minimum distance
    // between 2 billboards.
    $nxtbb = 0;
    for ($i = 1; $i <= $m; $i++)
    {
        // check if all billboards
        // are already placed.

1180
Chapter 159. Highway Billboard Problem

        if ($nxtbb < $n)


        {
            // check if we have billboard
            // for that particular
            // mile. If not, copy the 
            // previous maximum revenue.
            if ($x[$nxtbb] != $i)
                $maxRev[$i] = $maxRev[$i - 1];
  
            // we do have billboard 
            // for this mile.
            else
            {
                // We have 2 options, 
                // we either take 
                // current or we ignore 
                // current billboard.
  
                // If current position is
                // less than or equal to
                // t, then we can have only 
                // one billboard.
                if ($i <= $t)
                    $maxRev[$i] = max($maxRev[$i - 1], 
                                      $revenue[$nxtbb]);
  
                // Else we may have to
                // remove previously
                // placed billboard
                else
                    $maxRev[$i] = max($maxRev[$i - $t - 1] + 
                                      $revenue[$nxtbb],
                                      $maxRev[$i - 1]);
                $nxtbb++;
            }
        }
        else
            $maxRev[$i] = $maxRev[$i - 1];
    }
  
    return $maxRev[$m];
}
  
// Driver Code
$m = 20;
$x = array(6, 7, 12, 13, 14);
$revenue = array(5, 6, 5, 3, 1);
$n = sizeof($x);

1181
Chapter 159. Highway Billboard Problem

$t = 5;
echo maxRevenue($m, $x, 
                $revenue, $n, $t);
  
// This code is contributed by ajit
?>

Output:

10

Time Complexity: O(M), where M is distance of total Highway.


Auxiliary Space: O(M).
Source :
https://courses.cs.washington.edu/courses/cse421/06au/slides/Lecture18/Lecture18.pdf
Improved By : jit_t

Source

https://www.geeksforgeeks.org/highway-billboard-problem/

1182
Chapter 160

Hosoya’s Triangle

Hosoya’s Triangle - GeeksforGeeks


The Fibonnaci triangle or Hosoya’s triangle is a triangular arrangement of numbers
based on Fibonacci numbers. Each number is the sum of two numbers above in either the
left diagonal or the right diagonal. The first few rows are:

The numbers in this triangle follow the recurrence relations

1183
Chapter 160. Hosoya’s Triangle

Relation to Fibonacci numbers


The entries in the triangle satisfy the identity

Thus, the two outermost diagonals are the Fibonacci numbers, while the numbers on the
middle vertical lines are the squares of the Fibonacci numbers. All the other numbers in the
triangle are the product of two distinct Fibonacci numbers greater than 1. The row sums
are the first convolved Fibonnaci numbers.
Sources : Stackoverflow, Wikipedia
Given a positive integers n. The task is print Hosoya’s triangle of size n.
Examples:

Input : n = 4
Output :
1
1 1
2 1 2
3 2 2 3

Input : n = 5
Output :
1
1 1
2 1 2
3 2 2 3
5 3 4 3 5

Below is the implementation of printing Hosoya’s triangle of height n:

C++

// CPP Program to print Hosoya's


// triangle of height n.

1184
Chapter 160. Hosoya’s Triangle

#include <bits/stdc++.h>
using namespace std;
  
int Hosoya(int n, int m)
{
    // Base case
    if ((n == 0 && m == 0) ||
        (n == 1 && m == 0) || 
        (n == 1 && m == 1) ||
        (n == 2 && m == 1))
        return 1;
  
    // Recursive step
    if (n > m)
        return Hosoya(n - 1, m) 
               + Hosoya(n - 2, m);
  
    else if (m == n)
        return Hosoya(n - 1, m - 1) 
               + Hosoya(n - 2, m - 2);
  
    else
        return 0;
}
  
// Print the Hosoya triangle of height n.
void printHosoya(int n)
{
    for (int i = 0; i < n; i++) {
        for (int j = 0; j <= i; j++) 
            cout << Hosoya(i, j) << " ";     
  
        cout << endl;
    }
}
  
// Driven Program
int main()
{
    int n = 5;
    printHosoya(n);
    return 0;
}

Java

// Java Program to print Hosoya's 


// triangle of height n.

1185
Chapter 160. Hosoya’s Triangle

import java.util.*;
  
class GFG {
      
    static int Hosoya(int n, int m)
    {
        // Base case
        if ((n == 0 && m == 0) ||
            (n == 1 && m == 0) || 
            (n == 1 && m == 1) || 
            (n == 2 && m == 1))
            return 1;
       
        // Recursive step
        if (n > m)
            return Hosoya(n - 1, m)
                   + Hosoya(n - 2, m);
              
        else if (m == n)
            return Hosoya(n - 1, m - 1)
                    + Hosoya(n - 2, m - 2);
              
        else
            return 0;
    }
       
    // Print the Hosoya triangle of height n.
    static void printHosoya(int n)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j <= i; j++) 
                System.out.print(Hosoya(i, j) 
                                        + " ");       
       
            System.out.println("");
        }
    }
  
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int n = 5;
        printHosoya(n);
           
    }
}

1186
Chapter 160. Hosoya’s Triangle

  
// This code is contributed by  Arnav Kr. Mandal.

Python3

# Python3 code to print Hosoya's


# triangle of height n.
  
def Hosoya( n , m ):
  
    # Base case
    if ((n == 0 and m == 0) or
        (n == 1 and m == 0) or
        (n == 1 and m == 1) or
        (n == 2 and m == 1)):
                return 1
      
    # Recursive step
    if n > m:
        return Hosoya(n - 1, m) 
                    + Hosoya(n - 2, m)
  
    elif m == n:
        return Hosoya(n - 1, m - 1) 
                        + Hosoya(n - 2,    m - 2)
  
    else:
        return 0
          
# Print the Hosoya triangle of height n.
def printHosoya( n ):
    for i in range(n):
        for j in range(i + 1):
            print(Hosoya(i, j) , end = " ")
        print("\n", end = "")
          
# Driven Code
n = 5
printHosoya(n)
  
# This code is contributed by "Sharad_Bhardwaj".

C#

// C# Program to print Hosoya's 


// triangle of height n.
using System;

1187
Chapter 160. Hosoya’s Triangle

  
class GFG {
      
    static int Hosoya(int n, int m)
    {
        // Base case
        if ((n == 0 && m == 0) ||
            (n == 1 && m == 0) || 
            (n == 1 && m == 1) || 
            (n == 2 && m == 1))
            return 1;
      
        // Recursive step
        if (n > m)
            return Hosoya(n - 1, m)
                 + Hosoya(n - 2, m);
              
        else if (m == n)
            return Hosoya(n - 1, m - 1)
                 + Hosoya(n - 2, m - 2);
              
        else
            return 0;
    }
      
    // Print the Hosoya triangle of height n.
    static void printHosoya(int n)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j <= i; j++) 
                Console.Write(Hosoya(i, j) 
                                        + " "); 
      
            Console.WriteLine("");
        }
    }
  
      
    /* Driver program to test above function */
    public static void Main() 
    {
        int n = 5;
          
        printHosoya(n);
          
    }
}

1188
Chapter 160. Hosoya’s Triangle

  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program to print Hosoya's
// triangle of height n.
  
function Hosoya(int $n, int $m)
{
    // Base case
    if (($n == 0 && $m == 0) ||
        ($n == 1 && $m == 0) || 
        ($n == 1 && $m == 1) ||
        ($n == 2 && $m == 1))
        return 1;
  
    // Recursive step
    if ($n > $m)
        return Hosoya($n - 1,$m) + 
               Hosoya($n - 2, $m);
  
    else if ($m == $n)
        return Hosoya($n - 1, $m - 1) + 
               Hosoya($n - 2, $m - 2);
  
    else
        return 0;
}
  
// Print the Hosoya 
// triangle of height n.
function printHosoya( $n)
{
    for ( $i = 0; $i < $n; $i++)
    {
        for ( $j = 0; $j <= $i; $j++) 
            echo Hosoya($i, $j) , " "; 
            echo "\n";
    }
}
  
// Driven Code
$n = 5;
printHosoya($n);
  
// This code is contributed by anuj_67.

1189
Chapter 160. Hosoya’s Triangle

?>

Output :

1
1 1
2 1 2
3 2 2 3
5 3 4 3 5

Below is the implementation of printing Hosoya’s triangle of height n using Dynamic


Programming:

C++

// CPP Program to print Hosoya's triangle of height n.


#include <bits/stdc++.h>
#define N 5
using namespace std;
  
// Print the Hosoya triangle of height n.
void printHosoya(int n)
{
    int dp[N][N];
    memset(dp, 0, sizeof(dp));
  
    // base case.
    dp[0][0] = dp[1][0] = dp[1][1] = 1;
  
    // For each row.
    for (int i = 2; i < n; i++) {
  
        // for each column;
        for (int j = 0; j < n; j++) {
  
            // recursive steps.
            if (i > j)
                dp[i][j] = dp[i - 1][j] + dp[i - 2][j];
  
            else
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 2][j - 2];
        }
    }
  
    // printing the solution
    for (int i = 0; i < n; i++) {

1190
Chapter 160. Hosoya’s Triangle

        for (int j = 0; j <= i; j++) 


            cout << dp[i][j] << " ";        
  
        cout << endl;
    }
}
  
// Driven Program
int main()
{
    int n = 5;
    printHosoya(n);
    return 0;
}

Java

// JAVA Code for Hosoya Triangle


import java.util.*;
  
class GFG {
      
    static int N = 5;
      
    // Print the Hosoya triangle 
    // of height n.
    static void printHosoya(int n)
    {
        int dp[][] = new int[N][N];
          
        // base case.
        dp[0][0] = dp[1][0] = 1;
        dp[1][1] = 1;
       
        // For each row.
        for (int i = 2; i < n; i++) 
        {
            // for each column;
            for (int j = 0; j < n; j++) 
            {
                 // recursive steps.
                if (i > j)
                    dp[i][j] = dp[i - 1][j] + 
                                        dp[i - 2][j];
       
                else
                    dp[i][j] = dp[i - 1][j - 1] +
                                    dp[i - 2][j - 2];

1191
Chapter 160. Hosoya’s Triangle

            }
        }
       
        // printing the solution
        for (int i = 0; i < n; i++) 
        {
            for (int j = 0; j <= i; j++) 
                System.out.print(dp[i][j] + " ");        
       
            System.out.println("");
        }
    }
      
    /* Driver program*/
    public static void main(String[] args) 
    {
        int n = 5;
        printHosoya(n);
    }
}
  
// This code is contributed by Arnav Kr. Mandal.

C#

// C# Code for Hosoya Triangle


using System;
  
class GFG {
      
    static int N = 5;
      
    // Print the Hosoya triangle 
    // of height n.
    static void printHosoya(int n)
    {
        int [,]dp = new int[N,N];
          
        // base case.
        dp[0,0] = dp[1,0] = 1;
        dp[1,1] = 1;
      
        // For each row.
        for (int i = 2; i < n; i++) 
        {
            // for each column;
            for (int j = 0; j < n; j++) 
            {

1192
Chapter 160. Hosoya’s Triangle

                // recursive steps.


                if (i > j)
                    dp[i,j] = dp[i - 1,j] + 
                              dp[i - 2,j];
      
                else
                    dp[i,j] = dp[i - 1,j - 1] 
                           + dp[i - 2,j - 2];
            }
        }
      
        // printing the solution
        for (int i = 0; i < n; i++) 
        {
            for (int j = 0; j <= i; j++) 
                Console.Write(dp[i,j] + " "); 
      
            Console.WriteLine("");
        }
    }
      
    /* Driver program*/
    public static void Main() 
    {
        int n = 5;
          
        printHosoya(n);
    }
}
  
// This code is contributed by Vt_m.

Output :

1
1 1
2 1 2
3 2 2 3
5 3 4 3 5

Improved By : vt_m

Source

https://www.geeksforgeeks.org/hosoyas-triangle/

1193
Chapter 161

How to print maximum number


of A’s using given four keys

How to print maximum number of A’s using given four keys - GeeksforGeeks
This is a famous interview question asked in Google, Paytm and many other company
interviews.
Below is the problem statement.

Imagine you have a special keyboard with the following keys:


Key 1: Prints 'A' on screen
Key 2: (Ctrl-A): Select screen
Key 3: (Ctrl-C): Copy selection to buffer
Key 4: (Ctrl-V): Print buffer on screen appending it
after what has already been printed.

If you can only press the keyboard for N times (with the above four
keys), write a program to produce maximum numbers of A's. That is to
say, the input parameter is N (No. of keys that you can press), the
output is M (No. of As that you can produce).

Examples:

Input: N = 3
Output: 3
We can at most get 3 A's on screen by pressing
following key sequence.
A, A, A

1194
Chapter 161. How to print maximum number of A’s using given four keys

Input: N = 7
Output: 9
We can at most get 9 A's on screen by pressing
following key sequence.
A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V

Input: N = 11
Output: 27
We can at most get 27 A's on screen by pressing
following key sequence.
A, A, A, Ctrl A, Ctrl C, Ctrl V, Ctrl V, Ctrl A,
Ctrl C, Ctrl V, Ctrl V

Below are few important points to note.


a) For N < 7, the output is N itself.
b) Ctrl V can be used multiple times to print current buffer (See last two examples above).
The idea is to compute the optimal string length for N keystrokes by using a simple insight.
The sequence of N keystrokes which produces an optimal string length will end with a suffix
of Ctrl-A, a Ctrl-C, followed by only Ctrl-V’s . (For N > 6)
The task is to find out the break=point after which we get the above suffix of keystrokes.
Definition of a breakpoint is that instance after which we need to only press Ctrl-A, Ctrl-C
once and the only Ctrl-V’s afterwards to generate the optimal length. If we loop from N-3
to 1 and choose each of these values for the break-point, and compute that optimal string
they would produce. Once the loop ends, we will have the maximum of the optimal lengths
for various breakpoints, thereby giving us the optimal length for N keystrokes.
Below is implementation based on above idea.
C

/* A recursive C program to print maximum number of A's using 


   following four keys */
#include<stdio.h>
  
// A recursive function that returns the optimal length string 
// for N keystrokes
int findoptimal(int N)
{
    // The optimal string length is N when N is smaller than 7
    if (N <= 6)
        return N;
  
    // Initialize result
    int max = 0;
  
    // TRY ALL POSSIBLE BREAK-POINTS
    // For any keystroke N, we need to loop from N-3 keystrokes

1195
Chapter 161. How to print maximum number of A’s using given four keys

    // back to 1 keystroke to find a breakpoint 'b' after which we


    // will have Ctrl-A, Ctrl-C and then only Ctrl-V all the way.
    int b;
    for (b=N-3; b>=1; b--)
    {
            // If the breakpoint is s at b'th keystroke then
            // the optimal string would have length
            // (n-b-1)*screen[b-1];
            int curr = (N-b-1)*findoptimal(b);
            if (curr > max)
                max = curr;
     }
     return max;
}
  
// Driver program
int main()
{
    int N;
  
    // for the rest of the array we will rely on the previous
    // entries to compute new ones
    for (N=1; N<=20; N++)
        printf("Maximum Number of A's with %d keystrokes is %d\n",
               N, findoptimal(N));
}

Java

/* A recursive C program to print 


  maximum number of A's using 
  following four keys */
import java.io.*;
  
class GFG {
  
    // A recursive function that returns 
    // the optimal length string  for N keystrokes
    static int findoptimal(int N)
    {
        // The optimal string length is N
        // when N is smaller than 7
        if (N <= 6)
            return N;
      
        // Initialize result
        int max = 0;
      

1196
Chapter 161. How to print maximum number of A’s using given four keys

        // TRY ALL POSSIBLE BREAK-POINTS


        // For any keystroke N, we need to
        // loop from N-3 keystrokes back to 
        // 1 keystroke to find a breakpoint 
        // 'b' after which we will have Ctrl-A,
        //  Ctrl-C and then only Ctrl-V all the way.
        int b;
        for (b = N - 3; b >= 1; b--)
        {
                // If the breakpoint is s at b'th 
                // keystroke then the optimal string 
                // would have length
                // (n-b-1)*screen[b-1];
                int curr = (N - b - 1) * findoptimal(b);
                if (curr > max)
                    max = curr;
        }
        return max;
    }
      
    // Driver program
    public static void main(String[] args)
    {
        int N;
      
        // for the rest of the array we
        // will rely on the previous
        // entries to compute new ones
        for (N = 1; N <= 20; N++)
            System.out.println("Maximum Number of A's with keystrokes is " +
                                N + findoptimal(N));
    }
}
  
// This code is contributed by vt_m. 

C#

/* A recursive C# program 
to print maximum number 
of A's using following
four keys */
using System;
  
class GFG
{
// A recursive function that 
// returns the optimal length 

1197
Chapter 161. How to print maximum number of A’s using given four keys

// string for N keystrokes


static int findoptimal(int N)
{
    // The optimal string length
    // is N when N is smaller than 7
    if (N <= 6)
        return N;
  
    // Initialize result
    int max = 0;
  
    // TRY ALL POSSIBLE BREAK-POINTS
    // For any keystroke N, we need
    // to loop from N-3 keystrokes
    // back to 1 keystroke to find 
    // a breakpoint 'b' after which
    // we will have Ctrl-A, Ctrl-C 
    // and then only Ctrl-V all the way.
    int b;
    for (b = N - 3; b >= 1; b--)
    {
            // If the breakpoint is s 
            // at b'th keystroke then
            // the optimal string would
            // have length (n-b-1)*screen[b-1];
            int curr = (N - b - 1) * 
                        findoptimal(b);
            if (curr > max)
                max = curr;
    }
    return max;
}
  
// Driver code
static void Main()
{
    int N;
  
    // for the rest of the array 
    // we will rely on the 
    // previous entries to compute 
    // new ones
    for (N = 1; N <= 20; N++)
        Console.WriteLine("Maximum Number of A's with " +
                                  N + " keystrokes is " +
                                           findoptimal(N));
}
}

1198
Chapter 161. How to print maximum number of A’s using given four keys

  
// This code is contributed by Sam007

Output:

Maximum Number of A's with 1 keystrokes is 1


Maximum Number of A's with 2 keystrokes is 2
Maximum Number of A's with 3 keystrokes is 3
Maximum Number of A's with 4 keystrokes is 4
Maximum Number of A's with 5 keystrokes is 5
Maximum Number of A's with 6 keystrokes is 6
Maximum Number of A's with 7 keystrokes is 9
Maximum Number of A's with 8 keystrokes is 12
Maximum Number of A's with 9 keystrokes is 16
Maximum Number of A's with 10 keystrokes is 20
Maximum Number of A's with 11 keystrokes is 27
Maximum Number of A's with 12 keystrokes is 36
Maximum Number of A's with 13 keystrokes is 48
Maximum Number of A's with 14 keystrokes is 64
Maximum Number of A's with 15 keystrokes is 81
Maximum Number of A's with 16 keystrokes is 108
Maximum Number of A's with 17 keystrokes is 144
Maximum Number of A's with 18 keystrokes is 192
Maximum Number of A's with 19 keystrokes is 256
Maximum Number of A's with 20 keystrokes is 324

The above function computes the same subproblems again and again. Recomputations
of same subproblems can be avoided by storing the solutions to subproblems and solving
problems in bottom up manner.
Below is Dynamic Programming based C implementation where an auxiliary array screen[N]
is used to store result of subproblems.

/* A Dynamic Programming based C program to find maximum number of A's


   that can be printed using four keys */
#include<stdio.h>
  
// this function returns the optimal length string for N keystrokes
int findoptimal(int N)
{
    // The optimal string length is N when N is smaller than 7
    if (N <= 6)
        return N;
  

1199
Chapter 161. How to print maximum number of A’s using given four keys

    // An array to store result of subproblems


    int screen[N];
  
    int b;  // To pick a breakpoint
  
    // Initializing the optimal lengths array for uptil 6 input
    // strokes.
    int n;
    for (n=1; n<=6; n++)
        screen[n-1] = n;
  
    // Solve all subproblems in bottom manner
    for (n=7; n<=N; n++)
    {
        // Initialize length of optimal string for n keystrokes
        screen[n-1] = 0;
  
        // For any keystroke n, we need to loop from n-3 keystrokes
        // back to 1 keystroke to find a breakpoint 'b' after which we
        // will have ctrl-a, ctrl-c and then only ctrl-v all the way.
        for (b=n-3; b>=1; b--)
        {
            // if the breakpoint is at b'th keystroke then
            // the optimal string would have length
            // (n-b-1)*screen[b-1];
            int curr = (n-b-1)*screen[b-1];
            if (curr > screen[n-1])
                screen[n-1] = curr;
        }
    }
  
    return screen[N-1];
}
  
// Driver program
int main()
{
    int N;
  
    // for the rest of the array we will rely on the previous
    // entries to compute new ones
    for (N=1; N<=20; N++)
        printf("Maximum Number of A's with %d keystrokes is %d\n",
               N, findoptimal(N));
}

Java

1200
Chapter 161. How to print maximum number of A’s using given four keys

/* A Dynamic Programming based C 


   program to find maximum number
   of A's that can be printed using
   four keys */
import java.io.*;
  
class GFG {
      
    // this function returns the optimal 
    // length string for N keystrokes
    static int findoptimal(int N)
    {
        // The optimal string length is N 
        // when N is smaller than 7
        if (N <= 6)
            return N;
      
        // An array to store result
        // of subproblems
        int screen[] = new int[N];
      
        int b; // To pick a breakpoint
      
        // Initializing the optimal lengths 
        // array for uptil 6 input strokes
        int n;
        for (n = 1; n <= 6; n++)
            screen[n - 1] = n;
      
        // Solve all subproblems in bottom manner
        for (n = 7; n <= N; n++)
        {
            // Initialize length of optimal
            // string for n keystrokes
            screen[n - 1] = 0;
      
            // For any keystroke n, we need 
            // to loop from n-3 keystrokes
            // back to 1 keystroke to find 
            // a breakpoint 'b' after which we
            // will have ctrl-a, ctrl-c and
            // then only ctrl-v all the way.
            for (b = n - 3; b >= 1; b--)
            {
                // if the breakpoint is 
                // at b'th keystroke then
                // the optimal string would
                // have length

1201
Chapter 161. How to print maximum number of A’s using given four keys

                // (n-b-1)*screen[b-1];
                int curr = (n - b - 1) * screen[b - 1];
                if (curr > screen[n - 1])
                    screen[n - 1] = curr;
            }
        }
      
        return screen[N - 1];
    }
      
    // Driver program
    public static void main(String [] args)
    {
        int N;
      
        // for the rest of the array we will rely on the previous
        // entries to compute new ones
        for (N = 1; N <= 20; N++)
            System.out.println("Maximum Number of A's with keystrokes is "+
                                N + findoptimal(N));
    }
  
}
  
// This article is contributed by vt_m. 

Output:

Maximum Number of A's with 1 keystrokes is 1


Maximum Number of A's with 2 keystrokes is 2
Maximum Number of A's with 3 keystrokes is 3
Maximum Number of A's with 4 keystrokes is 4
Maximum Number of A's with 5 keystrokes is 5
Maximum Number of A's with 6 keystrokes is 6
Maximum Number of A's with 7 keystrokes is 9
Maximum Number of A's with 8 keystrokes is 12
Maximum Number of A's with 9 keystrokes is 16
Maximum Number of A's with 10 keystrokes is 20
Maximum Number of A's with 11 keystrokes is 27
Maximum Number of A's with 12 keystrokes is 36
Maximum Number of A's with 13 keystrokes is 48
Maximum Number of A's with 14 keystrokes is 64
Maximum Number of A's with 15 keystrokes is 81
Maximum Number of A's with 16 keystrokes is 108
Maximum Number of A's with 17 keystrokes is 144
Maximum Number of A's with 18 keystrokes is 192
Maximum Number of A's with 19 keystrokes is 256

1202
Chapter 161. How to print maximum number of A’s using given four keys

Maximum Number of A's with 20 keystrokes is 324

Thanks to Gaurav Saxena for providing the above approach to solve this problem.
Improved By : Sam007

Source

https://www.geeksforgeeks.org/how-to-print-maximum-number-of-a-using-given-four-keys/

1203
Chapter 162

How to solve a Dynamic


Programming Problem ?

How to solve a Dynamic Programming Problem ? - GeeksforGeeks


Dynamic Programming (DP) is a technique that solves some particular type of problems
in Polynomial Time. Dynamic Programming solutions are faster than exponential brute
method and can be easily proved for their correctness. Before we study how to think
Dynamically for a problem, we need to learn:

1. Overlapping Subproblems
2. Optimal Substructure Property

Steps to solve a DP
1) Identify if it is a DP problem
2) Decide a state expression with
least parameters
3) Formulate state relationship
4) Do tabulation (or add memoization)

Step 1 : How to classify a problem as a Dynamic Programming Problem?

• Typically, all the problems that require to maximize or minimize certain quantity
or counting problems that say to count the arrangements under certain condition or
certain probability problems can be solved by using Dynamic Programming.
• All dynamic programming problems satisfy the overlapping subproblems property and
most of the classic dynamic problems also satisfy the optimal substructure property.
Once, we observe these properties in a given problem, be sure that it can be solved
using DP.

Step 2 : Deciding the state


DP problems are all about state and their transition. This is the most basic step which must

1204
Chapter 162. How to solve a Dynamic Programming Problem ?

be done very carefully because the state transition depends on the choice of state definition
you make. So, let’s see what do we mean by the term “state”.
State A state can be defined as the set of parameters that can uniquely identify a certain
position or standing in the given problem. This set of parameters should be as small as
possible to reduce state space.
For example: In our famous Knapsack problem, we define our state by two parameters
index and weight i.e DP[index][weight]. Here DP[index][weight] tells us the maximum
profit it can make by taking items from range 0 to index having the capacity of sack to be
weight. Therefore, here the parameters index and weight together can uniquely identify a
subproblem for the knapsack problem.
So, our first step will be deciding a state for the problem after identifying that the problem
is a DP problem.
As we know DP is all about using calculated results to formulate the final result.
So, our next step will be to find a relation between previous states to reach the current state.

Step 3 : Formulating a relation among the states


This part is the hardest part of for solving a DP problem and requires a lot of intuition,
observation and practice. Let’s understand it by considering a sample problem

Given 3 numbers {1, 3, 5}, we need to tell


the total number of ways we can form a number 'N'
using the sum of the given three numbers.
(allowing repetitions and different arrangements).

Total number of ways to form 6 is: 8


1+1+1+1+1+1
1+1+1+3
1+1+3+1
1+3+1+1
3+1+1+1
3+3
1+5
5+1

Let’s think dynamically about this problem. So, first of all, we decide a state for the
given problem. We will take a parameter n to decide state as it can uniquely identify any
subproblem. So, our state dp will look like state(n). Here, state(n) means the total number
of arrangements to form n by using {1, 3, 5} as elements.
Now, we need to compute state(n).
How to do it?
So here the intuition comes into action. As we can only use 1, 3 or 5 to form a given number.
Let us assume that we know the result for n = 1,2,3,4,5,6 ; being termilogistic let us say we

1205
Chapter 162. How to solve a Dynamic Programming Problem ?

know the result for the


state (n = 1), state (n = 2), state (n = 3) ……… state (n = 6)
Now, we wish to know the result of the state (n = 7). See, we can only add 1, 3 and 5. Now
we can get a sum total of 7 by the following 3 ways:
1) Adding 1 to all possible combinations of state (n = 6)
Eg : [ (1+1+1+1+1+1) + 1]
[ (1+1+1+3) + 1]
[ (1+1+3+1) + 1]
[ (1+3+1+1) + 1]
[ (3+1+1+1) + 1]
[ (3+3) + 1]
[ (1+5) + 1]
[ (5+1) + 1]
2) Adding 3 to all possible combinations of state (n = 4);
Eg : [(1+1+1+1) + 3]
[(1+3) + 3]
[(3+1) + 3]
3) Adding 5 to all possible combinations of state(n = 2)
Eg : [ (1+1) + 5]
Now, think carefully and satisfy yourself that the above three cases are covering all possible
ways to form a sum total of 7;
Therefore, we can say that result for
state(7) = state (6) + state (4) + state (2)
or
state(7) = state (7-1) + state (7-3) + state (7-5)
In general,
state(n) = state(n-1) + state(n-3) + state(n-5)
So, our code will look like:

// Returns the number of arrangements to 


// form 'n' 
int solve(int n)

   // base case
   if (n < 0) 
      return 0;
   if (n == 0)  
      return 1;  
  
   return solve(n-1) + solve(n-3) + solve(n-5);
}    

The above code seems exponential as it is calculating the same state again and again. So,

1206
Chapter 162. How to solve a Dynamic Programming Problem ?

we just need to add a memoization.

Step 4 : Adding memoization or tabulation for the state


This is the easiest part of a dynamic programming solution. We just need to store the state
answer so that next time that state is required, we can directly use it from our memory
Adding memoization to the above code

// initialize to -1
int dp[MAXN];
  
// this function returns the number of 
// arrangements to form 'n' 
int solve(int n)

  // base case
  if (n < 0)  
      return 0;
  if (n == 0)  
      return 1;
  
  // checking if already calculated
  if (dp[n]!=-1) 
      return dp[n];
  
  // storing the result and returning
  return dp[n] = solve(n-1) + solve(n-3) + solve(n-5);
}

Another way is to add tabulation and make solution iterative. Please refer tabulation and
memoization for more details.
Dynamic Programming comes with a lots of practice. One must try solving various classic
DP problems that can be found here. You may check the below problems first and try
solving them using the above described steps:-

• http://www.spoj.com/problems/COINS/
• http://www.spoj.com/problems/ACODE/
• https://www.geeksforgeeks.org/dynamic-programming-set-6-min-cost-path/
• https://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/
• https://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
• https://www.geeksforgeeks.org/dynamic-programming-set-5-edit-distance/

Source

https://www.geeksforgeeks.org/solve-dynamic-programming-problem/

1207
Chapter 163

Jacobsthal and
Jacobsthal-Lucas numbers

Jacobsthal and Jacobsthal-Lucas numbers - GeeksforGeeks


The Jacobsthal sequence is an additive sequence similar to the Fibonacci sequence, defined
by the recurrence relation Jn = Jn-1 + Jn-2 , with initial terms J0 = 0 and J1 = 1. A number
in the sequence is called a Jacobsthal number. They are a specific type of Lucas sequence
Un (P, Q) for which P = -1 and Q = -2.
The first Jacobsthal numbers are:
0, 1, 1, 3, 5, 11, 21, 43, 85, 171, 341, 683, 1365, 2731, 5461, 10923, 21845, 43691, ……
Jacobsthal numbers are defined by the recurrence relation:

Jacobsthal-Lucas numbers
Jacobsthal-Lucas numbers represent the complementary Lucas sequence Vn (1, -2). They
satisfy the same recurrence relation as Jacobsthal numbers but have different initial

values:
Given a positive integer n. The task is to find nth Jacobsthal and Jacobsthal-Lucas numbers.
Examples :

1208
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

Input : n = 5
Output :
Jacobsthal number: 11
Jacobsthal-Lucas number: 31

Input : n = 4
Output :
Jacobsthal number: 5
Jacobsthal-Lucas number: 17

Below is the implementation of finding nth Jacobsthal and Jacobsthal-Lucas numbers using
recursion.

C++

// A simple C++ recursive solution to find 


// Jacobsthal and Jacobsthal-Lucas numbers 
#include <bits/stdc++.h>
using namespace std;
  
// Return nth Jacobsthal number.
int Jacobsthal(int n)
{
    // base case
    if (n == 0)
        return 0;
  
    // base case
    if (n == 1)
        return 1;
  
    // recursive step.
    return Jacobsthal(n - 1) + 2 * Jacobsthal(n - 2);
}
  
// Return nth Jacobsthal-Lucas number.
int Jacobsthal_Lucas(int n)
{
    // base case
    if (n == 0)
        return 2;
  
    // base case
    if (n == 1)
        return 1;
  
    // recursive step.

1209
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

    return Jacobsthal_Lucas(n - 1) + 
           2 * Jacobsthal_Lucas(n - 2);
}
  
// Driven Program
int main()
{
    int n = 5;
    cout << "Jacobsthal number: " << Jacobsthal(n) << endl;
    cout << "Jacobsthal-Lucas number: " << Jacobsthal_Lucas(n) << endl;
    return 0;
}

Java

// A simple recursive solution


// to find Jacobsthal and 
// Jacobsthal-Lucas numbers 
import java.util.*;
import java.lang.*;
  
public class GfG{
  
    // Return nth Jacobsthal number.
    public static int Jacobsthal(int n)
    {
        // base case
        if (n == 0)
            return 0;
  
        // base case
        if (n == 1)
            return 1;
  
        // recursive step.
        return Jacobsthal(n - 1) + 2 * Jacobsthal(n - 2);
    }
  
    // Return nth Jacobsthal-Lucas number.
    public static int Jacobsthal_Lucas(int n)
    {
        // base case
        if (n == 0)
            return 2;
  
        // base case
        if (n == 1)
            return 1;

1210
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

  
        // recursive step.
        return Jacobsthal_Lucas(n - 1) + 
               2 * Jacobsthal_Lucas(n - 2); 
    }
  
    // Driver function
    public static void main(String argc[]){
        int n = 5;
        System.out.println("Jacobsthal number: "
                            + Jacobsthal(n));
        System.out.println("Jacobsthal-Lucas number: " 
                            + Jacobsthal_Lucas(n));
    }
}
  
/* This code is cotributed Sagar Shukla */

Python3

# A simple Python3 recursive solution to  


# find Jacobsthal and Jacobsthal-Lucas 
# numbers 
  
# Return nth Jacobsthal number.
def Jacobsthal(n):
    # base case
    if (n == 0):
        return 0
  
    # base case
    if (n == 1):
        return 1
  
    # recursive step.
    return Jacobsthal(n - 1) + 2 * Jacobsthal(n - 2)
  
# Return nth Jacobsthal-Lucas number.
def Jacobsthal_Lucas(n):
    # base case
    if (n == 0):
        return 2
          
    # base case
    if (n == 1):
        return 1
  
    # recursive step.

1211
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

    return Jacobsthal_Lucas(n - 1) + 2 * Jacobsthal_Lucas(n - 2)


  
# Driven Program
n = 5
print("Jacobsthal number:", Jacobsthal(n))
print("Jacobsthal-Lucas number:", Jacobsthal_Lucas(n))
  
# This code is contributed by Smitha Dinesh Semwal

C#

// A simple recursive solution


// to find Jacobsthal and 
// Jacobsthal-Lucas numbers 
using System;
  
public class GfG {
  
    // Return nth Jacobsthal number.
    public static int Jacobsthal(int n)
    {
        // base case
        if (n == 0) return 0;
  
        // base case
        if (n == 1) return 1;
  
        // recursive step.
        return Jacobsthal(n - 1) +
               2 * Jacobsthal(n - 2);
    }
  
    // Return nth Jacobsthal-Lucas number.
    public static int Jacobsthal_Lucas(int n)
    {
        // base case
        if (n == 0) return 2;
  
        // base case
        if (n == 1) return 1;
  
        // recursive step
        return Jacobsthal_Lucas(n - 1) + 
                2 * Jacobsthal_Lucas(n - 2); 
    }
  
    // Driver function
    public static void Main() {

1212
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

        int n = 5;
        Console.WriteLine("Jacobsthal number: "
                                + Jacobsthal(n));
        Console.WriteLine("Jacobsthal-Lucas number: "
                                + Jacobsthal_Lucas(n));
    }
}
  
// This code is cotributed vt_m 

PHP

<?php
// A simple PHP recursive solution 
// to find Jacobsthal and 
// Jacobsthal-Lucas numbers 
  
// Return nth Jacobsthal number.
function Jacobsthal($n)
{
    // base case
    if ($n == 0)
        return 0;
  
    // base case
    if ($n == 1)
        return 1;
  
    // recursive step.
    return Jacobsthal($n - 1) + 
        2 * Jacobsthal($n - 2);
}
  
// Return nth Jacobsthal-
// Lucas number.
function Jacobsthal_Lucas($n)
{
    // base case
    if ($n == 0)
        return 2;
  
    // base case
    if ($n == 1)
        return 1;
  
    // recursive step.
    return Jacobsthal_Lucas($n - 1) + 
        2 * Jacobsthal_Lucas($n - 2);

1213
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

}
  
// Driven Code
$n = 5;
echo "Jacobsthal number: " , 
      Jacobsthal($n) , "\n";
echo "Jacobsthal-Lucas number: ", 
      Jacobsthal_Lucas($n), "\n";
  
// This code is contributed by aj_36 
?>

Output :

Jacobsthal number: 11
Jacobsthal-Lucas number: 31

Below is the implementation of finding nth Jacobsthal and Jacobsthal-Lucas numbers using
Dynamic Programming.
C++

// A DP based solution to find Jacobsthal


// and Jacobsthal-Lucas numbers 
#include <bits/stdc++.h>
using namespace std;
  
// Return nth Jacobsthal number.
int Jacobsthal(int n)
{
    int dp[n + 1];
  
    // base case
    dp[0] = 0;
    dp[1] = 1;
  
    for (int i = 2; i <= n; i++)
        dp[i] = dp[i - 1] + 2 * dp[i - 2];
  
    return dp[n];
}
  
// Return nth Jacobsthal-Lucas number.
int Jacobsthal_Lucas(int n)
{
    int dp[n + 1];
  

1214
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

    // base case


    dp[0] = 2;
    dp[1] = 1;
  
    for (int i = 2; i <= n; i++)
        dp[i] = dp[i - 1] + 2 * dp[i - 2];
  
    return dp[n];
}
// Driven Program
int main()
{
    int n = 5;
    cout << "Jacobsthal number: " << Jacobsthal(n) << endl;
    cout << "Jacobsthal-Lucas number: " << Jacobsthal_Lucas(n) << endl;
    return 0;
}

Java

// A DP based solution
// to find Jacobsthal and 
// Jacobsthal-Lucas numbers 
import java.util.*;
import java.lang.*;
  
public class GfG{
  
    // Return nth Jacobsthal number.
    public static int Jacobsthal(int n)
    {
        int[] dp = new int[n + 1];
  
        // base case
        dp[0] = 0;
        dp[1] = 1;
  
        for (int i = 2; i <= n; i++)
            dp[i] = dp[i - 1] + 2 * dp[i - 2];
  
        return dp[n];
    }
  
    // Return nth Jacobsthal-Lucas number.
    public static int Jacobsthal_Lucas(int n)
    {
        int[] dp = new int[n + 1];
  

1215
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

        // base case


        dp[0] = 2;
        dp[1] = 1;
  
        for (int i = 2; i <= n; i++)
            dp[i] = dp[i - 1] + 2 * dp[i - 2];
  
        return dp[n];
    }
  
    // Driver function
    public static void main(String argc[]){
        int n = 5;
        System.out.println("Jacobsthal number: "
                            + Jacobsthal(n));
        System.out.println("Jacobsthal-Lucas number: "
                            + Jacobsthal_Lucas(n));
    }
      
}
  
/* This code is cotributed Sagar Shukla */

Python3

# A DP based solution to find


# Jacobsthal and Jacobsthal-
# Lucas numbers 
  
# Return nth Jacobsthal number.
def Jacobsthal(n):
    dp = [0] * (n + 1)
  
    # base case
    dp[0] = 0
    dp[1] = 1
  
    for i in range(2, n+1):
        dp[i] = dp[i - 1] + 2 * dp[i - 2]
      
    return dp[n]
  
  
# Return nth Jacobsthal-
# Lucas number.
def Jacobsthal_Lucas(n):
  
    dp=[0] * (n + 1)

1216
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

      
    # base case
    dp[0] = 2
    dp[1] = 1
      
    for i in range(2, n+1):
        dp[i] = dp[i - 1] + 2 * dp[i - 2];
      
    return dp[n]
  
# Driven Program
n = 5
  
print("Jacobsthal number:",Jacobsthal(n))
print("Jacobsthal-Lucas number:",Jacobsthal_Lucas(n))
  
# This code is contributed by Smitha Dinesh Semwal

C#

// A DP based solution
// to find Jacobsthal and 
// Jacobsthal-Lucas numbers 
using System;
  
public class GfG {
  
    // Return nth Jacobsthal number.
    public static int Jacobsthal(int n)
    {
        int[] dp = new int[n + 1];
  
        // base case
        dp[0] = 0;
        dp[1] = 1;
  
        for (int i = 2; i <= n; i++)
            dp[i] = dp[i - 1] + 2 * dp[i - 2];
  
        return dp[n];
    }
  
    // Return nth Jacobsthal-Lucas number.
    public static int Jacobsthal_Lucas(int n)
    {
        int[] dp = new int[n + 1];
  
        // base case

1217
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

        dp[0] = 2;
        dp[1] = 1;
  
        for (int i = 2; i <= n; i++)
            dp[i] = dp[i - 1] + 2 * dp[i - 2];
  
        return dp[n];
    }
  
    // Driver Code
    public static void Main() {
        int n = 5;
        Console.WriteLine("Jacobsthal number: "
                                + Jacobsthal(n));
        Console.WriteLine("Jacobsthal-Lucas number: "
                                + Jacobsthal_Lucas(n));
    }
      
}
  
// This code is cotributed vt_m

PHP

<?php
// A DP based solution to 
// find Jacobsthal and 
// Jacobsthal-Lucas numbers 
  
// Return nth Jacobsthal number.
function Jacobsthal($n)
{
    //$dp[$n + 1];
  
    // base case
    $dp[0] = 0;
    $dp[1] = 1;
  
    for ($i = 2; $i <= $n; $i++)
        $dp[$i] = $dp[$i - 1] + 2 * 
                  $dp[$i - 2];
  
    return $dp[$n];
}
  
// Return nth Jacobsthal-
// Lucas number.
function Jacobsthal_Lucas($n)

1218
Chapter 163. Jacobsthal and Jacobsthal-Lucas numbers

{
    // $dp[$n + 1];
  
    // base case
    $dp[0] = 2;
    $dp[1] = 1;
  
    for ($i = 2; $i <= $n; $i++)
        $dp[$i] = $dp[$i - 1] + 2 * 
                  $dp[$i - 2];
  
    return $dp[$n];
}
  
// Driver Code
$n = 5;
echo "Jacobsthal number: " ,
       Jacobsthal($n), "\n";
echo "Jacobsthal-Lucas number: " ,
       Jacobsthal_Lucas($n), "\n";
          
// This code is contributed by ajit
?>

Output:

Jacobsthal number: 11
Jacobsthal-Lucas number: 31

Improved By : jit_t

Source

https://www.geeksforgeeks.org/jacobsthal-and-jacobsthal-lucas-numbers/

1219
Chapter 164

K maximum sums of
non-overlapping contiguous
sub-arrays

K maximum sums of non-overlapping contiguous sub-arrays - GeeksforGeeks


Given an Array of Integers and an Integer value k, find out k non-overlapping sub-arrays
which have k maximum sums.

Examples:

Input : arr1[] = {4, 1, 1, -1, -3, -5, 6, 2, -6, -2},


k = 3.
Output : Maximum non-overlapping sub-array sum1: 8,
starting index: 6, ending index: 7.

Maximum non-overlapping sub-array sum2: 6,


starting index: 0, ending index: 2.

Maximum non-overlapping sub-array sum3: -1,


starting index: 3, ending index: 3.

Input : arr2 = {5, 1, 2, -6, 2, -1, 3, 1},

1220
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

k = 2.
Output : Maximum non-overlapping sub-array sum1: 8,
starting index: 0, ending index: 2.

Maximum non-overlapping sub-array sum2: 5,


starting index: 4, ending index: 7.

Prerequisite: Kadane’s Algorithm


Kadane’s algorithm finds out only the maximum subarray sum, but using the same algorithm
we can find out k maximum non-overlapping subarray sums. The approach is:

• Find out the maximum subarray in the array using Kadane’s algorithm. Also find out
its starting and end indices. Print the sum of this subarray.
• Fill each cell of this subarray by -infinity.
• Repeat process 1 and 2 for k times.

C++

// C++ program to find out k maximum 


// non-overlapping sub-array sums.
#include <bits/stdc++.h>
using namespace std;
  
// Function to compute k maximum
// sub-array sums.
void kmax(int arr[], int k, int n) {
  
    // In each iteration it will give
    // the ith maximum subarray sum.
    for(int c = 0; c < k; c++){
  
        // Kadane's algorithm.
        int max_so_far = numeric_limits<int>::min();
        int max_here = 0;
  
        // compute starting and ending
        // index of each of the sub-array.
        int start = 0, end = 0, s = 0;
        for(int i = 0; i < n; i++)
        {
            max_here += arr[i];
            if (max_so_far < max_here)
            {
                max_so_far = max_here;
                start = s;
                end = i;
            }

1221
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

            if (max_here < 0)


            {
                max_here = 0;
                s = i + 1;
            }
        }
  
        // Print out the result.
        cout << "Maximum non-overlapping sub-array sum"
             << (c + 1) << ": "<< max_so_far 
             << ", starting index: " << start 
             << ", ending index: " << end << "." << endl;
  
        // Replace all elements of the maximum subarray 
        // by -infinity. Hence these places cannot form 
        // maximum sum subarray again.
        for (int l = start; l <= end; l++)
            arr[l] = numeric_limits<int>::min();
    }
    cout << endl;
}
  
// Driver Program
int main()
{
    // Test case 1
    int arr1[] = {4, 1, 1, -1, -3, 
                 -5, 6, 2, -6, -2};
    int k1 = 3;
    int n1 = sizeof(arr1) / sizeof(arr1[0]);
      
    // Function calling
    kmax(arr1, k1, n1);
  
    // Test case 2
    int arr2[] = {5, 1, 2, -6, 2, -1, 3, 1};
    int k2 = 2;
    int n2 = sizeof(arr2)/sizeof(arr2[0]);
      
    // Function calling
    kmax(arr2, k2, n2);
      
    return 0;
}

Java

// Java program to find out k maximum 

1222
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

// non-overlapping sub-array sums.


  
class GFG {
  
    // Method to compute k maximum 
    // sub-array sums.
    static void kmax(int arr[], int k, int n) {
      
        // In each iteration it will give
        // the ith maximum subarray sum.
        for(int c = 0; c < k; c++)
        { 
            // Kadane's algorithm.
            int max_so_far = Integer.MIN_VALUE;
            int max_here = 0;
      
            // compute starting and ending
            // index of each of the sub-array.
            int start = 0, end = 0, s = 0;
            for(int i = 0; i < n; i++)
            {
                max_here += arr[i];
                if (max_so_far < max_here)
                {
                    max_so_far = max_here;
                    start = s;
                    end = i;
                }
                if (max_here < 0)
                    {
                    max_here = 0;
                    s = i + 1;
                }
            }
      
            // Print out the result.
            System.out.println("Maximum non-overlapping sub-arraysum" +
                                (c + 1) + ": " +  max_so_far + 
                                ", starting index: " + start +
                                ", ending index: " + end + ".");
      
            // Replace all elements of the maximum subarray 
            // by -infinity. Hence these places cannot form 
            // maximum sum subarray again.
            for (int l = start; l <= end; l++)
                arr[l] = Integer.MIN_VALUE;
        }
        System.out.println();

1223
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

    }
      
    // Driver Program
    public static void main(String[] args)
    {
        // Test case 1
        int arr1[] = {4, 1, 1, -1, -3, -5, 
                            6, 2, -6, -2};
        int k1 = 3;
        int n1 = arr1.length;
          
        // Function calling
        kmax(arr1, k1, n1);
      
        // Test case 2
        int arr2[] = {5, 1, 2, -6, 2, -1, 3, 1};
        int k2 = 2;
        int n2 = arr2.length;
          
        // Function calling
        kmax(arr2, k2, n2);
    }
}
  
// This code is contributed by Nirmal Patel

Python3

# Python program to find out k maximum 


# non-overlapping subarray sums.
  
# Function to compute k 
# maximum sub-array sums.
def kmax(arr, k, n):
  
    # In each iteration it will give
    # the ith maximum subarray sum.
    for c in range(k):
  
        # Kadane's algorithm
        max_so_far = -float("inf")
        max_here = 0
  
        # compute starting and ending
        # index of each of the subarray
        start = 0
        end = 0
        s = 0

1224
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

        for i in range(n):
              
            max_here += arr[i]
            if (max_so_far < max_here):
                  
                max_so_far = max_here
                start = s
                end = i
            if (max_here < 0):
                  
                max_here = 0
                s = i + 1
  
        # Print out the result
        print("Maximum non-overlapping sub-array sum",
               c + 1, ": ", max_so_far, ", starting index: ",
               start, ", ending index: ", end, ".", sep = "")
  
        # Replace all elements of the maximum subarray
        # by -infinity. Hence these places cannot form 
        # maximum sum subarray again.
        for l in range(start, end+1):
            arr[l] = -float("inf")
    print()
  
# Driver Program
# Test case 1
arr1 = [4, 1, 1, -1, -3, -5, 6, 2, -6, -2]
k1 = 3
n1 = len(arr1)
  
# Function calling
kmax(arr1, k1, n1)
  
# Test case 2
arr2 = [5, 1, 2, -6, 2, -1, 3, 1]
k2 = 2
n2 = len(arr2)
  
# Function calling
kmax(arr2, k2, n2)

C#

// C# program to find out k maximum 


// non-overlapping sub-array sums.
using System;
  

1225
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

class GFG {
  
    // Method to compute k 
    // maximum sub-array sums.
    static void kmax(int []arr, int k, int n) {
      
        // In each iteration it will give
        // the ith maximum subarray sum.
        for(int c = 0; c < k; c++)
        { 
            // Kadane's algorithm.
            int max_so_far = int.MinValue;
            int max_here = 0;
      
            // compute starting and ending
            // index of each of the sub-array.
            int start = 0, end = 0, s = 0;
            for(int i = 0; i < n; i++)
            {
                max_here += arr[i];
                if (max_so_far < max_here)
                {
                    max_so_far = max_here;
                    start = s;
                    end = i;
                }
                if (max_here < 0)
                {
                    max_here = 0;
                    s = i + 1;
                }
            }
      
            // Print out the result.
            Console.WriteLine("Maximum non-overlapping sub-arraysum" +
                              (c + 1) + ": "+ max_so_far + 
                              ", starting index: " + start + 
                              ", ending index: " + end + ".");
      
            // Replace all elements of the maximum subarray 
            // by -infinity. Hence these places cannot form 
            // maximum sum subarray again.
            for (int l = start; l <= end; l++)
                arr[l] = int.MinValue;
        }
    Console.WriteLine();
    }
      

1226
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

    // Driver Program


    public static void Main(String[] args)
    {
        // Test case 1
        int []arr1 = {4, 1, 1, -1, -3, -5,
                            6, 2, -6, -2};
        int k1 = 3;
        int n1 = arr1.Length;
          
        // Function calling
        kmax(arr1, k1, n1);
      
        // Test case 2
        int []arr2 = {5, 1, 2, -6, 2, -1, 3, 1};
        int k2 = 2;
        int n2 = arr2.Length;
          
        // Function calling
        kmax(arr2, k2, n2);
    }
}
  
// This code is contributed by parashar...

PHP

<?php
// PHP program to find out k maximum 
// non-overlapping sub-array sums.
  
    // Method to compute k 
    // maximum sub-array sums.
    function kmax($arr, $k, $n) {
      
        // In each iteration it will give
        // the ith maximum subarray sum.
        for( $c = 0; $c < $k; $c++)
        { 
            // Kadane's algorithm.
            $max_so_far = PHP_INT_MIN;
            $max_here = 0;
      
            // compute starting and ending
            // index of each of the sub-array.
            $start = 0; $end = 0; $s = 0;
            for($i = 0; $i < $n; $i++)
            {
                $max_here += $arr[$i];

1227
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

                if ($max_so_far < $max_here)


                {
                    $max_so_far = $max_here;
                    $start = $s;
                    $end = $i;
                }
                if ($max_here < 0)
                {
                    $max_here = 0;
                    $s = $i + 1;
                }
            }
      
            // Print out the result.
            echo "Maximum non-overlapping sub-arraysum" ;
            echo ($c + 1) , ": ", $max_so_far ; 
            echo", starting index: " , $start ;
            echo", ending index: " , $end , ".";
            echo"\n";
      
            // Replace all elements of the maximum subarray 
            // by -infinity. Hence these places cannot form 
            // maximum sum subarray again.
            for ( $l = $start; $l <= $end; $l++)
                $arr[$l] = PHP_INT_MIN;
        }
        echo "\n";
    }
      
    // Driver Program
        // Test case 1
        $arr1 = array(4, 1, 1, -1, -3, -5,
                            6, 2, -6, -2);
        $k1 = 3;
        $n1 = count($arr1);
          
        // Function calling
        kmax($arr1, $k1, $n1);
      
        // Test case 2
        $arr2 = array(5, 1, 2, -6, 2, -1, 3, 1);
        $k2 = 2;
        $n2 =count($arr2);
          
        // Function calling
        kmax($arr2, $k2, $n2);
  
// This code is contributed by anuj_67.

1228
Chapter 164. K maximum sums of non-overlapping contiguous sub-arrays

?>

Output:

Maximum non-overlapping sub-array sum1: 8, starting index: 6, ending index: 7.


Maximum non-overlapping sub-array sum2: 6, starting index: 0, ending index: 2.
Maximum non-overlapping sub-array sum3: -1, starting index: 3, ending index: 3.

Maximum non-overlapping sub-array sum1: 8, starting index: 0, ending index: 2.


Maximum non-overlapping sub-array sum2: 5, starting index: 4, ending index: 7.

Time Complexity: The outer loop runs for k times and kadane’s algorithm in each itera-
tion runs in linear time O(n). Hence the overall time complexity is O(k*n).
Improved By : Nims972, parashar, vt_m

Source

https://www.geeksforgeeks.org/k-maximum-sums-non-overlapping-contiguous-sub-arrays/

1229
Chapter 165

K maximum sums of
overlapping contiguous
sub-arrays

K maximum sums of overlapping contiguous sub-arrays - GeeksforGeeks


Given an Array of Integers and an Integer value k, find out k sub-arrays(may be overlapping)
which have k maximum sums.
Examples:

Input : arr = {4, -8, 9, -4, 1, -8, -1, 6}, k = 4


Output : 9 6 6 5

Input : arr = {-2, -3, 4, -1, -2, 1, 5, -3}, k= 3


Output : 7 6 5

Using Kadane’s Algorithm we can find the maximum contiguous subarray sum of an array.
But in the case Kadane’s Algorithm does not work. As whenever we hit an negative number
in the array we set the max_ending_here variable to zero, hence we miss the possibilities
for second and so on maximums.
Here we is an algorithm presented by Sung Eun Bae and Tadao Takaoka which computes
the maximum sub-array sum problem in O(n) time and k maximum sub-array sum problem
in O(k*n) time.
First we look at the problem of only maximum sub-array sum using this method:
Prerequisite:
1. Prefix sum array
2. Maximum subarray sum in O(n) using prefix sum

1230
Chapter 165. K maximum sums of overlapping contiguous sub-arrays

Method for k-maximum sub-arrays:

1. Calculate the prefix sum of the input array.


2. Take cand, maxi and mini as arrays of size k.
3. Initialize mini[0] = 0 for the same reason as previous.
4. for each value of the prefix_sum[i] do
(i). update cand[j] value by prefix_sum[i] - mini[j]
(ii). maxi will be the maximum k elements of maxi and cand
(iii). if prefix_sum is minimum than all values of mini then
include it in mini and remove maximum element form mini
// After the ith iteration mini holds k minimum prefix sum upto
// index i and maxi holds k maximum overlapping sub-array sums
// upto index i.
5. return maxi

Throughout this calculation method we keep maxi in non-increasing and mini in non-
decreasing order.
C++

// C++ program to find out k maximum sum of


// overlapping sub-arrays
#include <iostream>
#include <limits>
#include <vector>
  
using namespace std;
  
// Function to compute prefix-sum of the input array
vector<int> prefix_sum(vector<int> arr, int n)
{
    vector<int> pre_sum;
    pre_sum.push_back(arr[0]);
    for (int i = 1; i < n; i++) 
        pre_sum.push_back(pre_sum[i - 1] + arr[i]);    
    return pre_sum;
}
  
// Update maxi by k maximum values from maxi and cand
void maxMerge(vector<int>& maxi, vector<int> cand)
{
    // Here cand and maxi arrays are in non-increasing
    // order beforehand. Now, j is the index of the
    // next cand element and i is the index of next
    // maxi element. Traverse through maxi array.
    // If cand[j] > maxi[i] insert cand[j] at the ith
    // position in the maxi array and remove the minimum

1231
Chapter 165. K maximum sums of overlapping contiguous sub-arrays

    // element of the maxi array i.e. the last element


    // and increase j by 1 i.e. take the next element
    // from cand.
    int k = maxi.size();
    int j = 0;
    for (int i = 0; i < k; i++) {
        if (cand[j] > maxi[i]) {
            maxi.insert(maxi.begin() + i, cand[j]);
            maxi.erase(maxi.begin() + k);
            j += 1;
        }
    }
}
  
// Insert prefix_sum[i] to mini array if needed
void insertMini(vector<int>& mini, int pre_sum)
{
    // Traverse the mini array from left to right.
    // If prefix_sum[i] is less than any element
    // then insert prefix_sum[i] at that position
    // and delete maximum element of the mini array
    // i.e. the rightmost element from the array.
    int k = mini.size();
    for (int i = 0; i < k; i++) {
        if (pre_sum < mini[i]) {
            mini.insert(mini.begin() + i, pre_sum);
            mini.erase(mini.begin() + k);
            break;
        }
    }
}
  
// Function to compute k maximum overlapping sub-
// array sums
void kMaxOvSubArray(vector<int> arr, int k)
{
    int n = arr.size();
  
    // Compute the prefix sum of the input array.
    vector<int> pre_sum = prefix_sum(arr, n);
  
    // Set all the elements of mini as +infinite
    // except 0th. Set the 0th element as 0.
    vector<int> mini(k, numeric_limits<int>::max());
    mini[0] = 0;
  
    // Set all the elements of maxi as -infinite.
    vector<int> maxi(k, numeric_limits<int>::min());

1232
Chapter 165. K maximum sums of overlapping contiguous sub-arrays

  
    // Initialize cand array.
    vector<int> cand(k);
  
    // For each element of the prefix_sum array do:
    // compute the cand array.
    // take k maximum values from maxi and cand
    // using maxmerge function.
    // insert prefix_sum[i] to mini array if needed
    // using insertMini function.
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < k; j++) {
             if(pre_sum[i] < 0 && mini[j]==numeric_limits<int>::max())
           cand[j]=(-pre_sum[i])-mini[j];
         else cand[j] = pre_sum[i] - mini[j];
        }
        maxMerge(maxi, cand);
        insertMini(mini, pre_sum[i]);
    }
  
    // Elements of maxi array is the k
    // maximum overlapping sub-array sums.
    // Print out the elements of maxi array.
    for (int ele : maxi)
        cout << ele << " ";
    cout << endl;
}
  
// Driver Program
int main()
{
    // Test case 1
    vector<int> arr1 = { 4, -8, 9, -4, 1, -8, -1, 6 };
    int k1 = 4;
    kMaxOvSubArray(arr1, k1);
  
    // Test case 2
    vector<int> arr2 = { -2, -3, 4, -1, -2, 1, 5, -3 };
    int k2 = 3;
    kMaxOvSubArray(arr2, k2);
    return 0;
}

Python3

# Python program to find out k maximum sum of


# overlapping sub-arrays
  

1233
Chapter 165. K maximum sums of overlapping contiguous sub-arrays

# Function to compute prefix-sum of the input array


def prefix_sum(arr, n):
    pre_sum = list()
    pre_sum.append(arr[0])
    for i in range(1, n):
        pre_sum.append(pre_sum[i-1] + arr[i])
    return pre_sum
  
# Update maxi by k maximum values from maxi and cand
def maxMerge(maxi, cand):
  
    # Here cand and maxi arrays are in non-increasing
    # order beforehand. Now, j is the index of the
    # next cand element and i is the index of next
    # maxi element. Traverse through maxi array.
    # If cand[j] > maxi[i] insert cand[j] at the ith
    # position in the maxi array and remove the minimum
    # element of the maxi array i.e. the last element
    # and increase j by 1 i.e. take the next element
    # from cand.
    k = len(maxi)
    j = 0
    for i in range(k):
        if (cand[j] > maxi[i]):
            maxi.insert(i, cand[j])
            del maxi[-1]
            j += 1
  
# Insert prefix_sum[i] to mini array if needed
def insertMini(mini, pre_sum):
  
    # Traverse the mini array from left to right.
    # If prefix_sum[i] is less than any element
    # then insert prefix_sum[i] at that position
    # and delete maximum element of the mini array
    # i.e. the rightmost element from the array.
    k = len(mini)
    for i in range(k):
        if (pre_sum < mini[i]):
            mini.insert(i, pre_sum)
            del mini[-1]
            break
  
# Function to compute k maximum overlapping sub-array sums
def kMaxOvSubArray(arr, k):
    n = len(arr)
  
    # Compute the prefix sum of the input array.

1234
Chapter 165. K maximum sums of overlapping contiguous sub-arrays

    pre_sum = prefix_sum(arr, n)
  
    # Set all the elements of mini as + infinite
    # except 0th. Set the 0th element as 0.
    mini = [float('inf') for i in range(k)]
    mini[0] = 0
  
    # Set all the elements of maxi as -infinite.
    maxi = [-float('inf') for i in range(k)]
  
    # Initialize cand array.
    cand = [0 for i in range(k)]
  
    # For each element of the prefix_sum array do:
    # compute the cand array.
    # take k maximum values from maxi and cand
    # using maxmerge function.
    # insert prefix_sum[i] to mini array if needed
    # using insertMini function.
    for i in range(n):
        for j in range(k):
            cand[j] = pre_sum[i] - mini[j]
        maxMerge(maxi, cand)
        insertMini(mini, pre_sum[i])
  
    # Elements of maxi array is the k
    # maximum overlapping sub-array sums.
    # Print out the elements of maxi array.
    for ele in maxi:
        print(ele, end = ' ')
    print('')
  
# Driver Program
# Test case 1
arr1 = [4, -8, 9, -4, 1, -8, -1, 6]
k1 = 4
kMaxOvSubArray(arr1, k1)
  
# Test case 2
arr2 = [-2, -3, 4, -1, -2, 1, 5, -3]
k2 = 3
kMaxOvSubArray(arr2, k2)

Output:

9 6 6 5
7 6 5

1235
Chapter 165. K maximum sums of overlapping contiguous sub-arrays

Time Complexity: The ‘insertMini’ and ‘maxMerge’ functions runs in O(k) time and it
takes O(k) time to update the ‘cand’ array. We do this process for n times. Hence, the
overall time complexity is O(k*n).
Improved By : getLost

Source

https://www.geeksforgeeks.org/k-maximum-sum-overlapping-contiguous-sub-arrays/

1236
Chapter 166

LCS (Longest Common


Subsequence) of three strings

LCS (Longest Common Subsequence) of three strings - GeeksforGeeks


Given 3 strings of all having length < 100,the task is to find the longest common sub-
sequence in all three given sequences.
Examples:

Input : str1 = "geeks"


str2 = "geeksfor"
str3 = "geeksforgeeks"
Output : 5
Longest common subsequence is "geeks"
i.e., length = 5

Input : str1 = "abcd1e2"


str2 = "bc12ea"
str3 = "bd1ea"
Output : 3
Longest common subsequence is "b1e"
i.e. length = 3.

This problem is simply an extension of LCS


Let the input sequences be X[0..m-1], Y[0..n-1] and Z[0..o-1] of lengths m, n and o respec-
tively. And let L(X[0..m-1], Y[0..n-1], Z[0..o-1]) be the lengths of LCS of the three sequences
X, Y and Z. Following is the implementation:

The idea is to take a 3D array to store the

1237
Chapter 166. LCS (Longest Common Subsequence) of three strings

length of common subsequence in all 3 given


sequences i. e., L[m + 1][n + 1][o + 1]

1- If any of the string is empty then there


is no common subsequence at all then
L[i][j][k] = 0

2- If the characters of all sequences match


(or X[i] == Y[j] ==Z[k]) then
L[i][j][k] = 1 + L[i-1][j-1][k-1]

3- If the characters of both sequences do


not match (or X[i] != Y[j] || X[i] != Z[k]
|| Y[j] !=Z[k]) then
L[i][j][k] = max(L[i-1][j][k],
L[i][j-1][k],
L[i][j][k-1])

Below is implementation of above idea.


C++

// C++ program to find LCS of three strings


#include<bits/stdc++.h>
using namespace std;
  
/* Returns length of LCS for X[0..m-1], Y[0..n-1]
   and Z[0..o-1] */
int lcsOf3( string X, string Y, string Z, int m,
                               int n, int o)
{
    int L[m+1][n+1][o+1];
  
    /* Following steps build L[m+1][n+1][o+1] in
       bottom up fashion. Note that L[i][j][k]
       contains length of LCS of X[0..i-1] and
       Y[0..j-1]  and Z[0.....k-1]*/
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {
            for (int k=0; k<=o; k++)
            {
                if (i == 0 || j == 0||k==0)
                    L[i][j][k] = 0;
  
                else if (X[i-1] == Y[j-1] && X[i-1]==Z[k-1])
                    L[i][j][k] = L[i-1][j-1][k-1] + 1;

1238
Chapter 166. LCS (Longest Common Subsequence) of three strings

  
                else
                    L[i][j][k] = max(max(L[i-1][j][k],
                                         L[i][j-1][k]),
                                     L[i][j][k-1]);
            }
        }
    }
  
    /* L[m][n][o] contains length of LCS for
      X[0..n-1] and Y[0..m-1] and Z[0..o-1]*/
    return L[m][n][o];
}
  
/* Driver program to test above function */
int main()
{
    string X = "AGGT12";
    string Y = "12TXAYB";
    string Z = "12XBA";
  
    int m = X.length();
    int n = Y.length();
    int o = Z.length();
  
    cout << "Length of LCS is " << lcsOf3(X, Y,
                                    Z, m, n, o);
  
    return 0;
}

Java

// Java program to find LCS of three strings


public class LCS_3Strings {
       
    /* Returns length of LCS for X[0..m-1], Y[0..n-1]
       and Z[0..o-1] */
    static int lcsOf3(String X, String Y, String Z, int m,
                                   int n, int o)
    {
        int[][][] L = new int[m+1][n+1][o+1];
       
        /* Following steps build L[m+1][n+1][o+1] in
           bottom up fashion. Note that L[i][j][k]
           contains length of LCS of X[0..i-1] and
           Y[0..j-1]  and Z[0.....k-1]*/
        for (int i=0; i<=m; i++)

1239
Chapter 166. LCS (Longest Common Subsequence) of three strings

        {
            for (int j=0; j<=n; j++)
            {
                for (int k=0; k<=o; k++)
                {
                    if (i == 0 || j == 0||k==0)
                        L[i][j][k] = 0;
       
                    else if (X.charAt(i - 1) == Y.charAt(j - 1) 
                                && X.charAt(i - 1)==Z.charAt(k - 1))
                        L[i][j][k] = L[i-1][j-1][k-1] + 1;
       
                    else
                        L[i][j][k] = Math.max(Math.max(L[i-1][j][k],
                                             L[i][j-1][k]),
                                         L[i][j][k-1]);
                }
            }
        }
       
        /* L[m][n][o] contains length of LCS for
          X[0..n-1] and Y[0..m-1] and Z[0..o-1]*/
        return L[m][n][o];
    }
       
    /* Driver program to test above function */
    public static void main(String args[])
    {
        String X = "AGGT12";
        String Y = "12TXAYB";
        String Z = "12XBA";
       
        int m = X.length();
        int n = Y.length();
        int o = Z.length();
       
        System.out.println("Length of LCS is " +
                                lcsOf3(X, Y,Z, m, n, o));
       
    }
}
// This code is contributed by Sumit Ghosh

Python3

# Python program to find


# LCS of three strings
  

1240
Chapter 166. LCS (Longest Common Subsequence) of three strings

# Returns length of LCS


# for X[0..m-1], Y[0..n-1]
# and Z[0..o-1]
def lcsOf3(X, Y, Z, m, n, o):
      
    L = [[[0 for i in range(o+1)] for j in range(n+1)]
         for k in range(m+1)]
  
    ''' Following steps build L[m+1][n+1][o+1] in
    bottom up fashion. Note that L[i][j][k]
    contains length of LCS of X[0..i-1] and
    Y[0..j-1] and Z[0.....k-1] '''
    for i in range(m+1):
        for j in range(n+1):
            for k in range(o+1):
                if (i == 0 or j == 0 or k == 0):
                    L[i][j][k] = 0
                      
                elif (X[i-1] == Y[j-1] and
                      X[i-1] == Z[k-1]):
                    L[i][j][k] = L[i-1][j-1][k-1] + 1
  
                else:
                    L[i][j][k] = max(max(L[i-1][j][k],
                    L[i][j-1][k]),
                                    L[i][j][k-1])
  
    # L[m][n][o] contains length of LCS for
    # X[0..n-1] and Y[0..m-1] and Z[0..o-1]
    return L[m][n][o]
  
# Driver program to test above function
  
X = 'AGGT12'
Y = '12TXAYB'
Z = '12XBA'
  
m = len(X)
n = len(Y)
o = len(Z)
  
print('Length of LCS is', lcsOf3(X, Y, Z, m, n, o))
  
# This code is contributed by Soumen Ghosh.                    

C#

// C# program to find 

1241
Chapter 166. LCS (Longest Common Subsequence) of three strings

// LCS of three strings


using System;
  
class GFG 
{
      
    /* Returns length of LCS 
    for X[0..m-1], Y[0..n-1]
    and Z[0..o-1] */
    static int lcsOf3(String X, String Y, 
                      String Z, int m,
                      int n, int o)
    {
        int [,,]L = new int[m + 1, 
                            n + 1, o + 1];
      
        /* Following steps build 
        L[m+1][n+1][o+1] in bottom 
        up fashion. Note that 
        L[i][j][k] contains length 
        of LCS of X[0..i-1] and
        Y[0..j-1] and Z[0.....k-1]*/
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                for (int k = 0; k <= o; k++)
                {
                    if (i == 0 || 
                        j == 0 || k == 0)
                        L[i, j, k] = 0;
      
                    else if (X[i - 1] == Y[j - 1] && 
                             X[i - 1] == Z[k - 1])
                        L[i, j, k] = L[i - 1, 
                                       j - 1,
                                       k - 1] + 1;
      
                    else
                        L[i, j, k] = Math.Max(Math.Max(L[i - 1, j, k], 
                                                       L[i, j - 1, k]),
                                                       L[i, j, k - 1]);
                }
            }
        }
      
        /* L[m][n][o] contains length 
        of LCS for X[0..n-1] and

1242
Chapter 166. LCS (Longest Common Subsequence) of three strings

        Y[0..m-1] and Z[0..o-1]*/


        return L[m, n, o];
    }
      
    // Driver Code
    public static void Main()
    {
        string X = "AGGT12";
        string Y = "12TXAYB";
        string Z = "12XBA";
      
        int m = X.Length;
        int n = Y.Length;
        int o = Z.Length;
      
        Console.Write("Length of LCS is " + 
                       lcsOf3(X, Y, Z, m, n, o));
    }
}
  
// This code is contributed 
// by shiv_bhakt.

PHP

<?php 
// PHP program to find 
// LCS of three strings
  
/* Returns length of LCS for
X[0..m-1], Y[0..n-1] and Z[0..o-1] */
function lcsOf3($X, $Y, $Z, 
                $m, $n, $o)
{
    $L[$m + 1][$n + 1][$o + 1] = array(array(array()));
  
    /* Following steps build 
    L[m+1][n+1][o+1] in bottom 
    up fashion. Note that 
    L[i][j][k] contains length
    of LCS of X[0..i-1] and
    Y[0..j-1] and Z[0.....k-1]*/
    for ($i = 0; $i <= $m; $i++)
    {
        for ($j = 0; $j <= $n; $j++)
        {
            for ($k = 0; $k <= $o; $k++)
            {

1243
Chapter 166. LCS (Longest Common Subsequence) of three strings

                if ($i == 0 || $j == 0||$k == 0)


                    $L[$i][$j][$k] = 0;
  
                else if ($X[$i - 1] == $Y[$j - 1] && 
                         $X[$i - 1] == $Z[$k - 1])
                    $L[$i][$j][$k] = $L[$i - 1][$j - 1][$k - 1] + 1;
  
                else
                    $L[$i][$j][$k] = max(max($L[$i - 1][$j][$k],
                                              $L[$i][$j - 1][$k]),
                                             $L[$i][$j][$k - 1]);
            }
        }
    }
  
    /* L[m][n][o] contains length 
    of LCS for X[0..n-1] and 
    Y[0..m-1] and Z[0..o-1]*/
    return $L[$m][$n][$o];
}
  
// Driver code
$X = "AGGT12";
$Y = "12TXAYB";
$Z = "12XBA";
  
$m = strlen($X);
$n = strlen($Y);
$o = strlen($Z);
  
echo "Length of LCS is " . 
      lcsOf3($X, $Y, $Z, 
             $m, $n, $o);
  
// This code is contributed
// by ChitraNayal
?>

Output:

Length of LCS is 2

Improved By : shiv_bhakt, ChitraNayal

Source
https://www.geeksforgeeks.org/lcs-longest-common-subsequence-three-strings/

1244
Chapter 167

LCS formed by consecutive


segments of at least length K

LCS formed by consecutive segments of at least length K - GeeksforGeeks


Given two strings s1, s2 and K, find the length of the longest subsequence formed by con-
secutive segments of at least length K.
Examples:

Input : s1 = aggayxysdfa
s2 = aggajxaaasdfa
k = 4
Output : 8
Explanation: aggasdfa is the longest
subsequence that can be formed by taking
consecutive segments, minimum of length 4.
Here segments are "agga" and "sdfa" which
are of length 4 which is included in making
the longest subsequence.

Input : s1 = aggasdfa
s2 = aggajasdfaxy
k = 5
Output : 5

Input: s1 = "aabcaaaa"
s2 = "baaabcd"
k = 3
Output: 4
Explanation: "aabc" is the longest subsequence that
is formed by taking segment of minimum length 3.

1245
Chapter 167. LCS formed by consecutive segments of at least length K

The segment is of length 4.

Prerequisite : Longest Common Subsequence


Create a LCS[][] array where LCSi, j denotes the length of the longest common subsequence
formed by characters of s1 till i and s2 till j having consecutive segments of at least length
K. Create a cnt[][] array to count the length of the common segment. cnti, j = cnti-1, j-1 +1
when s1[i-1]==s2[j-1]. If characters are not equal then segments are not equal hence mark
cnti, j as 0.
When cnti, j >=k, then update the lcs value by adding the value of cnti-a, j-a where a
is the length of the segments a<=cnti, j . The answer for the longest subsequence with
consecutive segments of at least length k will be stored in lcs[n][m] where n and m are the
length of string1 and string2.

C++

// CPP program to find the Length of Longest 


// subsequence formed by consecutive segments
// of at least length K
#include <bits/stdc++.h>
using namespace std;
  
// Returns the length of the longest common subsequence
// with a minimum of length of K consecutive segments
int longestSubsequenceCommonSegment(int k, string s1, 
                                           string s2)
{
    // length of strings
    int n = s1.length();
    int m = s2.length();
  
    // declare the lcs and cnt array
    int lcs[n + 1][m + 1];
    int cnt[n + 1][m + 1];
  
    // initialize the lcs and cnt array to 0
    memset(lcs, 0, sizeof(lcs));
    memset(cnt, 0, sizeof(cnt));
  
    // iterate from i=1 to n and j=1 to j=m
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
  
            // stores the maximum of lcs[i-1][j] and lcs[i][j-1]
            lcs[i][j] = max(lcs[i - 1][j], lcs[i][j - 1]);
  
            // when both the characters are equal
            // of s1 and s2

1246
Chapter 167. LCS formed by consecutive segments of at least length K

            if (s1[i - 1] == s2[j - 1])


                cnt[i][j] = cnt[i - 1][j - 1] + 1; 
  
            // when length of common segment is
            // more than k, then update lcs answer 
            // by adding that segment to the answer
            if (cnt[i][j] >= k) {
  
                // formulate for all length of segments
                // to get the longest subsequence with 
                // consecutive Common Segment of length 
                // of min k length
                for (int a = k; a <= cnt[i][j]; a++) 
  
                    // update lcs value by adding segment length
                    lcs[i][j] = max(lcs[i][j], 
                                    lcs[i - a][j - a] + a);
                  
            }
        }
    }
  
    return lcs[n][m];
}
  
// driver code to check the above fucntion
int main()
{
    int k = 4;
    string s1 = "aggasdfa";
    string s2 = "aggajasdfa";
    cout << longestSubsequenceCommonSegment(k, s1, s2);
    return 0;
}

Java

// Java program to find the Length of Longest 


// subsequence formed by consecutive segments
// of at least length K
  
class GFG {
  
    // Returns the length of the longest common subsequence
    // with a minimum of length of K consecutive segments
    static int longestSubsequenceCommonSegment(int k, String s1, 
                                               String s2)
    {

1247
Chapter 167. LCS formed by consecutive segments of at least length K

        // length of strings


        int n = s1.length();
        int m = s2.length();
      
        // declare the lcs and cnt array
        int lcs[][] = new int[n + 1][m + 1];
        int cnt[][] = new int[n + 1][m + 1];
      
      
        // iterate from i=1 to n and j=1 to j=m
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
      
                // stores the maximum of lcs[i-1][j] and lcs[i][j-1]
                lcs[i][j] = Math.max(lcs[i - 1][j], lcs[i][j - 1]);
      
                // when both the characters are equal
                // of s1 and s2
                if (s1.charAt(i - 1) == s2.charAt(j - 1))
                    cnt[i][j] = cnt[i - 1][j - 1] + 1; 
      
                // when length of common segment is
                // more than k, then update lcs answer 
                // by adding that segment to the answer
                if (cnt[i][j] >= k) 
                {
      
                    // formulate for all length of segments
                    // to get the longest subsequence with 
                    // consecutive Common Segment of length 
                    // of min k length
                    for (int a = k; a <= cnt[i][j]; a++) 
      
                        // update lcs value by adding 
                        // segment length
                        lcs[i][j] = Math.max(lcs[i][j], 
                                        lcs[i - a][j - a] + a);
                      
                }
            }
        }
      
        return lcs[n][m];
    }
      
    // driver code to check the above fucntion
    public static void main(String[] args)
    {

1248
Chapter 167. LCS formed by consecutive segments of at least length K

        int k = 4;
        String s1 = "aggasdfa";
        String s2 = "aggajasdfa";
        System.out.println(longestSubsequenceCommonSegment(k, s1, s2));
    }
}
  
// This code is contributed by prerna saini.

C#

// C# program to find the Length of Longest 


// subsequence formed by consecutive segments
// of at least length K
using System;
  
class GFG {
  
    // Returns the length of the longest common subsequence
    // with a minimum of length of K consecutive segments
    static int longestSubsequenceCommonSegment(int k, string s1, 
                                            string s2)
    {
        // length of strings
        int n = s1.Length;
        int m = s2.Length;
      
        // declare the lcs and cnt array
        int [,]lcs = new int[n + 1,m + 1];
        int [,]cnt = new int[n + 1,m + 1];
      
      
        // iterate from i=1 to n and j=1 to j=m
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
      
                // stores the maximum of lcs[i-1][j] and lcs[i][j-1]
                lcs[i,j] = Math.Max(lcs[i - 1,j], lcs[i,j - 1]);
      
                // when both the characters are equal
                // of s1 and s2
                if (s1[i - 1] == s2[j - 1])
                    cnt[i,j] = cnt[i - 1,j - 1] + 1; 
      
                // when length of common segment is
                // more than k, then update lcs answer 
                // by adding that segment to the answer
                if (cnt[i,j] >= k) 

1249
Chapter 167. LCS formed by consecutive segments of at least length K

                {
      
                    // formulate for all length of segments
                    // to get the longest subsequence with 
                    // consecutive Common Segment of length 
                    // of min k length
                    for (int a = k; a <= cnt[i,j]; a++) 
      
                        // update lcs value by adding 
                        // segment length
                        lcs[i,j] = Math.Max(lcs[i,j], 
                                        lcs[i - a,j - a] + a);
                      
                }
            }
        }
      
        return lcs[n,m];
    }
      
    // driver code to check the above fucntion
    public static void Main()
    {
        int k = 4;
        string s1 = "aggasdfa";
        string s2 = "aggajasdfa";
    Console.WriteLine(longestSubsequenceCommonSegment(k, s1, s2));
    }
}
  
// This code is contributed by vt_m.

Output:

Source

https://www.geeksforgeeks.org/lcs-formed-consecutive-segments-least-length-k/

1250
Chapter 168

Largest Sum Contiguous


Subarray

Largest Sum Contiguous Subarray - GeeksforGeeks


Write an efficient program to find the sum of contiguous subarray within a one-dimensional
array of numbers which has the largest sum.

Kadane’s Algorithm:

1251
Chapter 168. Largest Sum Contiguous Subarray

Initialize:
max_so_far = 0
max_ending_here = 0

Loop for each element of the array


(a) max_ending_here = max_ending_here + a[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far

Explanation:
Simple idea of the Kadane’s algorithm is to look for all positive contiguous segments of the
array (max_ending_here is used for this). And keep track of maximum sum contiguous
segment among all positive segments (max_so_far is used for this). Each time we get a
positive sum compare it with max_so_far and update max_so_far if it is greater than
max_so_far

Lets take the example:


{-2, -3, 4, -1, -2, 1, 5, -3}

max_so_far = max_ending_here = 0

for i=0, a[0] = -2


max_ending_here = max_ending_here + (-2)
Set max_ending_here = 0 because max_ending_here < 0

for i=1, a[1] = -3


max_ending_here = max_ending_here + (-3)
Set max_ending_here = 0 because max_ending_here < 0

for i=2, a[2] = 4


max_ending_here = max_ending_here + (4)
max_ending_here = 4
max_so_far is updated to 4 because max_ending_here greater
than max_so_far which was 0 till now

for i=3, a[3] = -1


max_ending_here = max_ending_here + (-1)
max_ending_here = 3

for i=4, a[4] = -2


max_ending_here = max_ending_here + (-2)
max_ending_here = 1

for i=5, a[5] = 1

1252
Chapter 168. Largest Sum Contiguous Subarray

max_ending_here = max_ending_here + (1)


max_ending_here = 2

for i=6, a[6] = 5


max_ending_here = max_ending_here + (5)
max_ending_here = 7
max_so_far is updated to 7 because max_ending_here is
greater than max_so_far

for i=7, a[7] = -3


max_ending_here = max_ending_here + (-3)
max_ending_here = 4

Program:

C++

// C++ program to print largest contiguous array sum


#include<iostream>
#include<climits>
using namespace std;
  
int maxSubArraySum(int a[], int size)
{
    int max_so_far = INT_MIN, max_ending_here = 0;
  
    for (int i = 0; i < size; i++)
    {
        max_ending_here = max_ending_here + a[i];
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
  
        if (max_ending_here < 0)
            max_ending_here = 0;
    }
    return max_so_far;
}
  
/*Driver program to test maxSubArraySum*/
int main()
{
    int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
    int n = sizeof(a)/sizeof(a[0]);
    int max_sum = maxSubArraySum(a, n);
    cout << "Maximum contiguous sum is " << max_sum;
    return 0;
}

1253
Chapter 168. Largest Sum Contiguous Subarray

Java

import java.io.*;
// Java program to print largest contiguous array sum
import java.util.*;
  
class Kadane
{
    public static void main (String[] args)
    {
        int [] a = {-2, -3, 4, -1, -2, 1, 5, -3};
        System.out.println("Maximum contiguous sum is " +
                                       maxSubArraySum(a));
    }
  
    static int maxSubArraySum(int a[])
    {
        int size = a.length;
        int max_so_far = Integer.MIN_VALUE, max_ending_here = 0;
  
        for (int i = 0; i < size; i++)
        {
            max_ending_here = max_ending_here + a[i];
            if (max_so_far < max_ending_here)
                max_so_far = max_ending_here;
            if (max_ending_here < 0)
                max_ending_here = 0;
        }
        return max_so_far;
    }
}

Python

# Python program to find maximum contiguous subarray


   
# Function to find the maximum contiguous subarray
from sys import maxint
def maxSubArraySum(a,size):
       
    max_so_far = -maxint - 1
    max_ending_here = 0
       
    for i in range(0, size):
        max_ending_here = max_ending_here + a[i]
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here

1254
Chapter 168. Largest Sum Contiguous Subarray

  
        if max_ending_here < 0:
            max_ending_here = 0   
    return max_so_far
   
# Driver function to check the above function 
a = [-13, -3, -25, -20, -3, -16, -23, -12, -5, -22, -15, -4, -7]
print "Maximum contiguous sum is", maxSubArraySum(a,len(a))
   
#This code is contributed by _Devesh Agrawal_

C#

// C# program to print largest 


// contiguous array sum
using System;
  
class GFG
{
    static int maxSubArraySum(int []a)
    {
        int size = a.Length;
        int max_so_far = int.MinValue, 
            max_ending_here = 0;
  
        for (int i = 0; i < size; i++)
        {
            max_ending_here = max_ending_here + a[i];
              
            if (max_so_far < max_ending_here)
                max_so_far = max_ending_here;
              
            if (max_ending_here < 0)
                max_ending_here = 0;
        }
          
        return max_so_far;
    }
      
    // Drive code 
    public static void Main ()
    {
        int [] a = {-2, -3, 4, -1, -2, 1, 5, -3};
        Console.Write("Maximum contiguous sum is " +
                                maxSubArraySum(a));
    }
  
}

1255
Chapter 168. Largest Sum Contiguous Subarray

  
// This code is contributed by Sam007_

PHP

<?php
// PHP program to print largest
// contiguous array sum
  
function maxSubArraySum($a, $size)
{
    $max_so_far = PHP_INT_MIN; 
    $max_ending_here = 0;
  
    for ($i = 0; $i < $size; $i++)
    {
        $max_ending_here = $max_ending_here + $a[$i];
        if ($max_so_far < $max_ending_here)
            $max_so_far = $max_ending_here;
  
        if ($max_ending_here < 0)
            $max_ending_here = 0;
    }
    return $max_so_far;
}
  
// Driver code
$a = array(-2, -3, 4, -1,
           -2, 1, 5, -3);
$n = count($a);
$max_sum = maxSubArraySum($a, $n);
echo "Maximum contiguous sum is " , 
                          $max_sum;
  
// This code is contributed by anuj_67.
?>

Output:

Maximum contiguous sum is 7

Above program can be optimized further, if we compare max_so_far with max_ending_here


only if max_ending_here is greater than 0.

C++

1256
Chapter 168. Largest Sum Contiguous Subarray

int maxSubArraySum(int a[], int size)


{
   int max_so_far = 0, max_ending_here = 0;
   for (int i = 0; i < size; i++)
   {
       max_ending_here = max_ending_here + a[i];
       if (max_ending_here < 0)
           max_ending_here = 0;
  
       /* Do not compare for all elements. Compare only   
          when  max_ending_here > 0 */
       else if (max_so_far < max_ending_here)
           max_so_far = max_ending_here;
   }
   return max_so_far;
}

Python

def maxSubArraySum(a,size):
      
    max_so_far = 0
    max_ending_here = 0
      
    for i in range(0, size):
        max_ending_here = max_ending_here + a[i]
        if max_ending_here < 0:
            max_ending_here = 0
          
        # Do not compare for all elements. Compare only   
        # when  max_ending_here > 0
        elif (max_so_far < max_ending_here):
            max_so_far = max_ending_here
              
    return max_so_far

Time Complexity: O(n)


Algorithmic Paradigm: Dynamic Programming
Following is another simple implementation suggested by Mohit Kumar. The implemen-
tation handles the case when all numbers in array are negative.

C++

#include<iostream>
using namespace std;
  

1257
Chapter 168. Largest Sum Contiguous Subarray

int maxSubArraySum(int a[], int size)


{
   int max_so_far = a[0];
   int curr_max = a[0];
  
   for (int i = 1; i < size; i++)
   {
        curr_max = max(a[i], curr_max+a[i]);
        max_so_far = max(max_so_far, curr_max);
   }
   return max_so_far;
}
  
/* Driver program to test maxSubArraySum */
int main()
{
   int a[] =  {-2, -3, 4, -1, -2, 1, 5, -3};
   int n = sizeof(a)/sizeof(a[0]);
   int max_sum = maxSubArraySum(a, n);
   cout << "Maximum contiguous sum is " << max_sum;
   return 0;
}

Java

// Java program to print largest contiguous


// array sum
import java.io.*;
  
class GFG {
  
    static int maxSubArraySum(int a[], int size)
    {
    int max_so_far = a[0];
    int curr_max = a[0];
  
    for (int i = 1; i < size; i++)
    {
           curr_max = Math.max(a[i], curr_max+a[i]);
        max_so_far = Math.max(max_so_far, curr_max);
    }
    return max_so_far;
    }
  
    /* Driver program to test maxSubArraySum */
    public static void main(String[] args)
    {
    int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};

1258
Chapter 168. Largest Sum Contiguous Subarray

    int n = a.length;   
    int max_sum = maxSubArraySum(a, n);
    System.out.println("Maximum contiguous sum is " 
                       + max_sum);
    }
}
  
// This code is contributd by Prerna Saini

Python

# Python program to find maximum contiguous subarray


  
def maxSubArraySum(a,size):
      
    max_so_far =a[0]
    curr_max = a[0]
      
    for i in range(1,size):
        curr_max = max(a[i], curr_max + a[i])
        max_so_far = max(max_so_far,curr_max)
          
    return max_so_far
  
# Driver function to check the above function 
a = [-2, -3, 4, -1, -2, 1, 5, -3]
print"Maximum contiguous sum is" , maxSubArraySum(a,len(a))
  
#This code is contributed by _Devesh Agrawal_

C#

// C# program to print largest 


// contiguous array sum
using System;
  
class GFG
{
    static int maxSubArraySum(int []a, int size)
    {
    int max_so_far = a[0];
    int curr_max = a[0];
  
    for (int i = 1; i < size; i++)
    {
        curr_max = Math.Max(a[i], curr_max+a[i]);
        max_so_far = Math.Max(max_so_far, curr_max);

1259
Chapter 168. Largest Sum Contiguous Subarray

    }
  
    return max_so_far;
    }
  
    // Drive code 
    public static void Main ()
    {
        int []a = {-2, -3, 4, -1, -2, 1, 5, -3};
        int n = a.Length; 
        Console.Write("Maximum contiguous sum is "
                           + maxSubArraySum(a, n));
    }
  
}
  
// This code is contributed by Sam007_

Output:

Maximum contiguous sum is 7

To print the subarray with the maximum sum, we maintain indices whenever we get the
maximum sum.

C++

// C++ program to print largest contiguous array sum


#include<iostream>
#include<climits>
using namespace std;
  
int maxSubArraySum(int a[], int size)
{
    int max_so_far = INT_MIN, max_ending_here = 0,
       start =0, end = 0, s=0;
  
    for (int i=0; i< size; i++ )
    {
        max_ending_here += a[i];
  
        if (max_so_far < max_ending_here)
        {
            max_so_far = max_ending_here;
            start = s;
            end = i;
        }

1260
Chapter 168. Largest Sum Contiguous Subarray

  
        if (max_ending_here < 0)
        {
            max_ending_here = 0;
            s = i + 1;
        }
    }
    cout << "Maximum contiguous sum is "
        << max_so_far << endl;
    cout << "Starting index "<< start
        << endl << "Ending index "<< end << endl;
}
  
/*Driver program to test maxSubArraySum*/
int main()
{
    int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
    int n = sizeof(a)/sizeof(a[0]);
    int max_sum = maxSubArraySum(a, n);
    return 0;
}

Java

// Java program to print largest 


// contiguous array sum
class GFG {
  
    static void maxSubArraySum(int a[], int size)
    {
        int max_so_far = Integer.MIN_VALUE,
        max_ending_here = 0,start = 0,
        end = 0, s = 0;
  
        for (int i = 0; i < size; i++) 
        {
            max_ending_here += a[i];
  
            if (max_so_far < max_ending_here) 
            {
                max_so_far = max_ending_here;
                start = s;
                end = i;
            }
  
            if (max_ending_here < 0) 
            {
                max_ending_here = 0;

1261
Chapter 168. Largest Sum Contiguous Subarray

                s = i + 1;
            }
        }
        System.out.println("Maximum contiguous sum is " 
                           + max_so_far);
        System.out.println("Starting index " + start);
        System.out.println("Ending index " + end);
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int a[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = a.length;
        maxSubArraySum(a, n);
    }
}
  
// This code is contributed by  prerna saini

Python3

# Python program to print largest contiguous array sum


  
from sys import maxsize
  
# Function to find the maximum contiguous subarray
# and print its starting and end index
def maxSubArraySum(a,size):
  
    max_so_far = -maxsize - 1
    max_ending_here = 0
    start = 0
    end = 0
    s = 0
  
    for i in range(0,size):
  
        max_ending_here += a[i]
  
        if max_so_far < max_ending_here:
            max_so_far = max_ending_here
            start = s
            end = i
  
        if max_ending_here < 0:
            max_ending_here = 0
            s = i+1

1262
Chapter 168. Largest Sum Contiguous Subarray

  
    print ("Maximum contiguous sum is %d"%(max_so_far))
    print ("Starting Index %d"%(start))
    print ("Ending Index %d"%(end))
  
# Driver program to test maxSubArraySum
a = [-2, -3, 4, -1, -2, 1, 5, -3]
maxSubArraySum(a,len(a))

C#

// C# program to print largest 


// contiguous array sum
using System;
  
class GFG 
{
    static void maxSubArraySum(int []a, 
                               int size)
    {
        int max_so_far = int.MinValue,
        max_ending_here = 0, start = 0,
        end = 0, s = 0;
  
        for (int i = 0; i < size; i++) 
        {
            max_ending_here += a[i];
  
            if (max_so_far < max_ending_here) 
            {
                max_so_far = max_ending_here;
                start = s;
                end = i;
            }
  
            if (max_ending_here < 0) 
            {
                max_ending_here = 0;
                s = i + 1;
            }
        }
        Console.WriteLine("Maximum contiguous " + 
                         "sum is " + max_so_far);
        Console.WriteLine("Starting index " + 
                                      start);
        Console.WriteLine("Ending index " + 
                                      end);
    }

1263
Chapter 168. Largest Sum Contiguous Subarray

  
    // Driver code
    public static void Main()
    {
        int []a = {-2, -3, 4, -1, 
                   -2, 1, 5, -3};
        int n = a.Length;
        maxSubArraySum(a, n);
    }
}
  
// This code is contributed
// by anuj_67.

Output:

Maximum contiguous sum is 7


Starting index 2
Ending index 6

Now try below question


Given an array of integers (possibly some of the elements negative), write a C program
to find out the *maximum product* possible by multiplying ‘n’ consecutive integers in
the array where n <= ARRAY_SIZE. Also print the starting point of maximum product
subarray.

References:
http://en.wikipedia.org/wiki/Kadane%27s_Algorithm
Improved By : vt_m

Source

https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/

1264
Chapter 169

Largest area rectangular


sub-matrix with equal number
of 1’s and 0’s

Largest area rectangular sub-matrix with equal number of 1’s and 0’s - GeeksforGeeks
Given a binary matrix. The problem is to find the largest area rectangular sub-matrix with
equal number of 1’s and 0’s.
Examples:

Input : mat[][] = { {0, 0, 1, 1},


{0, 1, 1, 0},
{1, 1, 1, 0},
{1, 0, 0, 1} }
Output : 8 sq. units
(Top, left): (0, 0)
(Bottom, right): (3, 1)

Input : mat[][] = { {0, 0, 1, 1},


{0, 1, 1, 1} }
Output : 6 sq. units

The naive solution for this problem is to check every possible rectangle in given 2D array
by counting the total number of 1’s and 0’s in that rectangle. This solution requires 4 nested
loops and time complexity of this solution would be O(n^4).
An efficient solution is based on Largest rectangular sub-matrix whose sum is 0 which
reduces the time complexity to O(n^3). First of all consider every ‘0’ in the matrix as ‘-1’.
Now, the idea is to reduce the problem to 1-D array. We fix the left and right columns one
by one and find the largest sub-array with 0 sum contiguous rows for every left and right

1265
Chapter 169. Largest area rectangular sub-matrix with equal number of 1’s and 0’s

column pair. We basically find top and bottom row numbers (which have sum zero) for
every fixed left and right column pair. To find the top and bottom row numbers, calculate
sum of elements in every row from left to right and store these sums in an array say temp[].
So temp[i] indicates sum of elements from left to right in row i. If we find largest subarray
with 0 sum in temp[], we can get the index positions of rectangular sub-matrix with sum
equal to 0 (i.e. having equal number of 1’s and 0’s). With this process we can find the
largest area rectangular sub-matrix with sum equal to 0 (i.e. having equal number of 1’s
and 0’s). We can use Hashing technique to find maximum length sub-array with sum equal
to 0 in 1-D array in O(n) time.

// C++ implementation to find largest area rectangular


// submatrix with equal number of 1's and 0's
#include <bits/stdc++.h>
  
using namespace std;
  
#define MAX_ROW 10
#define MAX_COL 10
  
// This function basically finds largest 0
// sum subarray in arr[0..n-1]. If 0 sum
// does't exist, then it returns false. Else
// it returns true and sets starting and
// ending indexes as start and end.
bool subArrWithSumZero(int arr[], int &start, 
                              int &end, int n)
{
    // to store cumulative sum
    int sum[n];
      
    // Initialize all elements of sum[] to 0
    memset(sum, 0, sizeof(sum));
      
    // map to store the indexes of sum
    unordered_map<int, int> um;
      
    // build up the cumulative sum[] array
    sum[0] = arr[0];
    for (int i=1; i<n; i++)
        sum[i] = sum[i-1] + arr[i];
      
    // to store the maximum length subarray
    // with sum equal to 0
    int maxLen = 0;
      
    // traverse to the sum[] array
    for (int i=0; i<n; i++)    
    {

1266
Chapter 169. Largest area rectangular sub-matrix with equal number of 1’s and 0’s

        // if true, then there is a subarray


        // with sum equal to 0 from the
        // beginning up to index 'i'
        if (sum[i] == 0)
        {
            // update the required variables
            start = 0; 
            end = i;
            maxLen = (i+1);
        }
          
        // else if true, then sum[i] has not 
        // seen before in 'um'
        else if (um.find(sum[i]) == um.end())
            um[sum[i]] = i;
          
        // sum[i] has been seen before in the
        // unordered_map 'um'    
        else
        {
            // if previous subarray length is smaller
            // than the current subarray length, then
            // update the required variables
            if (maxLen < (i-um[sum[i]]))
            {
                maxLen = (i-um[sum[i]]);
                start = um[sum[i]] + 1;
                end = i;
            }
        }    
    }    
      
    // if true, then there is no
    // subarray with sum equal to 0
    if (maxLen == 0)
        return false;
          
    // else return true    
    return true;    
}
  
// function to find largest area rectangular
// submatrix with equal number of 1's and 0's
void maxAreaRectWithSumZero(int mat[MAX_ROW][MAX_COL], 
                                    int row, int col)
{
    // to store intermediate values
    int temp[row], startRow, endRow;

1267
Chapter 169. Largest area rectangular sub-matrix with equal number of 1’s and 0’s

      
    // to store the final outputs
    int finalLeft, finalRight, finalTop, finalBottom;
    finalLeft = finalRight = finalTop = finalBottom = -1;
    int maxArea = 0;
      
    // Set the left column    
    for (int left = 0; left < col; left++)
    {
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
          
        // Set the right column for the left column
        // set by outer loop
        for (int right = left; right < col; right++)
        {
            // Calculate sum between current left
            // and right for every row 'i'
            // consider value '1' as '1' and
            // value '0' as '-1'
            for (int i=0; i<row; i++)
                temp[i] += mat[i][right] ? 1 : -1;
                  
            // Find largest subarray with 0 sum in
            // temp[]. The subArrWithSumZero() function 
            // also sets values of finalTop, finalBottom,
            // finalLeft and finalRight if there exists
            // a subarray with sum 0 in temp
            if (subArrWithSumZero(temp, startRow, endRow, row))
            {
                int area = (right - left + 1) * 
                                       (endRow - startRow + 1);
  
                // Compare current 'area' with previous area
                // and accodingly update final values
                if (maxArea < area)
                {
                    finalTop = startRow;
                    finalBottom = endRow;
                    finalLeft = left;
                    finalRight = right;                    
                    maxArea = area;
                }
            }
        }
    }
      
    // if true then there is no rectangular submatrix

1268
Chapter 169. Largest area rectangular sub-matrix with equal number of 1’s and 0’s

    // with equal number of 1's and 0's


    if (maxArea == 0)
        cout << "No such rectangular submatrix exists:";
      
    // displaying the top left and bottom right boundaries
    // with the area of the rectangular submatrix    
    else
    {
        cout << "(Top, Left): " 
             << "(" << finalTop << ", " << finalLeft
             << ")" << endl; 
               
        cout << "(Bottom, Right): " 
             << "(" << finalBottom << ", " << finalRight 
             << ")" << endl;      
          
        cout << "Area: " << maxArea << " sq.units";     
    }
}
  
// Driver program to test above
int main()
{
    int mat[MAX_ROW][MAX_COL] = { {0, 0, 1, 1},
                                    {0, 1, 1, 0},
                                    {1, 1, 1, 0},
                                  {1, 0, 0, 1} };    
    int row = 4, col = 4;
    maxAreaRectWithSumZero(mat, row, col);
    return 0;                      
                        

Output:

(Top, Left): (0, 0)


(Bottom, Right): (3, 1)
Area: 8 sq.units

Time Complexity: O(n3 )


Auxiliary Space: O(n)

Source

https://www.geeksforgeeks.org/largest-area-rectangular-sub-matrix-equal-number-1s-0s/

1269
Chapter 170

Largest divisible pairs subset

Largest divisible pairs subset - GeeksforGeeks


Given an array of n distinct elements, find length of the largest subset such that every pair
in the subset is such that the larger element of the pair is divisible by smaller element.
Examples:

Input : arr[] = {10, 5, 3, 15, 20}


Output : 3
Explanation: The largest subset is 10, 5, 20.
10 is divisible by 5, and 20 is divisible by 10.

Input : arr[] = {18, 1, 3, 6, 13, 17}


Output : 4
Explanation: The largest subset is 18, 1, 3, 6,
In the subsequence, 3 is divisible by 1,
6 by 3 and 18 by 6.

This can be solved using Dynamic Programming. We first sort the array so that the largest
element is at the end. Then we traverse the sorted array from end. For every element
a[i], we compute dp[i] where dp[i] indicates size of largest divisible subset where a[i] is the
smallest element. We can compute dp[i] in a sorted array using values from dp[i+1] to
dp[n-1]. Finally we return maximum value from dp[].
Below is the implementation of the above approach:

C++

// CPP program to find the largest subset which


// where each pair is divisible.
#include <bits/stdc++.h>

1270
Chapter 170. Largest divisible pairs subset

using namespace std;


  
// function to find the longest Subsequence
int largestSubset(int a[], int n)
{
    // Sort array in increasing order
    sort(a, a + n);
  
    // dp[i] is going to store size of largest
    // divisible subset beginning with a[i].
    int dp[n];
  
    // Since last element is largest, d[n-1] is 1
    dp[n - 1] = 1;
  
    // Fill values for smaller elements.
    for (int i = n - 2; i >= 0; i--) {
  
        // Find all multiples of a[i] and consider
        // the multiple that has largest subset 
        // beginning with it.
        int mxm = 0;
        for (int j = i + 1; j < n; j++)
            if (a[j] % a[i] == 0)
                mxm = max(mxm, dp[j]);
  
        dp[i] = 1 + mxm;
    }
  
    // Return maximum value from dp[]
    return *max_element(dp, dp + n);
}
  
// driver code to check the above function
int main()
{
    int a[] = { 1, 3, 6, 13, 17, 18 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << largestSubset(a, n) << endl;
    return 0;
}

Python3
# Python program to find the largest
# subset where each pair is divisible.
# function to find the longest Subsequence
def largestSubset(a, n):

1271
Chapter 170. Largest divisible pairs subset

# Sort array in
# increasing order
a.sort()
# dp[i] is going to store size
# of largest divisible subset
# beginning with a[i].
dp = [0 for i in range(n)]
# Since last element is largest,
# d[n-1] is 1
dp[n – 1] = 1;
# Fill values for smaller elements
for i in range(n – 2, -1, -1):
# Find all multiples of a[i]
# and consider the multiple
# that has largest subset
# beginning with it.
mxm = 0;
for j in range(i + 1, n):
if a[j] % a[i] == 0:
mxm = max(mxm, dp[j])
dp[i] = 1 + mxm
# Return maximum value from dp[]
return max(dp)
# Driver Code
a = [ 1, 3, 6, 13, 17, 18 ]
n = len(a)
print(largestSubset(a, n))
# This code is contributed by
# sahil shelangia
C#

// C# program to find the largest 


// subset which where each pair 
// is divisible.
using System;
using System.Linq;
  
public class GFG {
  
    // function to find the longest Subsequence
    static int largestSubset(int[] a, int n)
    {
        // Sort array in increasing order
        Array.Sort(a);

1272
Chapter 170. Largest divisible pairs subset

  
        // dp[i] is going to store size of largest
        // divisible subset beginning with a[i].
        int[] dp = new int[n];
  
        // Since last element is largest, d[n-1] is 1
        dp[n - 1] = 1;
  
        // Fill values for smaller elements.
        for (int i = n - 2; i >= 0; i--) {
  
            // Find all multiples of a[i] and consider
            // the multiple that has largest subset
            // beginning with it.
            int mxm = 0;
            for (int j = i + 1; j < n; j++)
                if (a[j] % a[i] == 0)
                    mxm = Math.Max(mxm, dp[j]);
  
            dp[i] = 1 + mxm;
        }
  
        // Return maximum value from dp[]
        return dp.Max();
    }
  
    // driver code to check the above function
    static public void Main()
    {
        int[] a = { 1, 3, 6, 13, 17, 18 };
        int n = a.Length;
        Console.WriteLine(largestSubset(a, n));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to find the
// largest subset which
// where each pair is
// divisible.
  
// function to find the
// longest Subsequence
function largestSubset($a, $n)

1273
Chapter 170. Largest divisible pairs subset

{
      
    // Sort array in 
    // increasing order
    sort($a);
  
    // dp[i] is going to 
    // store size of largest
    // divisible subset 
    // beginning with a[i].
    $dp = array();
  
    // Since last element is 
    // largest, d[n-1] is 1
    $dp[$n - 1] = 1;
  
    // Fill values for 
    // smaller elements.
    for ($i = $n - 2; $i >= 0; $i--) 
    {
  
        // Find all multiples of
        // a[i] and consider
        // the multiple that 
        // has largest subset 
        // beginning with it.
        $mxm = 0;
        for ($j = $i + 1; $j < $n; $j++)
            if ($a[$j] % $a[$i] == 0)
                $mxm = max($mxm, $dp[$j]);
  
        $dp[$i] = 1 + $mxm;
    }
  
    // Return maximum value
    // from dp[]
    return max($dp);
}
  
    // Driver Code
    $a = array(1, 3, 6, 13, 17, 18);
    $n = count($a);
    echo largestSubset($a, $n);
      
// This code is contributed by anuj_67.
?>

Output:

1274
Chapter 170. Largest divisible pairs subset

Time Complexity: O(n*n)


Exercise: The above solution doesn’t handle duplicates. How to extend this solution to
handle duplicates?
Improved By : vt_m, sahilshelangia

Source

https://www.geeksforgeeks.org/largest-divisible-pairs-subset/

1275
Chapter 171

Largest rectangular sub-matrix


having sum divisible by k

Largest rectangular sub-matrix having sum divisible by k - GeeksforGeeks


Given a n x n matrix of integers. The problem is to find the largest area rectangular
sub-matrix having sum divisible by the given value k.
Examples:

Input : mat[][] = { {1, 2, -1, -4},


{-8, -3, 4, 2},
{3, 8, 10, 1},
{-4, -1, 1, 7} }

k = 5

Output : Area = 12
(Top, Left): (0, 0)
(Bottom, Right): (2, 3)
The sub-matrix is:
| 1, 2, -1, -4 |
| -8, -3, 4, 2 |
| 3, 8, 10, 1 |

Naive Approach: Check every possible rectangle in given 2D array having sum divisible
by ‘k’ and print the largest one. This solution requires 4 nested loops and time complexity
of this solution would be O(n^4).
Efficient Approach: Longest subarray having sum divisible by k for 1-D array can be
used to reduce the time complexity to O(n^3). The idea is to fix the left and right columns
one by one and find the longest sub-array having sum divisible by ‘k’ for contiguous rows

1276
Chapter 171. Largest rectangular sub-matrix having sum divisible by k

for every left and right column pair. We basically find top and bottom row numbers (which
are part of the largest sub-matrix) for every fixed left and right column pair. To find the top
and bottom row numbers, calculate sum of elements in every row from left to right and store
these sums in an array say temp[]. So temp[i] indicates sum of elements from left to right
in row i. Now, apply Longest subarray having sum divisible by k 1D algorithm on temp[],
and get the longest sub-array having sum divisible by ‘k’ of temp[]. This length would be
the maximum possible length with left and right as boundary columns. Set the ‘top’ and
‘bottom’ row indexes for the left right column pair and calculate the area. In similar manner
get the top, bottom, left, right indexes for other sub-matrices having sum divisible by ‘k’
and print the one having maximum area.

// C++ implementation to find largest rectangular


// sub-matrix having sum divisible by k
#include <bits/stdc++.h>
using namespace std;
  
#define SIZE 10
  
// function to find the longest subarray with sum divisible
// by k. The function stores starting and ending indexes of
// the subarray at addresses pointed by start and finish
// pointers respectively.
void longSubarrWthSumDivByK(int arr[], int n, int k,
                            int& start, int& finish)
{
    // unodered map 'um' implemented as
    // hash table
    unordered_map<int, int> um;
  
    // 'mod_arr[i]' stores (sum[0..i] % k)
    int mod_arr[n];
    int curr_sum = 0, max = 0;
  
    // traverse arr[] and build up the
    // array 'mod_arr[]'
    for (int i = 0; i < n; i++) {
        curr_sum += arr[i];
  
        // as the sum can be negative, taking modulo twice
        mod_arr[i] = ((curr_sum % k) + k) % k;
    }
  
    for (int i = 0; i < n; i++) {
  
        // if true then sum(0..i) is divisible
        // by k
        if (mod_arr[i] == 0) {
  

1277
Chapter 171. Largest rectangular sub-matrix having sum divisible by k

            // update variables


            max = i + 1;
            start = 0;
            finish = i;
        }
  
        // if value 'mod_arr[i]' not present in 'um'
        // then store it in 'um' with index of its
        // first occurrence
        else if (um.find(mod_arr[i]) == um.end())
            um[mod_arr[i]] = i;
  
        else
            // if true, then update variables
            if (max < (i - um[mod_arr[i]])) {
            max = i - um[mod_arr[i]];
            start = um[mod_arr[i]] + 1;
            finish = i;
        }
    }
}
  
// function to find largest rectangular sub-matrix
// having sum divisible by k
void findLargestSubmatrix(int mat[SIZE][SIZE], int n, int k)
{
    // Variables to store the final output
    int finalLeft, finalRight, finalTop, finalBottom;
  
    int left, right, i, maxArea = 0;
    int temp[n], start, finish;
  
    // Set the left column
    for (left = 0; left < n; left++) {
  
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
  
        // Set the right column for the left column
        // set by outer loop
        for (right = left; right < n; right++) {
  
            // Calculate sum between current left and 
            // right for every row 'i'
            for (i = 0; i < n; ++i)
                temp[i] += mat[i][right];
  
            // The longSubarrWthSumDivByK() function sets

1278
Chapter 171. Largest rectangular sub-matrix having sum divisible by k

            // the values of 'start' and 'finish'. So 


            // submatrix having sum divisible by 'k' between 
            // (start, left) and (finish, right) which is
            // the largest submatrix with boundary columns 
            // strictly as left and right.
            longSubarrWthSumDivByK(temp, n, k, start, finish);
  
            // Calculate current area and compare it with 
            // maximum area so far. If maxArea is less, then 
            // update maxArea and other output values
            if (maxArea < ((right - left + 1) * 
                          (finish - start + 1))) {
                finalLeft = left;
                finalRight = right;
                finalTop = start;
                finalBottom = finish;
                maxArea = (right - left + 1) * (finish - start + 1);
            }
        }
    }
  
    // Print final values
    cout << "(Top, Left): (" << finalTop << ", "
         << finalLeft << ")\n";
    cout << "(Bottom, Right): (" << finalBottom << ", "
         << finalRight << ")\n";
    cout << "Area: " << maxArea;
}
  
// Driver program to test above functions
int main()
{
    int mat[SIZE][SIZE] = { { 1, 2, -1, -4 },
                            { -8, -3, 4, 2 },
                            { 3, 8, 10, 1 },
                            { -4, -1, 1, 7 } };
  
    int n = 4, k = 5;
    findLargestSubmatrix(mat, n, k);
  
    return 0;
}

Output:

(Top, Left): (0, 0)


(Bottom, Right): (2, 3)

1279
Chapter 171. Largest rectangular sub-matrix having sum divisible by k

Area: 12

Time Complexity: O(n^3).


Auxiliary Space: O(n).

Source

https://www.geeksforgeeks.org/largest-rectangular-sub-matrix-sum-divisible-k/

1280
Chapter 172

Largest rectangular sub-matrix


whose sum is 0

Largest rectangular sub-matrix whose sum is 0 - GeeksforGeeks


Given a 2D matrix, find the largest rectangular sub-matrix whose sum is 0. for example
consider the following N x M input matrix

Examples:

Input : 1, 2, 3
-3, -2, -1
1, 7, 5

Output : 1, 2, 3
-3, -2, -1

1281
Chapter 172. Largest rectangular sub-matrix whose sum is 0

Input : 9, 7, 16, 5
1, -6, -7, 3
1, 8, 7, 9
7, -2, 0, 10

Output :-6, -7
8, 7
-2, 0

The naive solution for this problem is to check every possible rectangle in given 2D array.
This solution requires 4 nested loops and time complexity of this solution would be O(n^4).
The solution is based onMaximum sum rectangle in a 2D matrix. The idea is to reduce
the problem to 1 D array. We can use Hashing to find maximum length of sub-array in
1-D array in O(n) time. We fix the left and right columns one by one and find the largest
sub-array with 0 sum contiguous rows for every left and right column pair. We basically
find top and bottom row numbers (which have sum is zero) for every fixed left and right
column pair. To find the top and bottom row numbers, calculate sum of elements in every
row from left to right and store these sums in an array say temp[]. So temp[i] indicates sum
of elements from left to right in row i. If we find largest subarray with 0 sum on temp, and
no. of elements is greater than previous no. of elements then update the values of final
row_up, final row_down, final col_left, final col_right.

// A C++ program to find Largest rectangular


// sub-matrix whose sum is 0
#include <bits/stdc++.h>
using namespace std;
  
const int MAX = 100;
  
// This function basically finds largest 0
// sum aubarray in temp[0..n-1]. If 0 sum
// does't exist, then it returns false. Else
// it returns true and sets starting and
// ending indexes as starti and endj.
bool sumZero(int temp[], int* starti,
            int* endj, int n)
{
    // Map to store the previous sums
    map<int, int> presum;
    int sum = 0; // Initialize sum of elements
  
    // Initialize length of sub-array with sum 0
    int max_length = 0;
  
    // Traverse through the given array
    for (int i = 0; i < n; i++)

1282
Chapter 172. Largest rectangular sub-matrix whose sum is 0

    {
        // Add current element to sum
        sum += temp[i];
  
        if (temp[i] == 0 && max_length == 0)
        {
            *starti = i;
            *endj = i;
            max_length = 1;
        }
        if (sum == 0)
        {
            if (max_length < i + 1)
            {
                *starti = 0;
                *endj = i;
            }
            max_length = i + 1;
        }
  
        // Look for this sum in Hash table
        if (presum.find(sum) != presum.end())
        {
            // store previous max_length so
            // that we can check max_length
            // is updated or not
            int old = max_length;
  
            // If this sum is seen before,
            // then update max_len
            max_length = max(max_length, i - presum[sum]);
  
            if (old < max_length)
            {
                // If max_length is updated then
                // enter and update start and end
                // point of array
                *endj = i;
                *starti = presum[sum] + 1;
            }
        }
        else
  
            // Else insert this sum with
            // index in hash table
            presum[sum] = i;
    }
  

1283
Chapter 172. Largest rectangular sub-matrix whose sum is 0

    // Return true if max_length is non-zero


    return (max_length != 0);
}
  
// The main function that finds Largest rectangle
// sub-matrix in a[][] whose sum is 0.
void sumZeroMatrix(int a[][MAX], int row, int col)
{
    int temp[row];
  
    // Variables to store the final output
    int fup = 0, fdown = 0, fleft = 0, fright = 0;
    int sum;
    int up, down;
    int maxl = INT_MIN;
  
    // Set the left column
    for (int left = 0; left < col; left++)
    {
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
  
        // Set the right column for the left column
        // set by outer loop
        for (int right = left; right < col; right++)
        {
            // Calculate sum between current left
            // and right for every row 'i'
            for (int i = 0; i < row; i++)
                temp[i] += a[i][right];
  
            // Find largest subarray with 0 sum in
            // temp[]. The sumZero() function also
            // sets values of start and finish. So
            // 'sum' is sum of rectangle between (start,
            // left) and (finish, right) which is
            // boundary columns strictly as left and right.
            bool sum = sumZero(temp, &up, &down, row);
            int ele = (down - up + 1) * (right - left + 1);
  
            // Compare no. of elements with previous
            // no. of elements in sub-Matrix.
            // If new sub-matrix has more elements
            // then update maxl and final boundaries
            // like fup, fdown, fleft, fright
            if (sum && ele > maxl)
            {
                fup = up;

1284
Chapter 172. Largest rectangular sub-matrix whose sum is 0

                fdown = down;
                fleft = left;
                fright = right;
                maxl = ele;
            }
        }
    }
  
    // If there is no change in boundaries
    // than check if a[0][0] is 0
    // If it not zero then print 
    // that no such zero-sum sub-matrix exists
    if (fup == 0 && fdown == 0 && fleft == 0 &&
            fright == 0 && a[0][0] != 0) {
        cout << "No zero-sum sub-matrix exists";
        return;
    }
  
    // Print final values
    for (int j = fup; j <= fdown; j++)
    {
        for (int i = fleft; i <= fright; i++)
            cout << a[j][i] << " ";
        cout << endl;
    }
}
  
// Driver program to test above functions
int main()
{
    int a[][MAX] = { { 9, 7, 16, 5 }, { 1, -6, -7, 3 },
                      { 1, 8, 7, 9 }, { 7, -2, 0, 10 } };
   
    int row = 4, col = 4;
    sumZeroMatrix(a, row, col);
    return 0;
}

Output:

-6, -7
8, 7
-2, 0

Source
https://www.geeksforgeeks.org/largest-rectangular-sub-matrix-whose-sum-0/

1285
Chapter 173

Largest sum Zigzag sequence in


a matrix

Largest sum Zigzag sequence in a matrix - GeeksforGeeks


Given a matrix of size n x n, find sum of the Zigzag sequence with the largest sum. A zigzag
sequence starts from the top and ends at the bottom. Two consecutive elements of sequence
cannot belong to same column.
Examples:

Input : mat[][] = 3 1 2
4 8 5
6 9 7
Output : 18
Zigzag sequence is: 3->8->7
Another such sequence is 2->4->7

Input : mat[][] = 4 2 1
3 9 6
11 3 15
Output : 28

This problem has Optimal Substructure.

Maximum Zigzag sum starting from arr[i][j] to a


bottom cell can be written as :
zzs(i, j) = arr[i][j] + max(zzs(i+1, k)),
where k = 0, 1, 2 and k != j
zzs(i, j) = arr[i][j], if i = n-1

1286
Chapter 173. Largest sum Zigzag sequence in a matrix

We have to find the largest among all as


Result = zzs(0, j) where 0 <= j < n

C++

// C++ program to find the largest sum zigzag sequence


#include <bits/stdc++.h>
using namespace std;
  
const int MAX = 100;
  
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
int largestZigZagSumRec(int mat[][MAX], int i,
                                int j, int n)
{
   // If we have reached bottom
   if (i == n-1)
     return mat[i][j];
  
   // Find the largest sum by considering all
   // possible next elements in sequence.
   int zzs = 0;
   for (int k=0; k<n; k++)
     if (k != j)
       zzs = max(zzs, largestZigZagSumRec(mat, i+1, k, n));
  
   return zzs + mat[i][j];
}
  
// Returns largest possible sum of a Zizag sequence
// starting from top and ending at bottom.
int largestZigZag(int mat[][MAX], int n)
{
   // Consider all cells of top row as starting point
   int res = 0;
   for (int j=0; j<n; j++)
     res = max(res, largestZigZagSumRec(mat, 0, j, n));
  
   return res;
}
  
// Driver program to test above
int main()
{
    int n = 3;
    int  mat[][MAX] = { {4, 2, 1},
                        {3, 9, 6},

1287
Chapter 173. Largest sum Zigzag sequence in a matrix

                        {11, 3, 15}};
    cout << "Largest zigzag sum: " << largestZigZag(mat, n);
    return 0;
}

Java

// Java program to find the largest sum 


// zigzag sequence
import java.io.*;
  
class GFG {
  
    static int MAX = 100;
      
    // Returns largest sum of a Zigzag 
    // sequence starting from (i, j) 
    // and ending at a bottom cell.
    static int largestZigZagSumRec(int mat[][],
                            int i, int j, int n)
    {
          
        // If we have reached bottom
        if (i == n-1)
            return mat[i][j];
          
        // Find the largest sum by considering all
        // possible next elements in sequence.
        int zzs = 0;
          
        for (int k=0; k<n; k++)
            if (k != j)
            zzs = Math.max(zzs, 
               largestZigZagSumRec(mat, i+1, k, n));
          
        return zzs + mat[i][j];
    }
      
    // Returns largest possible sum of a Zizag
    // sequence starting from top and ending 
    // at bottom.
    static int largestZigZag(int mat[][], int n)
    {
        // Consider all cells of top row as starting
        // point
        int res = 0;
        for (int j=0; j<n; j++)
            res = Math.max(res, 

1288
Chapter 173. Largest sum Zigzag sequence in a matrix

                   largestZigZagSumRec(mat, 0, j, n));
          
        return res;
    }
      
    // Driver program to test above
    public static void main (String[] args)
    {
        int n = 3;
          
        int mat[][] = { {4, 2, 1},
                        {3, 9, 6},
                        {11, 3, 15} };
        System.out.println( "Largest zigzag sum: " 
                       + largestZigZag(mat, n));
    }
}
  
// This code is contributed by anuj_67.

C#

// C# program to find the largest sum 


// zigzag sequence
using System;
class GFG {
  
    // static int MAX = 100;
      
    // Returns largest sum of a Zigzag 
    // sequence starting from (i, j) 
    // and ending at a bottom cell.
    static int largestZigZagSumRec(int [,]mat,
                          int i, int j, int n)
    {
          
        // If we have reached bottom
        if (i == n-1)
            return mat[i,j];
          
        // Find the largest sum by considering all
        // possible next elements in sequence.
        int zzs = 0;
          
        for (int k = 0; k < n; k++)
            if (k != j)
            zzs = Math.Max(zzs, largestZigZagSumRec(mat, 
                                           i + 1, k, n));

1289
Chapter 173. Largest sum Zigzag sequence in a matrix

          
        return zzs + mat[i,j];
    }
      
    // Returns largest possible
    // sum of a Zizag sequence 
    // starting from top and ending 
    // at bottom.
    static int largestZigZag(int [,]mat, int n)
    {
          
        // Consider all cells of 
        // top row as starting
        // point
        int res = 0;
        for (int j = 0; j < n; j++)
            res = Math.Max(res, 
                largestZigZagSumRec(mat, 0, j, n));
          
        return res;
    }
      
    // Driver Code
    public static void Main ()
    {
        int n = 3;
        int [,]mat = {{4, 2, 1},
                      {3, 9, 6},
                      {11, 3, 15}};
        Console.WriteLine("Largest zigzag sum: "
                           + largestZigZag(mat, n));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to find the 
// largest sum zigzag sequence
  
$MAX = 100;
  
// Returns largest sum of a 
// Zigzag sequence starting
// from (i, j) and ending at
// a bottom cell.

1290
Chapter 173. Largest sum Zigzag sequence in a matrix

function largestZigZagSumRec($mat, $i,


                              $j, $n)
{
    // If we have reached bottom
    if ($i == $n - 1)
        return $mat[$i][$j];
      
    // Find the largest sum
    // by considering all
    // possible next elements
    // in sequence.
    $zzs = 0;
    for ($k = 0; $k < $n; $k++)
        if ($k != $j)
        $zzs = max($zzs, largestZigZagSumRec($mat, 
                                $i + 1, $k, $n));
      
    return $zzs + $mat[$i][$j];
}
  
// Returns largest possible
// sum of a Zizag sequence
// starting from top and 
// ending at bottom.
function largestZigZag( $mat, $n)
{
      
    // Consider all cells of top
    // row as starting point
    $res = 0;
    for ($j = 0; $j < $n; $j++)
        $res = max($res, largestZigZagSumRec(
                            $mat, 0, $j, $n));
      
    return $res;
}
  
    // Driver Code
    $n = 3;
    $mat = array(array(4, 2, 1),
                 array(3, 9, 6),
                 array(11, 3, 15));
    echo "Largest zigzag sum: " , largestZigZag($mat, $n);
      
// This code is contributed by anuj_67.
?>

Output:

1291
Chapter 173. Largest sum Zigzag sequence in a matrix

Largest zigzag sum: 28

Overlapping Subproblems
Considering the above implementation, for a matrix mat[][] of size 3 x 3, to find zigzag
sum(zzs) for an element mat(i,j), the following recursion tree is formed.

Recursion tree for cell (0, 0)


zzs(0,0)
/ \
zzs(1,1) zzs(1,2)
/ \ / \
zzs(2,0) zzs(2,2) zzs(2,0) zzs(2,1)

Recursion tree for cell (0, 1)


zzs(0,1)
/ \
zzs(1,0) zzs(1,2)
/ \ / \
zzs(2,1) zzs(2,2) zzs(2,0) zzs(2,1)

Recursion tree for cell (0, 2)


zzs(0,2)
/ \
zzs(1,0) zzs(1,1)
/ \ / \
zzs(2,1) zzs(2,2) zzs(2,0) zzs(2,2)

We can see that there are many subproblems which are solved again and again. So this
problem has Overlapping Substructure property and recomputation of same subproblems
can be avoided by either using Memoization or Tabulation. Following is a tabluated imple-
mentation for the LIS problem.

// Memoization based C++ program to find the largest


// sum zigzag sequence
#include <bits/stdc++.h>
using namespace std;
  
const int MAX = 100;
int dp[MAX][MAX];
  
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
int largestZigZagSumRec(int mat[][MAX], int i,

1292
Chapter 173. Largest sum Zigzag sequence in a matrix

                                int j, int n)
{
   if (dp[i][j] != -1)
      return dp[i][j];
  
   // If we have reached bottom
   if (i == n-1)
     return (dp[i][j] = mat[i][j]);
  
   // Find the largest sum by considering all
   // possible next elements in sequence.
   int zzs = 0;
   for (int k=0; k<n; k++)
     if (k != j)
       zzs = max(zzs, largestZigZagSumRec(mat, i+1, k, n));
  
   return (dp[i][j] = (zzs + mat[i][j]));
}
  
// Returns largest possible sum of a Zizag sequence
// starting from top and ending at bottom.
int largestZigZag(int mat[][MAX], int n)
{
   memset(dp, -1, sizeof(dp));
  
   // Consider all cells of top row as starting point
   int res = 0;
   for (int j=0; j<n; j++)
     res = max(res, largestZigZagSumRec(mat, 0, j, n));
  
   return res;
}
  
// Driver program to test above
int main()
{
    int n = 3;
    int  mat[][MAX] = { {4, 2, 1},
                        {3, 9, 6},
                        {11, 3, 15}};
    cout << "Largest zigzag sum: " << largestZigZag(mat, n);
    return 0;
}

Output:

28

1293
Chapter 173. Largest sum Zigzag sequence in a matrix

References: Asked in Directi


Improved By : vt_m

Source

https://www.geeksforgeeks.org/largest-sum-zig-zag-sequence-in-a-matrix/

1294
Chapter 174

Largest sum subarray with


at-least k numbers

Largest sum subarray with at-least k numbers - GeeksforGeeks


Given an array, find the subarray (containing at least k numbers) which has the largest sum.
Examples:

Input : arr[] = {-4, -2, 1, -3}


k = 2
Output : -1
The sub array is {-2, 1}

Input : arr[] = {1, 1, 1, 1, 1, 1}


k = 2
Output : 6
The sub array is {1, 1, 1, 1, 1, 1}

Asked in : Facebook
This problem is an extension of Largest Sum Subarray Problem.
1) We first compute maximum sum till every index and store it in an array maxSum[].
2) After filling the array, we use the sliding window concept of size k. Keep track of sum
of current k elements. To compute sum of current window, remove first element of previous
window and add current element. After getting the sum of current window, we add the
maxSum of the previous window, if it is greater than current max, then update it else not.
C++

// C++ program to find largest subarray sum with


// at-least k elements in it.

1295
Chapter 174. Largest sum subarray with at-least k numbers

#include<bits/stdc++.h>
using namespace std;
  
// Returns maximum sum of a subarray with at-least
// k elements.
int maxSumWithK(int a[], int n, int k)
{
    // maxSum[i] is going to store maximum sum
    // till index i such that a[i] is part of the
    // sum.
    int maxSum[n];
    maxSum[0] = a[0];
  
    // We use Kadane's algorithm to fill maxSum[]
    // Below code is taken from method 3 of
    // https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/
    int curr_max = a[0];
    for (int i = 1; i < n; i++)
    {
        curr_max = max(a[i], curr_max+a[i]);
        maxSum[i] = curr_max;
    }
  
    // Sum of first k elements
    int sum = 0;
    for (int i = 0; i < k; i++)
        sum += a[i];
  
    // Use the concept of sliding window
    int result = sum;
    for (int i = k; i < n; i++)
    {
        // Compute sum of k elements ending
        // with a[i].
        sum = sum + a[i] - a[i-k];
  
        // Update result if required
        result = max(result, sum);
  
        // Include maximum sum till [i-k] also
        // if it increases overall max.
        result = max(result, sum + maxSum[i-k]);
    }
    return result;
}
  
// Driver code
int main()

1296
Chapter 174. Largest sum subarray with at-least k numbers

{
    int a[] = {1, 2, 3, -10, -3};
    int k = 4;
    int n = sizeof(a)/sizeof(a[0]);
    cout << maxSumWithK(a, n, k);
    return 0;
}

Java

// Java program to find largest subarray sum with


// at-least k elements in it.
class Test
{
    // Returns maximum sum of a subarray with at-least
    // k elements.
    static int maxSumWithK(int a[], int n, int k)
    {
        // maxSum[i] is going to store maximum sum
        // till index i such that a[i] is part of the
        // sum.
        int maxSum[] = new int [n];
        maxSum[0] = a[0];
  
        // We use Kadane's algorithm to fill maxSum[]
        // Below code is taken from method 3 of
        // https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/
        int curr_max = a[0];
        for (int i = 1; i < n; i++)
        {
            curr_max = Math.max(a[i], curr_max+a[i]);
            maxSum[i] = curr_max;
        }
  
        // Sum of first k elements
        int sum = 0;
        for (int i = 0; i < k; i++)
            sum += a[i];
  
        // Use the concept of sliding window
        int result = sum;
        for (int i = k; i < n; i++)
        {
            // Compute sum of k elements ending
            // with a[i].
            sum = sum + a[i] - a[i-k];
  
            // Update result if required

1297
Chapter 174. Largest sum subarray with at-least k numbers

            result = Math.max(result, sum);


  
            // Include maximum sum till [i-k] also
            // if it increases overall max.
            result = Math.max(result, sum + maxSum[i-k]);
        }
        return result;
    }
  
    // Driver method
    public static void main(String[] args)
    {
        int arr[] = {1, 2, 3, -10, -3};
        int k = 4;
        System.out.println(maxSumWithK(arr, arr.length, k));;
    }
}

Python3

# Python3 program to find largest subarray 


# sum with at-least k elements in it.
  
# Returns maximum sum of a subarray
#  with at-least k elements.
def maxSumWithK(a, n, k):
   
    # maxSum[i] is going to store 
    # maximum sum till index i such
    # that a[i] is part of the sum.
    maxSum = [0 for i in range(n)]
    maxSum[0] = a[0]
  
    # We use Kadane's algorithm to fill maxSum[]
    # Below code is taken from method3 of
    # https://www.geeksforgeeks.org/largest-sum-contiguous-subarray/
    curr_max = a[0]
    for i in range(1, n):
      
        curr_max = max(a[i], curr_max + a[i])
        maxSum[i] = curr_max
  
    # Sum of first k elements
    sum = 0
    for i in range(k):
        sum += a[i]
  
    # Use the concept of sliding window

1298
Chapter 174. Largest sum subarray with at-least k numbers

    result = sum
    for i in range(k, n):
      
        # Compute sum of k elements 
        # ending with a[i].
        sum = sum + a[i] - a[i-k]
  
        # Update result if required
        result = max(result, sum)
  
        # Include maximum sum till [i-k] also
        # if it increases overall max.
        result = max(result, sum + maxSum[i-k])
      
    return result
  
# Driver code
a = [1, 2, 3, -10, -3]
k = 4
n = len(a)
print(maxSumWithK(a, n, k))
  
# This code is contributed by Anant Agarwal.

PHP

<?php
// PHP program to find largest subarray 
// sum with at-least k elements in it.
  
// Returns maximum sum of a subarray
// with at-least k elements.
function maxSumWithK($a, $n, $k)
{
      
    // maxSum[i] is going to 
    // store maximum sum till
    // index i such that a[i]
    // is part of the sum.
    $maxSum[0] = $a[0];
  
    // We use Kadane's algorithm
    // to fill maxSum[] 
    $curr_max = $a[0];
    for ($i = 1; $i < $n; $i++)
    {
        $curr_max = max($a[$i], $curr_max+$a[$i]);
        $maxSum[$i] = $curr_max;

1299
Chapter 174. Largest sum subarray with at-least k numbers

    }
  
    // Sum of first k elements
    $sum = 0;
    for ($i = 0; $i < $k; $i++)
        $sum += $a[$i];
  
    // Use the concept of 
    // sliding window
    $result = $sum;
    for ($i = $k; $i < $n; $i++)
    {
        // Compute sum of k 
        // elements ending
        // with a[i].
        $sum = $sum + $a[$i] - $a[$i - $k];
  
        // Update result if required
        $result = max($result, $sum);
  
        // Include maximum sum till [i-k] also
        // if it increases overall max.
        $result = max($result, $sum +
                    $maxSum[$i - $k]);
    }
    return $result;
}
  
    // Driver code
    $a= array (1, 2, 3, -10, -3);
    $k = 4;
    $n = sizeof($a);
    echo maxSumWithK($a, $n, $k);
  
// This code is contributed by m_kit
?>

Output:

-4

Time Complexity: O(n)


Improved By : jit_t

1300
Chapter 174. Largest sum subarray with at-least k numbers

Source

https://www.geeksforgeeks.org/largest-sum-subarray-least-k-numbers/

1301
Chapter 175

Length of Longest Balanced


Subsequence

Length of Longest Balanced Subsequence - GeeksforGeeks


Given a string S, find the length of longest balanced subsequence in it. A balanced string
is defined as:-

• A Null string is a balanced string.


• If X and Y are balanced strings, then (X)Y and XY are balanced strings.

Examples :

Input : S = "()())"
Output : 4

()() is the longest balanced subsequence


of length 4.

Input : s = "()(((((()"
Output : 4

A brute force approach is to find all subsequence of the given string S and check for all
possible subsequence if it form a balanced sequence, if yes, compare it with maximum value.
The better approach is to use Dynamic Programming.
Longest Balananced Subsequence (LBS), can be recursively defined as below.

LBS of substring str[i..j] :

1302
Chapter 175. Length of Longest Balanced Subsequence

If str[i] == str[j]
LBS(str, i, j) = LBS(str, i + 1, j - 1) + 2
Else
LBS(str, i, j) = max(LBS(str, i, k) +
LBS(str, k + 1, j))
Where i <= k < j

Declare a 2D matrix dp[][], where our state dp[i][j] will denote the length of longest balanced
subsequence from index i to j. We will compute this state in order of increasing j - i. For a
particular state dp[i][j], we will try to match the jth symbol with kth symbol, that can be
done only if S[k] is ’(’ and S[j] is ’)’, we will take the max of 2 + dp[i][k - 1] + dp[k + 1][j -
1] for all such possible k and also max(dp[i + 1][j], dp[i][j - 1]) and put the value in dp[i][j].
In this way we can fill all the dp states. dp[0][length of string - 1] (considering 0 indexing)
will be our answer.
Below is the implementation of this approach:

C++

// C++ program to find length of 


// the longest balanced subsequence
#include <bits/stdc++.h>
using namespace std;
  
int maxLength(char s[], int n)
{
    int dp[n][n];
    memset(dp, 0, sizeof(dp));
  
    // Considering all balanced 
    // substrings of length 2
    for (int i = 0; i < n - 1; i++)
        if (s[i] == '(' && s[i + 1] == ')')
            dp[i][i + 1] = 2;
  
    // Considering all other substrings
    for (int l = 2; l < n; l++) 
    {
        for (int i = 0, j = l; j < n; i++, j++) 
        {
            if (s[i] == '(' && s[j] == ')')
                dp[i][j] = 2 + dp[i + 1][j - 1];
  
            for (int k = i; k < j; k++) 
                dp[i][j] = max(dp[i][j],
                              dp[i][k] + 
                          dp[k + 1][j]);         
        }

1303
Chapter 175. Length of Longest Balanced Subsequence

    }
  
    return dp[0][n - 1];
}
  
// Driver Code
int main()
{
    char s[] = "()(((((()";
    int n = strlen(s);
    cout << maxLength(s, n) << endl;
    return 0;
}

Java

// Java program to find length of the


// longest balanced subsequence.
import java.io.*;
  
class GFG 
{
static int maxLength(String s, int n)
{
    int dp[][] = new int[n][n];
      
  
    // Considering all balanced substrings 
    // of length 2
    for (int i = 0; i < n - 1; i++)
        if (s.charAt(i) == '(' &&  
                s.charAt(i + 1)    == ')')
            dp[i][i + 1] = 2;
  
    // Considering all other substrings
    for (int l = 2; l < n; l++) 
    {
        for (int i = 0, j = l; j < n; i++, j++) 
        {
            if (s.charAt(i) == '(' && 
                      s.charAt(j) == ')')
                dp[i][j] = 2 + dp[i + 1][j - 1];
  
            for (int k = i; k < j; k++) 
                dp[i][j] = Math.max(dp[i][j],
                        dp[i][k] + dp[k + 1][j]);     
                              
        }

1304
Chapter 175. Length of Longest Balanced Subsequence

    }
  
    return dp[0][n - 1];
}
  
// Driver Code
public static void main(String[] args)
{
    String s = "()(((((()";
    int n = s.length() ;
    System.out.println(maxLength(s, n));
}
}
// This code is contributed by Prerna Saini

C#

// C# program to find length of the


// longest balanced subsequence.
using System;
  
class GFG 
{
  
static int maxLength(String s, int n)
{
    int [,]dp = new int[n, n];
      
  
    // Considering all balanced substrings 
    // of length 2
    for (int i = 0; i < n - 1; i++)
        if (s[i] == '(' && s[i + 1] == ')')
            dp[i, i + 1] = 2;
  
    // Considering all other substrings
    for (int l = 2; l < n; l++) 
    {
        for (int i = 0, j = l; j < n; i++, j++) 
        {
            if (s[i] == '(' && s[j] == ')')
                dp[i, j] = 2 + dp[i + 1, j - 1];
  
            for (int k = i; k < j; k++) 
                dp[i, j] = Math.Max(dp[i, j],
                        dp[i, k] + dp[k + 1, j]);     
        }
    }

1305
Chapter 175. Length of Longest Balanced Subsequence

  
    return dp[0, n - 1];
}
  
    // Driver Code
    public static void Main()
    {
        string s = "()(((((()";
        int n = s.Length ;
        Console.WriteLine(maxLength(s, n));
    }
}
  
// This code is contributed by vt_m.

Output:

Time Complexity : O(n2 )


Auxiliary Space : O(n2 )
Improved By : vt_m

Source

https://www.geeksforgeeks.org/length-longest-balanced-subsequence/

1306
Chapter 176

Length of longest common


subsequence containing vowels

Length of longest common subsequence containing vowels - GeeksforGeeks


Given two strings X and Y of length m and n respectively. The problem is to find the
length of the longest common subsequence of strings X and Y which contains all vowel
characters.
Examples:

Input : X = "aieef"
Y = "klaief"
Output : aie

Input : X = "geeksforgeeks"
Y = "feroeeks"
Output : eoee

Source: Paytm Interview Experience ( Backend Developer ).


Naive Approach: Generate all subsequences of both given sequences and find the longest
matching subsequence which contains all vowel characters. This solution is exponential in
term of time complexity.
Efficient Approach (Dynamic Programming): This approach is a variation to Longest
Common Subsequence | DP-4 problem. The difference in this post is just that the common
subsequence characters must all be vowels.

Source
https://www.geeksforgeeks.org/length-of-longest-common-subsequence-containing-vowels/

1307
Chapter 176. Length of longest common subsequence containing vowels

C++

// C++ implementation to find the length of longest common


// subsequence which contains all vowel characters
#include <bits/stdc++.h>
  
using namespace std;
  
// function to check whether 'ch'
// is a vowel or not
bool isVowel(char ch)
{
    if (ch == 'a' || ch == 'e' || ch == 'i'
        || ch == 'o' || ch == 'u')
        return true;
    return false;
}
  
// function to find the length of longest common subsequence
// which contains all vowel characters
int lcs(char* X, char* Y, int m, int n)
{
    int L[m + 1][n + 1];
    int i, j;
  
    // Following steps build L[m+1][n+1] in bottom up fashion. Note
    // that L[i][j] contains length of LCS of X[0..i-1] and Y[0..j-1]
    for (i = 0; i <= m; i++) {
        for (j = 0; j <= n; j++) {
            if (i == 0 || j == 0)
                L[i][j] = 0;
  
            else if ((X[i - 1] == Y[j - 1]) && isVowel(X[i - 1]))
                L[i][j] = L[i - 1][j - 1] + 1;
  
            else
                L[i][j] = max(L[i - 1][j], L[i][j - 1]);
        }
    }
  
    // L[m][n] contains length of LCS for X[0..n-1] and Y[0..m-1]
    // which contains all vowel characters
    return L[m][n];
}
  
// Driver program to test above
int main()
{

1308
Chapter 176. Length of longest common subsequence containing vowels

    char X[] = "aieef";


    char Y[] = "klaief";
  
    int m = strlen(X);
    int n = strlen(Y);
  
    cout << "Length of LCS = "
         << lcs(X, Y, m, n);
  
    return 0;
}

Java
// Java implementation to find the
// length of longest common subsequence
// which contains all vowel characters
class GFG
{
// function to check whether ‘ch’
// is a vowel or not
static boolean isVowel(char ch)
{
if (ch == ‘a’ || ch == ‘e’ ||
ch == ‘i’ || ch == ‘o’ ||
ch == ‘u’)
return true;
return false;
}
// function to find the length of
// longest common subsequence which
// contains all vowel characters
static int lcs(String X, String Y,
int m, int n)
{
int L[][] = new int[m + 1][n + 1];
int i, j;
// Following steps build L[m+1][n+1]
// in bottom up fashion. Note that
// L[i][j] contains length of LCS of
// X[0..i-1] and Y[0..j-1]
for (i = 0; i <= m; i++) { for (j = 0; j <= n; j++) { if (i == 0 || j == 0) L[i][j] = 0; else if
((X.charAt(i - 1) == Y.charAt(j - 1)) && isVowel(X.charAt(i - 1))) L[i][j] = L[i - 1][j - 1] +
1; else L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]); } } // L[m][n] contains length of LCS // for
X[0..n-1] and Y[0..m-1] // which contains all vowel characters return L[m][n]; } // Driver
Code public static void main(String[] args) { String X = ”aieef”; String Y = ”klaief”; int

1309
Chapter 176. Length of longest common subsequence containing vowels

m = X.length(); int n = Y.length(); System.out.println(”Length of LCS = ” + lcs(X, Y, m,


n)); } } // This code is contributed by Bilal [tabbyending]
Output:

Length of LCS = 3

Time Complexity: O(m*n).


Auxiliary Space: O(m*n).
Improved By : bilal-hungund

1310
Chapter 177

Length of the longest valid


substring

Length of the longest valid substring - GeeksforGeeks


Given a string consisting of opening and closing parenthesis, find length of the longest valid
parenthesis substring.
Examples:

Input : ((()
Output : 2
Explanation : ()

Input: )()())
Output : 4
Explanation: ()()

Input: ()(()))))
Output: 6
Explanation: ()(())

A Simple Approach is to find all the substrings of given string. For every string, check
if it is a valid string or not. If valid and length is more than maximum length so far, then
update maximum length. We can check whether a substring is valid or not in linear time
using a stack (See this for details). Time complexity of this solution is O(n2 .
An Efficient Solution can solve this problem in O(n) time. The idea is to store indexes
of previous starting brackets in a stack. The first element of stack is a special element that
provides index before beginning of valid substring (base for next valid string).

1311
Chapter 177. Length of the longest valid substring

1) Create an empty stack and push -1 to it. The first element


of stack is used to provide base for next valid string.

2) Initialize result as 0.

3) If the character is '(' i.e. str[i] == '('), push index


'i' to the stack.

2) Else (if the character is ')')


a) Pop an item from stack (Most of the time an opening bracket)
b) If stack is not empty, then find length of current valid
substring by taking difference between current index and
top of the stack. If current length is more than result,
then update the result.
c) If stack is empty, push current index as base for next
valid substring.

3) Return result.

Below are C++ and Python implementations of above algorithm.

C++

// C++ program to find length of the longest valid


// substring
#include<bits/stdc++.h>
using namespace std;
  
int findMaxLen(string str)
{
    int n = str.length();
  
    // Create a stack and push -1 as initial index to it.
    stack<int> stk;
    stk.push(-1);
  
    // Initialize result
    int result = 0;
  
    // Traverse all characters of given string
    for (int i=0; i<n; i++)
    {
        // If opening bracket, push index of it
        if (str[i] == '(')
          stk.push(i);
  

1312
Chapter 177. Length of the longest valid substring

        else // If closing bracket, i.e.,str[i] = ')'


        {
            // Pop the previous opening bracket's index
            stk.pop();
  
            // Check if this length formed with base of
            // current valid substring is more than max 
            // so far
            if (!stk.empty())
                result = max(result, i - stk.top());
  
            // If stack is empty. push current index as 
            // base for next valid substring (if any)
            else stk.push(i);
        }
    }
  
    return result;
}
  
// Driver program
int main()
{
    string str = "((()()";
    cout << findMaxLen(str) << endl;
  
    str = "()(()))))";
    cout << findMaxLen(str) << endl ;
  
    return 0;
}

Java

// Java program to find length of the longest valid


// substring
  
import java.util.Stack;
      
class Test
{
    // method to get length of the longest valid
    static int findMaxLen(String str)
    {
        int n = str.length();
       
        // Create a stack and push -1 as initial index to it.
        Stack<Integer> stk = new Stack<>();

1313
Chapter 177. Length of the longest valid substring

        stk.push(-1);
       
        // Initialize result
        int result = 0;
       
        // Traverse all characters of given string
        for (int i=0; i<n; i++)
        {
            // If opening bracket, push index of it
            if (str.charAt(i) == '(')
              stk.push(i);
       
            else // If closing bracket, i.e.,str[i] = ')'
            {
                // Pop the previous opening bracket's index
                stk.pop();
       
                // Check if this length formed with base of
                // current valid substring is more than max 
                // so far
                if (!stk.empty())
                    result = Math.max(result, i - stk.peek());
       
                // If stack is empty. push current index as 
                // base for next valid substring (if any)
                else stk.push(i);
            }
        }
       
        return result;
    }
      
    // Driver method
    public static void main(String[] args) 
    {
        String str = "((()()";
        System.out.println(findMaxLen(str));
       
        str = "()(()))))";
        System.out.println(findMaxLen(str));
       
    }
}

Python

# Python program to find length of the longest valid


# substring

1314
Chapter 177. Length of the longest valid substring

  
def findMaxLen(string):
    n = len(string)
  
    # Create a stack and push -1 as initial index to it.
    stk = []
    stk.append(-1)
  
    # Initialize result
    result = 0
  
    # Traverse all characters of given string
    for i in xrange(n):
      
        # If opening bracket, push index of it
        if string[i] == '(':
            stk.append(i)
  
        else:    # If closing bracket, i.e., str[i] = ')'
      
            # Pop the previous opening bracket's index
            stk.pop()
      
            # Check if this length formed with base of
            # current valid substring is more than max 
            # so far
            if len(stk) != 0:
                result = max(result, i - stk[len(stk)-1])
  
            # If stack is empty. push current index as 
            # base for next valid substring (if any)
            else:
                stk.append(i)
  
    return result
  
# Driver program
string = "((()()"
print findMaxLen(string)
  
string = "()(()))))"
print findMaxLen(string)
  
# This code is contributed by Bhavya Jain

Output:

1315
Chapter 177. Length of the longest valid substring

Explanation with example:

Input: str = "(()()"

Initialize result as 0 and stack with one item -1.

For i = 0, str[0] = '(', we push 0 in stack

For i = 1, str[1] = '(', we push 1 in stack

For i = 2, str[2] = ')', currently stack has [-1, 0, 1], we pop


from the stack and the stack now is [-1, 0] and length of current
valid substring becomes 2 (we get this 2 by subtracting stack top
from current index).
Since current length is more than current result, we update result.

For i = 3, str[3] = '(', we push again, stack is [-1, 0, 3].

For i = 4, str[4] = ')', we pop from the stack, stack becomes


[-1, 0] and length of current valid substring becomes 4 (we get
this 4 by subtracting stack top from current index).
Since current length is more than current result, we update result.

Thanks to Gaurav Ahirwar and Ekta Goel. for suggesting above approach.

Source

https://www.geeksforgeeks.org/length-of-the-longest-valid-substring/

1316
Chapter 178

Level Ancestor Problem

Level Ancestor Problem - GeeksforGeeks


The level ancestor problem is the problem of preprocessing a given rooted tree T into a data
structure that can determine the ancestor of a given node at a given depth from the root
of the tree. Here depth of any node in a tree is the number of edges on the shortest path
from the root of the tree to the node.
Given tree is represented as un-directed connected graph having n nodes and n-1 edges.
The idea to solve the above query is to use Jump Pointer Algorithm and pre-processes
the tree in O( n log n ) time and answer level ancestor queries in O( logn ) time. In jump
pointer, there is a pointer from node N to N’s j-th ancestor, for
j = 1, 2, 4, 8, …, and so on. We refer to these pointers as JumpN [i], where
Jumpu [i] = LA(N, depth(N) – 2i ).
When the algorithm is asked to process a query, we repeatedly jump up the tree using these
jump pointers. The number of jumps will be at most log n and therefore queries can be
answered in O( logn ) time.
So we store 2i th ancestor of each node and also find the depth of each node from the root
of the tree.
Now our task reduces to find the ( depth(N) – 2i )th ancestor of node N. Let’s denote X as
( depth(N) – 2i ) and let b bits of the X are set bits (1) denoted by s1, s2, s3, …sb.
X = 2(s1) + 2(s2) + … + 2(sb)
Now the problem is how to find 2j ancestors of each node and depth of each node from the
root of the tree?
Initially, we know the 20 th ancestor of each node is its parent. We can recursively compute
2j -th ancestor. We know 2j -th ancestor is 2j-1 -th ancestor of 2j-1 -th ancestor. To calculate
the depth of each node we use the ancestor matrix. If we found the root node present in
the array of the kth element at jth index then the depth of that node is simply 2j but if
root node doesn’t present in the array of ancestors of the kth element than the depth of kth
element is 2( index of last non zero ancestor at kth row ) + depth of ancestor present at last index
of kth row.

1317
Chapter 178. Level Ancestor Problem

Below is the algorithm to fill the ancestor matrix and depth of each node using dynamic
programming. Here, we denote root node as R and initially assume the ancestor of root
node as 0. We also initialize depth array with -1 means the depth of the current node is
not set and we need to find its depth. If the depth of the current node is not equal to -1
means we have already computed its depth.

we know the first ancestor of each node so we take j>=1,


For j>=1

ancstr[k][j] = 2jth ancestor of k


= 2j-1th ancestor of (2j-1th ancestor of k)
= ancstr[ancstr[i][j-1][j-1]
if ancstr[k][j] == R && depth[k] == -1
depth[k] = 2j
else if ancstr[k][j] == -1 && depth[k] == -1
depth[k] = 2(j-1) + depth[ ancstr[k][j-1] ]

Let’s understand this algorithm with below diagram.

In the given figure we need to compute 1st level ancestor of the node with value 8. First,
we make ancestor matrix which stores 2ith ancestor of nodes. Now, 20 ancestor of node 8
is 10 and similarly 20 ancestor of node 10 is 9 and for node 9 it is 1 and for node 1 it is 5.
Based on the above algorithm 1st level ancestor of node 8 is( depth(8)-1 )th ancestor of
node 8. We have pre computed depth of each node and depth of 8 is 5 so we finally need to

1318
Chapter 178. Level Ancestor Problem

find (5-1) = 4th ancestor of node 8 which is equal to 21 th ancestor of [21 ancestor of
node 8] and 21 th ancestor of node 8 is 20 th ancestor of [20 th ancestor of node 8].
So, 20 th ancestor of [20 th ancestor of node 8] is node with value 9 and 21 th ancestor
of node 9 is node with value 5. Thus in this way we can compute all query in O(logn) time
complexity.

// CPP program to implement Level Ancestor Algorithm


#include <bits/stdc++.h>
using namespace std;
int R = 0;
  
// n -> it represent total number of nodes
// len -> it is the maximum length of array to hold 
//          ancestor of each node. In worst case, 
// the highest value of ancestor a node can have is n-1.
// 2 ^ len <= n-1
// len = O(log2n)
int getLen(int n)
{
    return (int)(log(n) / log(2)) + 1;
}
  
// ancstr represents 2D matrix to hold ancestor of node.
// Here we pass reference of 2D matrix so that the change
// made occur directly  to the original matrix
// depth[] stores depth of each node
// len is same as defined above
// n is total nodes in graph
// R represent root node
void setancestor(vector<vector<int> >& ancstr,
           vector<int>& depth, int* node, int len, int n)
{
    // depth of root node is set to 0
    depth[R] = 0;
  
    // if depth of a node is -1 it means its depth 
    // is not set otherwise we have computed its depth
    for (int j = 1; j <= len; j++) {
        for (int i = 0; i < n; i++) {
            ancstr[node[i]][j] = ancstr[ancstr[node[i]][j - 1]][j - 1];
  
            // if ancestor of current node is R its height is
            //  previously not set, then its height is  2^j
            if (ancstr[node[i]][j] == R && depth[node[i]] == -1) {
  
                // set the depth of ith node
                depth[node[i]] = pow(2, j);
            }

1319
Chapter 178. Level Ancestor Problem

  
            // if ancestor of current node is 0 means it 
            // does not have root node at its 2th power 
            // on its path so its depth is 2^(index of 
            // last non zero ancestor means j-1) + depth 
            // of 2^(j-1) th ancestor
            else if (ancstr[node[i]][j] == 0 && 
                     node[i] != R && depth[node[i]] == -1) {
                depth[node[i]] = pow(2, j - 1) + 
                                 depth[ancstr[node[i]][j - 1]];
            }
        }
    }
}
  
// c -> it represent child
// p -> it represent ancestor
// i -> it represent node number
// p=0 means the node is root node
// R represent root node
// here also we pass reference of 2D matrix and depth
// vector so that the change made occur directly to
// the original matrix and original vector
void constructGraph(vector<vector<int> >& ancstr,
            int* node, vector<int>& depth, int* isNode,
                                   int c, int p, int i)
{
    // enter the node in node array
    // it stores all the nodes in the graph
    node[i] = c;
  
    // to confirm that no child node have 2 ancestors
    if (isNode == 0) {
        isNode = 1;
  
        // make ancestor of x as y
        ancstr[0] = p;
  
        // ifits first ancestor is root than its depth is 1
        if (R == p) {
            depth = 1;
        }
    }
    return;
}
  
// this function will delete leaf node
// x is node to be deleted

1320
Chapter 178. Level Ancestor Problem

void removeNode(vector<vector<int> >& ancstr, 


                    int* isNode, int len, int x)
{
    if (isNode[x] == 0)
        cout << "node does not present in graph " << endl;
    else {
        isNode[x] = 0;
  
        // make all ancestor of node x as 0
        for (int j = 0; j <= len; j++) {
            ancstr[x][j] = 0;
        }
    }
    return;
}
  
// x -> it represent new node to be inserted
// p -> it represent ancestor of new node
void addNode(vector<vector<int> >& ancstr,
      vector<int>& depth, int* isNode, int len, 
                                 int x, int p)
{
    if (isNode[x] == 1) {
        cout << " Node is already present in array " << endl;
        return;
    }
    if (isNode[p] == 0) {
        cout << " ancestor not does not present in an array " << endl;
        return;
    }
  
    isNode[x] = 1;
    ancstr[x][0] = p;
  
    // depth of new node is 1 + depth of its ancestor
    depth[x] = depth[p] + 1;
    int j = 0;
  
    // while we don't reach root node
    while (ancstr[x][j] != 0) {
        ancstr[x][j + 1] = ancstr[ancstr[x][j]][j];
        j++;
    }
  
    // remaining array will fill with 0 after 
    // we find root of tree
    while (j <= len) {
        ancstr[x][j] = 0;

1321
Chapter 178. Level Ancestor Problem

        j++;
    }
    return;
}
  
// LA function to find Lth level ancestor of node x
void LA(vector<vector<int> >& ancstr, vector<int> depth, 
                              int* isNode, int x, int L)
{
    int j = 0;
    int temp = x;
  
    // to check if node is present in graph or not
    if (isNode[x] == 0) {
        cout << "Node is not present in graph " << endl;
        return;
    }
  
    // we change L as depth of node x -
    int k = depth[x] - L;
    // int q = k;
    // in this loop we decrease the value of k by k/2 and
    // increment j by 1 after each iteration, and check for set bit
    // if we get set bit then we update x with jth ancestor of x
    // as k becomes less than or equal to zero means we
    // reach to kth level ancestor
    while (k > 0) {
  
        // to check if last bit is 1 or not
        if (k & 1) {
            x = ancstr[x][j];
        }
  
        // use of shift operator to make k = k/2 
        // after every iteration
        k = k >> 1;
        j++;
    }
    cout << L << "th level acestor of node "
               << temp << " is = " << x << endl;
  
    return;
}
  
int main()
{
    // n represent number of nodes
    int n = 12;

1322
Chapter 178. Level Ancestor Problem

  
    // initialization of ancestor matrix
    // suppose max range of node is up to 1000
    // if there are 1000 nodes than also length 
    // of ancestor matrix will not exceed 10
    vector<vector<int> > ancestor(1000, vector<int>(10));
  
    // this vector is used to store depth of each node.
    vector<int> depth(1000);
  
    // fill function is used to initialize depth with -1
    fill(depth.begin(), depth.end(), -1);
  
    // node array is used to store all nodes
    int* node = new int[1000];
  
    // isNode is an array to check whether a
    // node is present in graph or not
    int* isNode = new int[1000];
  
    // memset function to initialize isNode array with 0
    memset(isNode, 0, 1000 * sizeof(int));
  
    // function to calculate len
    // len -> it is the maximum length of array to 
    // hold ancestor of each node.
    int len = getLen(n);
  
    // R stores root node
    R = 2;
  
    // construction of graph
    // here 0 represent that the node is root node
    constructGraph(ancestor, node, depth, isNode, 2, 0, 0);
    constructGraph(ancestor, node, depth, isNode, 5, 2, 1);
    constructGraph(ancestor, node, depth, isNode, 3, 5, 2);
    constructGraph(ancestor, node, depth, isNode, 4, 5, 3);
    constructGraph(ancestor, node, depth, isNode, 1, 5, 4);
    constructGraph(ancestor, node, depth, isNode, 7, 1, 5);
    constructGraph(ancestor, node, depth, isNode, 9, 1, 6);
    constructGraph(ancestor, node, depth, isNode, 10, 9, 7);
    constructGraph(ancestor, node, depth, isNode, 11, 10, 8);
    constructGraph(ancestor, node, depth, isNode, 6, 10, 9);
    constructGraph(ancestor, node, depth, isNode, 8, 10, 10);
  
    // function to pre compute ancestor matrix
    setancestor(ancestor, depth, node, len, n);
  

1323
Chapter 178. Level Ancestor Problem

    // query to get 1st level ancestor of node 8


    LA(ancestor, depth, isNode, 8, 1);
  
    // add node 12 and its ancestor is 8
    addNode(ancestor, depth, isNode, len, 12, 8);
  
    // query to get 2nd level ancestor of node 12
    LA(ancestor, depth, isNode, 12, 2);
  
    // delete node 12
    removeNode(ancestor, isNode, len, 12);
  
    // query to get 5th level ancestor of node
    // 12 after deletion of node
    LA(ancestor, depth, isNode, 12, 1);
  
    return 0;
}

Output:

1th level acestor of node 8 is = 5


2th level acestor of node 12 is = 1
Node is not present in graph

Source

https://www.geeksforgeeks.org/level-ancestor-problem/

1324
Chapter 179

Lobb Number

Lobb Number - GeeksforGeeks


In combinatorial mathematics, the Lobb number Lm, n counts the number of ways that n
+ m open parentheses can be arranged to form the start of a valid sequence of balanced
parentheses.
The Lobb number are parameterized by two non-negative integers m and n with n >= m
>= 0. It can be obtained by:

Lobb Number is also used to count the number of ways in which n + m copies of the value
+1 and n – m copies of the value -1 may be arranged into a sequence such that all of the
partial sums of the sequence are non- negative.
Examples :

Input : n = 3, m = 2
Output : 5

Input : n =5, m =3
Output :35

The idea is simple, we use a function that computes binomial coefficients for given values.
Using this function and above formula, we can compute Lobb numbers.

C++

// CPP Program to find Ln, m Lobb Number.


#include <bits/stdc++.h>
#define MAXN 109
using namespace std;

1325
Chapter 179. Lobb Number

  
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    int C[n + 1][k + 1];
  
    // Calculate value of Binomial Coefficient in
    // bottom up manner
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= min(i, k); j++) {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
  
            // Calculate value using previously stored values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
  
    return C[n][k];
}
  
// Return the Lm, n Lobb Number.
int lobb(int n, int m)
{
    return ((2 * m + 1) * binomialCoeff(2 * n, m + n)) / (m + n + 1);
}
  
// Driven Program
int main()
{
    int n = 5, m = 3;
    cout << lobb(n, m) << endl;
    return 0;
}

Java

// JAVA Code For Lobb Number


import java.util.*;
  
class GFG {
      
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {

1326
Chapter 179. Lobb Number

        int C[][] = new int[n + 1][k + 1];


       
        // Calculate value of Binomial 
        // Coefficient in bottom up manner
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= Math.min(i, k);
                                        j++) {
                // Base Cases
                if (j == 0 || j == i)
                    C[i][j] = 1;
       
                // Calculate value using 
                // previously stored values
                else
                    C[i][j] = C[i - 1][j - 1] +
                              C[i - 1][j];
            }
        }
       
        return C[n][k];
    }
      
    // Return the Lm, n Lobb Number.
    static int lobb(int n, int m)
    {
        return ((2 * m + 1) * binomialCoeff(2 * n, m + n)) / 
                                             (m + n + 1);
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int n = 5, m = 3;
        System.out.println(lobb(n, m));
          
    }
}
  
// This code is contributed by Arnav Kr. Mandal.

Python 3

# Python 3 Program to find Ln, 


# m Lobb Number.
  
# Returns value of Binomial
# Coefficient C(n, k)
def binomialCoeff(n, k):

1327
Chapter 179. Lobb Number

  
    C = [[0 for j in range(k + 1)] 
             for i in range(n + 1)]
  
  
    # Calculate value of Binomial 
    # Coefficient in bottom up manner
    for i in range(0, n + 1): 
        for j in range(0, min(i, k) + 1): 
            # Base Cases
            if (j == 0 or j == i):
                C[i][j] = 1
  
            # Calculate value using 
            # previously stored values
            else:
                C[i][j] = (C[i - 1][j - 1] 
                            + C[i - 1][j])
          
    return C[n][k]
  
# Return the Lm, n Lobb Number.
def lobb(n, m):
  
    return (((2 * m + 1) * 
        binomialCoeff(2 * n, m + n)) 
                      / (m + n + 1))
  
# Driven Program
n = 5
m = 3
print(int(lobb(n, m)))
  
# This code is contributed by
# Smitha Dinesh Semwal

C#

// C# Code For Lobb Number


using System;
  
class GFG {
  
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {
          

1328
Chapter 179. Lobb Number

        int[, ] C = new int[n + 1, k + 1];


  
        // Calculate value of Binomial
        // Coefficient in bottom up manner
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= Math.Min(i, k);
                j++) {
                      
                // Base Cases
                if (j == 0 || j == i)
                    C[i, j] = 1;
  
                // Calculate value using
                // previously stored values
                else
                    C[i, j] = C[i - 1, j - 1] 
                                + C[i - 1, j];
            }
        }
  
        return C[n, k];
    }
  
    // Return the Lm, n Lobb Number.
    static int lobb(int n, int m)
    {
        return ((2 * m + 1) * binomialCoeff(
                 2 * n, m + n)) / (m + n + 1);
    }
  
    /* Driver program to test above function */
    public static void Main()
    {
        int n = 5, m = 3;
          
        Console.WriteLine(lobb(n, m));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program to find Ln,
// m Lobb Number.
  
$MAXN =109;

1329
Chapter 179. Lobb Number

  
// Returns value of Binomial 
// Coefficient C(n, k)
function binomialCoeff($n, $k)
{
    $C= array(array());
  
    // Calculate value of Binomial
    // Coefficient in bottom up manner
    for ($i = 0; $i <= $n; $i++) 
    {
        for ($j = 0; $j <= min($i, $k); $j++) 
        {
            // Base Cases
            if ($j == 0 || $j == $i)
                $C[$i][$j] = 1;
  
            // Calculate value using p
            // reviously stored values
            else
                $C[$i][$j] = $C[$i - 1][$j - 1] + 
                             $C[$i - 1][$j];
        }
    }
  
    return $C[$n][$k];
}
  
// Return the Lm, n Lobb Number.
function lobb($n, int $m)
{
    return ((2 * $m + 1) * 
             binomialCoeff(2 * $n, $m + $n)) / 
                          ($m + $n + 1);
}
  
// Driven Code
$n = 5;$m = 3;
echo lobb($n, $m);
  
// This code is contributed by anuj_67.
?>

Output :

35

Improved By : Smitha Dinesh Semwal, vt_m, RajatRaj

1330
Chapter 179. Lobb Number

Source

https://www.geeksforgeeks.org/lobb-number/

1331
Chapter 180

Longest Common Substring


(Space optimized DP solution)

Longest Common Substring (Space optimized DP solution) - GeeksforGeeks


Given two strings ‘X’ and ‘Y’, find the length of longest common substring. Expected space
complexity is linear.
Examples :

Input : X = "GeeksforGeeks", Y = "GeeksQuiz"


Output : 5
The longest common substring is "Geeks" and is of
length 5.

Input : X = "abcdxyz", Y = "xyzabcd"


Output : 4
The longest common substring is "abcd" and is of
length 4.

1332
Chapter 180. Longest Common Substring (Space optimized DP solution)

We have discussed Dynamic programming based solution for Longest common substring.
The auxiliary space used by the solution is O(m*n), where m and n are lengths of string X
and Y. The space used by solution can be reduced to O(2*n).
Suppose we are at position mat[i][j]. Now if X[i-1] == Y[j-1], then we add the value of
mat[i-1][j-1] to our result. That is we add value from previous row and value for all other
rows below the previous row are never used. So, at a time we are using only two consecutive
rows. This observation can be used to reduce the space required to find length of longest
common substring.
Instead of creating a matrix of size m*n, we create a matrix of size 2*n. A variable currRow
is used to represent that either row 0 or row 1 of this matrix is currently used to find
length. Initially row 0 is used as current row for the case when length of string X is zero.
At the end of each iteration, current row is made previous row and previous row is made
new current row.

C++

// Space optimized CPP implementation of longest


// common substring.
#include <bits/stdc++.h>
using namespace std;
  
// Function to find longest common substring.
int LCSubStr(string X, string Y)
{
    // Find length of both the strings.
    int m = X.length();
    int n = Y.length();
  

1333
Chapter 180. Longest Common Substring (Space optimized DP solution)

    // Variable to store length of longest


    // common substring.
    int result = 0;
  
    // Matrix to store result of two
    // consecutive rows at a time.
    int len[2][n];
  
    // Variable to represent which row of
    // matrix is current row.
    int currRow = 0;
  
    // For a particular value of i and j,
    // len[currRow][j] stores length of longest
    // common substring in string X[0..i] and Y[0..j].
    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            if (i == 0 || j == 0) {
                len[currRow][j] = 0;
            }
            else if (X[i - 1] == Y[j - 1]) {
                len[currRow][j] = len[1 - currRow][j - 1] + 1;
                result = max(result, len[currRow][j]);
            }
            else {
                len[currRow][j] = 0;
            }
        }
  
        // Make current row as previous row and previous
        // row as new current row.
        currRow = 1 - currRow;
    }
  
    return result;
}
  
int main()
{
    string X = "GeeksforGeeks";
    string Y = "GeeksQuiz";
  
    cout << LCSubStr(X, Y);
    return 0;
}

Java

1334
Chapter 180. Longest Common Substring (Space optimized DP solution)

// Space optimized CPP implementation of 


// longest common substring.
import java.io.*;
import java.util.*;
  
public class GFG {
      
    // Function to find longest
    // common substring.
    static int LCSubStr(String X, String Y)
    {
          
        // Find length of both the strings.
        int m = X.length();
        int n = Y.length();
      
        // Variable to store length of longest
        // common substring.
        int result = 0;
      
        // Matrix to store result of two
        // consecutive rows at a time.
        int [][]len = new int[2][n];
      
        // Variable to represent which row of
        // matrix is current row.
        int currRow = 0;
      
        // For a particular value of
        // i and j, len[currRow][j] 
        // stores length of longest
        // common substring in string
        // X[0..i] and Y[0..j].
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (i == 0 || j == 0) {
                    len[currRow][j] = 0;
                }
                else if (X.charAt(i - 1) == 
                              Y.charAt(j - 1))
                {
                    len[currRow][j] =
                      len[(1 - currRow)][(j - 1)]
                                             + 1;
                    result = Math.max(result, 
                                len[currRow][j]);
                }
                else

1335
Chapter 180. Longest Common Substring (Space optimized DP solution)

                {
                    len[currRow][j] = 0;
                }
            }
      
            // Make current row as previous
            // row and previous row as 
            // new current row.
            currRow = 1 - currRow;
        }
      
        return result;
    }
      
    // Driver Code
    public static void main(String args[])
    {
        String X = "GeeksforGeeks";
        String Y = "GeeksQuiz";
      
        System.out.print(LCSubStr(X, Y));
    }
}
  
// This code is contributed by 
// Manish Shaw (manishshaw1)

C#

// Space optimized C# implementation


// of longest common substring.
using System;
using System.Collections.Generic;
class GFG {
      
    // Function to find longest
    // common substring.
    static int LCSubStr(string X, string Y)
    {
          
        // Find length of both the strings.
        int m = X.Length;
        int n = Y.Length;
      
        // Variable to store length of longest
        // common substring.
        int result = 0;
      

1336
Chapter 180. Longest Common Substring (Space optimized DP solution)

        // Matrix to store result of two


        // consecutive rows at a time.
        int [,]len = new int[2,n];
      
        // Variable to represent which row of
        // matrix is current row.
        int currRow = 0;
      
        // For a particular value of
        // i and j, len[currRow][j] 
        // stores length of longest
        // common substring in string
        // X[0..i] and Y[0..j].
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (i == 0 || j == 0) {
                    len[currRow,j] = 0;
                }
                else if (X[i - 1] == Y[j - 1]) {
                    len[currRow,j] = len[(1 - currRow), 
                                          (j - 1)] + 1;
                    result = Math.Max(result, len[currRow, j]);
                }
                else 
                {
                    len[currRow,j] = 0;
                }
            }
      
            // Make current row as previous
            // row and previous row as 
            // new current row.
            currRow = 1 - currRow;
        }
      
        return result;
    }
      
      
    // Driver Code
    public static void Main()
    {
        string X = "GeeksforGeeks";
        string Y = "GeeksQuiz";
      
        Console.Write(LCSubStr(X, Y));
    }
}

1337
Chapter 180. Longest Common Substring (Space optimized DP solution)

  
// This code is contributed by 
// Manish Shaw (manishshaw1)

PHP

<?php
// Space optimized PHP implementation 
// of longest common substring.
  
// Function to find 
// longest common substring.
function LCSubStr($X, $Y)
{
    // Find length of
    // both the strings.
    $m = strlen($X);
    $n = strlen($Y);
  
    // Variable to store length 
    // of longest common substring.
    $result = 0;
  
    // Matrix to store result of two
    // consecutive rows at a time.
    $len = array(array(), array(), );
  
    // Variable to represent which 
    // row of matrix is current row.
    $currRow = 0;
  
    // For a particular value of 
    // i and j, len[currRow][j] 
    // stores length of longest 
    // common substring in string 
    // X[0..i] and Y[0..j].
    for ($i = 0; $i <= $m; $i++) 
    {
        for ($j = 0; $j <= $n; $j++) 
        {
            if ($i == 0 || $j == 0) 
            {
                $len[$currRow][$j] = 0;
            }
            else if ($X[$i - 1] == $Y[$j - 1]) 
            {
                $len[$currRow][$j] = 
                        $len[1 - $currRow][$j - 1] + 1;

1338
Chapter 180. Longest Common Substring (Space optimized DP solution)

                  
                $result = max($result, 
                              $len[$currRow][$j]);
            }
            else 
            {
                $len[$currRow][$j] = 0;
            }
        }
  
        // Make current row as 
        // previous row and previous
        // row as new current row.
        $currRow = 1 - $currRow;
    }
  
    return $result;
}
  
// Driver Code
$X = "GeeksforGeeks";
$Y = "GeeksQuiz";
  
print (LCSubStr($X, $Y));
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

Output :

Time Complexity: O(m*n)


Auxiliary Space: O(n)
Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/longest-common-substring-space-optimized-dp-solution/

1339
Chapter 181

Longest Common Increasing


Subsequence (LCS + LIS)

Longest Common Increasing Subsequence (LCS + LIS) - GeeksforGeeks


Prerequisites : LCS, LIS
Given two arrays, find length of the longest common increasing subsequence [LCIS] and
print one of such sequences (multiple sequences may exist)
Suppose we consider two arrays –
arr1[] = {3, 4, 9, 1} and
arr2[] = {5, 3, 8, 9, 10, 2, 1}
Our answer would be {3, 9} as this is the longest common subsequence which is increasing
also.
The idea is to use dynamic programming here as well. We store the longest common in-
creasing sub-sequence ending at each index of arr2[]. We create an auxiliary array table[]
such that table[j] stores length of LCIS ending with arr2[j]. At the end, we return maximum
value from this table. For filling values in this table, we traverse all elements of arr1[] and
for every element arr1[i], we traverse all elements of arr2[]. If we find a match, we update
table[j] with length of current LCIS. To maintain current LCIS, we keep checking valid
table[j] values.
Below is the program to find length of LCIS.

C++

// A C++ Program to find length of the Longest Common


// Increasing Subsequence (LCIS)
#include<bits/stdc++.h>
using namespace std;
  

1340
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

// Returns the length and the LCIS of two


// arrays arr1[0..n-1] and arr2[0..m-1]
int LCIS(int arr1[], int n, int arr2[], int m)
{
    // table[j] is going to store length of LCIS
    // ending with arr2[j]. We initialize it as 0,
    int table[m];
    for (int j=0; j<m; j++)
        table[j] = 0;
  
    // Traverse all elements of arr1[]
    for (int i=0; i<n; i++)
    {
        // Initialize current length of LCIS
        int current = 0;
  
        // For each element of arr1[], traverse all
        // elements of arr2[].
        for (int j=0; j<m; j++)
        {
            // If both the array have same elements.
            // Note that we don't break the loop here.
            if (arr1[i] == arr2[j])
                if (current + 1 > table[j])
                    table[j] = current + 1;
  
            /* Now seek for previous smaller common
               element for current element of arr1 */
            if (arr1[i] > arr2[j])
                if (table[j] > current)
                    current = table[j];
        }
    }
  
    // The maximum value in table[] is out result
    int result = 0;
    for (int i=0; i<m; i++)
        if (table[i] > result)
           result = table[i];
  
    return result;
}
  
/* Driver program to test above function */
int main()
{
    int arr1[] = {3, 4, 9, 1};
    int arr2[] = {5, 3, 8, 9, 10, 2, 1};

1341
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

  
    int n = sizeof(arr1)/sizeof(arr1[0]);
    int m = sizeof(arr2)/sizeof(arr2[0]);
  
    cout << "Length of LCIS is "
         << LCIS(arr1, n, arr2, m);
    return (0);
}

Java

// A Java Program to find length of the Longest


// Common Increasing Subsequence (LCIS)
import java.io.*;
  
class GFG {
  
    // Returns the length and the LCIS of two
    // arrays arr1[0..n-1] and arr2[0..m-1]
    static int LCIS(int arr1[], int n, int arr2[],
                                         int m)
    {
        // table[j] is going to store length of 
        // LCIS ending with arr2[j]. We initialize
        // it as 0,
        int table[] = new int[m];
        for (int j = 0; j < m; j++)
            table[j] = 0;
  
        // Traverse all elements of arr1[]
        for (int i = 0; i < n; i++)
        {
            // Initialize current length of LCIS
            int current = 0;
  
            // For each element of arr1[], trvarse 
            // all elements of arr2[].
            for (int j = 0; j < m; j++)
            {
                // If both the array have same 
                // elements. Note that we don't
                // break the loop here.
                if (arr1[i] == arr2[j])
                    if (current + 1 > table[j])
                        table[j] = current + 1;
  
                /* Now seek for previous smaller
                common element for current 

1342
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

                element of arr1 */
                if (arr1[i] > arr2[j])
                    if (table[j] > current)
                        current = table[j];
            }
        }
  
        // The maximum value in table[] is out
        // result
        int result = 0;
        for (int i=0; i<m; i++)
            if (table[i] > result)
            result = table[i];
  
        return result;
    }
  
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        int arr1[] = {3, 4, 9, 1};
        int arr2[] = {5, 3, 8, 9, 10, 2, 1};
  
        int n = arr1.length;
        int m = arr2.length;
  
    System.out.println("Length of LCIS is " +
                       LCIS(arr1, n, arr2, m));
    }
}
// This code is contributed by Prerna Saini

C#

// A C# Program to find length of the Longest


// Common Increasing Subsequence (LCIS)
using System;
  
class GFG {
  
    // Returns the length and the LCIS of two
    // arrays arr1[0..n-1] and arr2[0..m-1]
    static int LCIS(int []arr1, int n,
                    int []arr2, int m)
    {
        // table[j] is going to store length of 
        // LCIS ending with arr2[j]. We initialize
        // it as 0,

1343
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

        int []table = new int[m];


        for (int j = 0; j < m; j++)
            table[j] = 0;
  
        // Traverse all elements of arr1[]
        for (int i = 0; i < n; i++)
        {
            // Initialize current length of LCIS
            int current = 0;
  
            // For each element of arr1[], trvarse 
            // all elements of arr2[].
            for (int j = 0; j < m; j++)
            {
                // If both the array have same 
                // elements. Note that we don't
                // break the loop here.
                if (arr1[i] == arr2[j])
                    if (current + 1 > table[j])
                        table[j] = current + 1;
  
                /* Now seek for previous smaller
                   common element for current 
                   element of arr1 */
                if (arr1[i] > arr2[j])
                    if (table[j] > current)
                        current = table[j];
            }
        }
  
        // The maximum value in 
        // table[] is out result
        int result = 0;
        for (int i = 0; i < m; i++)
            if (table[i] > result)
            result = table[i];
  
        return result;
    }
  
    /* Driver program to test above function */
    public static void Main()
    {
        int []arr1 = {3, 4, 9, 1};
        int []arr2 = {5, 3, 8, 9, 10, 2, 1};
  
        int n = arr1.Length;
        int m = arr2.Length;

1344
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

  
    Console.Write("Length of LCIS is " +
                   LCIS(arr1, n, arr2, m));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP Program to find length of
// the Longest Common Increasing 
// Subsequence (LCIS)
  
// Returns the length and the LCIS 
// of two arrays arr1[0..n-1] and 
// arr2[0..m-1]
function LCIS($arr1, $n, $arr2, $m)
{
    // table[j] is going to store 
    // length of LCIS ending with 
    // arr2[j]. We initialize it as 0,
      
    $table = Array();
      
    //int table[m];
    for ($j = 0; $j < $m; $j++)
        $table[$j] = 0;
  
    // Traverse all elements of arr1[]
    for ($i = 0; $i < $n; $i++)
    {
        // Initialize current
        // length of LCIS
        $current = 0;
  
        // For each element of 
        // arr1[], trvarse all
        // elements of arr2[].
        for ($j = 0; $j < $m; $j++)
        {
            // If both the array have 
            // same elements. Note that
            // we don't break the loop here.
            if ($arr1[$i] == $arr2[$j])
                if ($current + 1 > $table[$j])
                    $table[$j] = $current + 1;

1345
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

  
            /* Now seek for previous smaller 
            common element for current 
            element of arr1 */
            if ($arr1[$i] > $arr2[$j])
                if ($table[$j] > $current)
                    $current = $table[$j];
        }
    }
  
    // The maximum value in 
    // table[] is out result
    $result = 0;
    for ($i = 0; $i < $m; $i++)
        if ($table[$i] > $result)
        $result = $table[$i];
  
    return $result;
}
  
// Driver Code
$arr1 = array (3, 4, 9, 1);
$arr2 = array (5, 3, 8, 9, 10, 2, 1);
  
$n = sizeof($arr1);
$m = sizeof($arr2);
  
echo "Length of LCIS is ",
       LCIS($arr1, $n, $arr2, $m);
  
// This code is contributed by ajit 
?>

Output :

Length of LCIS is 2

How to print a LCIS?


To print the longest common increasing subsequence we keep track of the parent of each
element in the longest common increasing subsequence.

C++

// A C++ Program to find length of the Longest Common


// Increasing Subsequence (LCIS)
#include<bits/stdc++.h>

1346
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

using namespace std;


  
// Returns the length and the LCIS of two
// arrays arr1[0..n-1] and arr2[0..m-1] and
// prints LCIS
int LCIS(int arr1[], int n, int arr2[], int m)
{
    // table[j] is going to store length of LCIS
    // ending with arr2[j]. We initialize it as 0,
    int table[m], parent[m];
    for (int j=0; j<m; j++)
        table[j] = 0;
  
    // Traverse all elements of arr1[]
    for (int i=0; i<n; i++)
    {
        // Initialize current length of LCIS
        int current = 0, last = -1;
  
        // For each element of arr1[], trvarse all
        // elements of arr2[].
        for (int j=0; j<m; j++)
        {
            // If both the array have same elements.
            // Note that we don't break the loop here.
            if (arr1[i] == arr2[j])
            {
                if (current + 1 > table[j])
                {
                    table[j] = current + 1;
                    parent[j] = last;
                }
            }
  
            /* Now seek for previous smaller common
               element for current element of arr1 */
            if (arr1[i] > arr2[j])
            {
                if (table[j] > current)
                {
                    current = table[j];
                    last = j;
                }
            }
        }
    }
  
    // The maximum value in table[] is out result

1347
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

    int result = 0, index = -1;


    for (int i=0; i<m; i++)
    {
        if (table[i] > result)
        {
           result = table[i];
           index = i;
        }
    }
  
    // LCIS is going to store elements of LCIS
    int lcis[result];
    for (int i=0; index != -1; i++)
    {
        lcis[i] = arr2[index];
        index = parent[index];
    }
  
    cout << "The LCIS is : ";
    for (int i=result-1; i>=0; i--)
        printf ("%d ", lcis[i]);
  
    return result;
}
  
/* Driver program to test above function */
int main()
{
    int arr1[] = {3, 4, 9, 1};
    int arr2[] = {5, 3, 8, 9, 10, 2, 1};
  
    int n = sizeof(arr1)/sizeof(arr1[0]);
    int m = sizeof(arr2)/sizeof(arr2[0]);
  
    cout << "\nLength of LCIS is "
         << LCIS(arr1, n, arr2, m);
    return (0);
}

Java

// Java Program to find length of the Longest


// Common Increasing Subsequence (LCIS)
import java.io.*;
  
class GFG {
  
    // Returns the length and the LCIS of

1348
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

    // two arrays arr1[0..n-1] and arr2[0..m-1]


    // and prints LCIS
    static int LCIS(int arr1[], int n, int arr2[],
                                         int m)
    {   
        // table[j] is going to store length of 
        // LCIS ending with arr2[j]. We 
        // initialize it as 0.
        int table[] = new int[m];
        int parent[] = new int[m];
        for (int j = 0; j < m; j++)
            table[j] = 0;
  
        // Traverse all elements of arr1[]
        for (int i = 0; i < n; i++)
        {
            // Initialize current length of LCIS
            int current = 0, last = -1;
  
            // For each element of arr1[],
            // trvarse all elements of arr2[].
            for (int j = 0; j < m; j++)
            {
                // If both the array have same
                // elements. Note that we don't 
                // break the loop here.
                if (arr1[i] == arr2[j])
                {   
                    if (current + 1 > table[j])
                    {
                        table[j] = current + 1;
                        parent[j] = last;
                    }
                }
  
                /* Now seek for previous smaller
                common element for current element
                of arr1 */
                if (arr1[i] > arr2[j])
                {
                    if (table[j] > current)
                    {
                        current = table[j];
                        last = j;
                    }
                }
            }
        }

1349
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

  
        // The maximum value in table[] is out
        // result
        int result = 0, index = -1;
        for (int i = 0; i < m; i++)
        {
            if (table[i] > result)
            {
            result = table[i];
            index = i;
            }
        }
  
        // LCIS is going to store elements 
        // of LCIS
        int lcis[] = new int[result];
        for (int i = 0; index != -1; i++)
        {
            lcis[i] = arr2[index];
            index = parent[index];
        }
  
        System.out.print("The LCIS is : ");
        for (int i = result - 1; i >= 0; i--)
            System.out.print(lcis[i] + " ");
      
        return result;
    }
  
    /* Driver program to test above function */ 
    public static void main(String[] args)
    {
        int arr1[] = {3, 4, 9, 1};
        int arr2[] = {5, 3, 8, 9, 10, 2, 1};
  
        int n = arr1.length;
        int m = arr2.length;
  
        System.out.println("\nLength of LCIS is "+
                          LCIS(arr1, n, arr2, m));
    }
}
// This code is contributed by Prerna Saini

C#

// C# Program to find length 


// of the Longest Common 

1350
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

// Increasing Subsequence (LCIS)


using System;
  
class GFG
{
  
// Returns the length and
// the LCIS of two arrays
// arr1[0..n-1] and arr2[0..m-1]
// and prints LCIS
static int LCIS(int []arr1, int n, 
                int []arr2, int m)

    // table[j] is going to store 
    // length of LCIS ending with 
    // arr2[j]. We initialize it as 0.
    int []table = new int[m];
    int []parent = new int[m];
    for (int j = 0; j < m; j++)
        table[j] = 0;
  
    // Traverse all elements of arr1[]
    for (int i = 0; i < n; i++)
    {
        // Initialize current
        // length of LCIS
        int current = 0, last = -1;
  
        // For each element of arr1[],
        // trvarse all elements of arr2[].
        for (int j = 0; j < m; j++)
        {
            // If both the array have same
            // elements. Note that we don't 
            // break the loop here.
            if (arr1[i] == arr2[j])
            { 
                if (current + 1 > table[j])
                {
                    table[j] = current + 1;
                    parent[j] = last;
                }
            }
  
            /* Now seek for previous 
            smaller common element for 
            current element of arr1 */
            if (arr1[i] > arr2[j])

1351
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

            {
                if (table[j] > current)
                {
                    current = table[j];
                    last = j;
                }
            }
        }
    }
  
    // The maximum value in 
    // table[] is out result
    int result = 0, index = -1;
    for (int i = 0; i < m; i++)
    {
        if (table[i] > result)
        {
        result = table[i];
        index = i;
        }
    }
  
    // LCIS is going to store 
    // elements of LCIS
    int []lcis = new int[result];
    for (int i = 0; index != -1; i++)
    {
        lcis[i] = arr2[index];
        index = parent[index];
    }
  
    Console.Write("The LCIS is : ");
    for (int i = result - 1; i >= 0; i--)
    Console.Write(lcis[i] + " ");
  
    return result;
}
  
// Driver Code    
static public void Main ()
{
    int []arr1 = {3, 4, 9, 1};
    int []arr2 = {5, 3, 8, 9, 
                  10, 2, 1};
  
    int n = arr1.Length;
    int m = arr2.Length;
  

1352
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

    Console.WriteLine("\nLength of LCIS is "+


                     LCIS(arr1, n, arr2, m));
  
}
}
  
// This code is contributed by ajit

PHP

<?php
// A PHP Program to find 
// length of the Longest
// Common Increasing 
// Subsequence (LCIS)
  
// Returns the length and 
// the LCIS of two arrays 
// arr1[0..n-1] and 
// arr2[0..m-1] and prints LCIS
  
function LCIS($arr1, $n, 
              $arr2, $m)
{
    // table[j] is going to
    // store length of LCIS
    // ending with arr2[j].
    // We initialize it as 0,
      
    $table = Array(); $parent = Array();
    for ($j = 0; $j < $m; $j++)
        $table[$j] = 0;
  
    // Traverse all
    // elements of arr1[]
    for ($i = 0 ; $i < $n; $i++)
    {
        // Initialize current
        // length of LCIS
        $current = 0; $last = -1;
  
        // For each element of
        // arr1[], trvarse all
        // elements of arr2[].
        for ($j = 0; $j < $m; $j++)
        {
            // If both the array have
            // same elements. Note that 

1353
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

            // we don't break the loop here.


            if ($arr1[$i] == $arr2[$j])
            {
                if ($current + 1 > $table[$j])
                {
                    $table[$j] = $current + 1;
                    $parent[$j] = $last;
                }
            }
  
            /* Now seek for previous 
            smaller common element for
            current element of arr1 */
            if ($arr1[$i] > $arr2[$j])
            {
                if ($table[$j] > $current)
                {
                    $current = $table[$j];
                    $last = $j;
                }
            }
        }
    }
  
    // The maximum value in
    // table[] is out result
    $result = 0; $index = -1;
    for ($i =0 ; $i < $m; $i++)
    {
        if ($table[$i] > $result)
        {
        $result = $table[$i];
        $index = $i;
        }
    }
  
    // LCIS is going to store 
    // elements of LCIS 
    // $lcis[$result];
    for ($i = 0; $index != -1; $i++)
    {
        $lcis[$i] = $arr2[$index];
        $index = $parent[$index];
    }
  
    echo "The LCIS is : ";
    for ($i = $result - 1; $i >= 0; $i--)
        echo $lcis[$i], " ";

1354
Chapter 181. Longest Common Increasing Subsequence (LCS + LIS)

        echo " \n";


      
    return $result;
}
  
// Driver Code
$arr1 = array (3, 4, 9, 1);
$arr2 = array (5, 3, 8, 9, 10, 2, 1);
  
$n = sizeof($arr1);
$m = sizeof($arr2);
$x = LCIS($arr1, $n, $arr2, $m);
  
echo "Length of LCIS is ", $x;
      
// This code is contributed by m_kit
?>

Output :

The LCIS is : 3 9
Length of LCIS is 2

Time Complexity : O(m*n)


Auxiliary Space : O(m)
Improved By : nitin mittal, jit_t, AyanBanerjee

Source

https://www.geeksforgeeks.org/longest-common-increasing-subsequence-lcs-lis/

1355
Chapter 182

Longest Common Subsequence


with at most k changes allowed

Longest Common Subsequence with at most k changes allowed - GeeksforGeeks


Given two sequence P and Q of numbers. The task is to find Longest Common Subsequence
of two sequence if we are allowed to change at most k element in first sequence to any value.
Examples:

Input : P = { 8, 3 }
Q = { 1, 3 }
K = 1
Output : 2
If we change first element of first
sequence from 8 to 1, both sequences
become same.

Input : P = { 1, 2, 3, 4, 5 }
Q = { 5, 3, 1, 4, 2 }
K = 1
Output : 3
By changing first element of first
sequence to 5 to get the LCS ( 5, 3, 4 }.

The idea is to use Dynamic Programming. Define a 3D matrix dp[][][], where dp[i][j][k]
defines the Longest Common Subsequence for the first i numbers of first array, first j number
of second array when we are allowed to change at max k number in the first array.
Therefore, recursion will look like

1356
Chapter 182. Longest Common Subsequence with at most k changes allowed

If P[i] != Q[j],
dp[i][j][k] = max(dp[i - 1][j][k],
dp[i][j - 1][k],
dp[i - 1][j - 1][k - 1] + 1)
If P[i] == Q[j],
dp[i][j][k] = max(dp[i - 1][j][k],
dp[i][j - 1][k],
dp[i - 1][j - 1][k] + 1)

Below is C++ implementation of this approach:

// CPP program to find LCS of two arrays with


// k changes allowed in first array.
#include <bits/stdc++.h>
using namespace std;
#define MAX 10
  
// Return LCS with at most k changes allowed.
int lcs(int dp[MAX][MAX][MAX], int arr1[], int n,
                       int arr2[], int m, int k)
{
    // If at most changes is less than 0.
    if (k < 0)
        return -1e7;
  
    // If any of two array is over.
    if (n < 0 || m < 0)
        return 0;
  
    // Making a reference variable to dp[n][m][k]
    int& ans = dp[n][m][k];
  
    // If value is already calculated, return
    // that value.
    if (ans != -1)
        return ans;
  
    // calculating LCS with no changes made.
    ans = max(lcs(dp, arr1, n - 1, arr2, m, k), 
              lcs(dp, arr1, n, arr2, m - 1, k));
  
    // calculating LCS when array element are same.
    if (arr1[n] == arr2[m])
        ans = max(ans, 1 + lcs(dp, arr1, n - 1, 
                                arr2, m - 1, k));
  
    // calculating LCS with changes made.
    ans = max(ans, 1 + lcs(dp, arr1, n - 1, 

1357
Chapter 182. Longest Common Subsequence with at most k changes allowed

                          arr2, m - 1, k - 1));
  
    return ans;
}
  
// Driven Program
int main()
{
    int k = 1;
    int arr1[] = { 1, 2, 3, 4, 5 };
    int arr2[] = { 5, 3, 1, 4, 2 };
    int n = sizeof(arr1) / sizeof(arr1[0]);
    int m = sizeof(arr2) / sizeof(arr2[0]);
  
    int dp[MAX][MAX][MAX];
    memset(dp, -1, sizeof(dp));
  
    cout << lcs(dp, arr1, n, arr2, m, k) << endl;
  
    return 0;
}

Output:

Time Complexity: O(N*M*K).

Source

https://www.geeksforgeeks.org/longest-common-subsequence-with-at-most-k-changes-allowed/

1358
Chapter 183

Longest Common Subsequence |


DP using Memoization

Longest Common Subsequence | DP using Memoization - GeeksforGeeks


Given two strings s1 and s2, the task is to find the length of longest common subsequence
present in both of them.
Examples:

Input: s1 = “ABCDGH”, s2 = “AEDFHR”


Output: 3
LCS for input Sequences “AGGTAB” and “GXTXAYB” is “GTAB” of length
4.
Input: s1 = “striver”, s2 = “raj”
Output: 1

The naive solution for this problem is to generate all subsequences of both given sequences
and find the longest matching subsequence. This solution is exponential in term of time com-
plexity. The general recursive solution of the problem is to generate all subsequences of both
given sequences and find the longest matching subsequence. Total possible combinations
will be 2n . Hence recursive solution will take O(2n ).
Optimal Substructure:

• Let the input sequences be X[0..m-1] and Y[0..n-1] of lengths m and n respectively.
And let L(X[0..m-1], Y[0..n-1]) be the length of LCS of the two sequences X and Y.
Following is the recursive definition of L(X[0..m-1], Y[0..n-1]).
• If last characters of both sequences match (or X[m-1] == Y[n-1]) then L(X[0..m-1],
Y[0..n-1]) = 1 + L(X[0..m-2], Y[0..n-2])
• If last characters of both sequences do not match (or X[m-1] != Y[n-1]) then L(X[0..m-
1], Y[0..n-1]) = MAX ( L(X[0..m-2], Y[0..n-1]), L(X[0..m-1], Y[0..n-2])

1359
Chapter 183. Longest Common Subsequence | DP using Memoization

Given below is the recursive solution to the LCS problem:

// A Naive recursive implementation


// of LCS of two strings
#include <bits/stdc++.h>
using namespace std;
  
// Returns length of LCS for X[0..m-1], Y[0..n-1]
int lcs(string X, string Y, int m, int n)
{
    if (m == 0 || n == 0)
        return 0;
  
    if (X[m - 1] == Y[n - 1])
        return 1 + lcs(X, Y, m - 1, n - 1);
    else
        return max(lcs(X, Y, m, n - 1),
                   lcs(X, Y, m - 1, n));
}
  
// Driver Code
int main()
{
    string X = "AGGTAB";
    string Y = "GXTXAYB";
  
    // Find the length of string
    int m = X.length();
    int n = Y.length();
  
    cout << "Length of LCS: " << lcs(X, Y, m, n);
  
    return 0;
}

Output:

Length of LCS: 4

Dynamic Programming using Memoization


Considering the above implementation, the following is a partial recursion tree for input
strings “AXYT” and “AYZX”

lcs("AXYT", "AYZX")

1360
Chapter 183. Longest Common Subsequence | DP using Memoization

/ \
lcs("AXY", "AYZX") lcs("AXYT", "AYZ")
/ \ / \
lcs("AX", "AYZX") lcs("AXY", "AYZ") lcs("AXY", "AYZ") lcs("AXYT", "AY")

In the above partial recursion tree, lcs(“AXY”, “AYZ”) is being solved twice. On
drawing the complete recursion tree, it has been observed that there are many subproblems
which are solved again and again. So this problem has Overlapping Substructure prop-
erty and recomputation of same subproblems can be avoided by either using Memoization
or Tabulation. The tabulation method has been discussed here.
A common point of observation to use memoization in the recursive code will be the two
non-constant arguments M and N in every function call. The function has 4 arguments,
but 2 arguments are constant which do not affect the Memoization. The repetitive calls occur
for N and M which have been called previously. Following the below steps will help us to
write the DP solution using memoization.

• Use a 2-D array to store the computed lcs(m, n) value at arr[m-1][n-1] as the
string index starts from 0.
• Whenever the function with the same argument m and n are called again, do not per-
form any further recursive call and return arr[m-1][n-1] as the previous computation
of the lcs(m, n) has already been stored in arr[m-1][n-1], hence reducing the recursive
calls that happen more then once.

Below is the implementation of the above approach:

// C++ program to memoize


// recursive implementation of LCS problem
#include <bits/stdc++.h>
using namespace std;
  
const int maximum = 1000;
  
// Returns length of LCS for X[0..m-1], Y[0..n-1] */
// memoization applied in recursive solution
int lcs(string X, string Y, int m, int n, int dp[][maximum])
{
    // base case
    if (m == 0 || n == 0)
        return 0;
  
    // if the same state has already been
    // computed
    if (dp[m - 1][n - 1] != -1)
        return dp[m - 1][n - 1];
  
    // if equal, then we store the value of the
    // function call

1361
Chapter 183. Longest Common Subsequence | DP using Memoization

    if (X[m - 1] == Y[n - 1]) {


  
        // store it in arr to avoid further repetitive
        // work in future function calls
        dp[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1, dp);
  
        return dp[m - 1][n - 1];
    }
    else {
  
        // store it in arr to avoid further repetitive
        // work in future function calls
        dp[m - 1][n - 1] = max(lcs(X, Y, m, n - 1, dp),
                               lcs(X, Y, m - 1, n, dp));
  
        return dp[m - 1][n - 1];
    }
}
  
// Driver Code
int main()
{
  
    string X = "AGGTAB";
    string Y = "GXTXAYB";
    int m = X.length();
    int n = Y.length();
  
    int dp[m][maximum];
  
    // assign -1 to all positions
    memset(dp, -1, sizeof(dp));
  
    cout << "Length of LCS: " << lcs(X, Y, m, n, dp);
  
    return 0;
}

Output:

Length of LCS: 4

Time Complexity: O(N * M), where N and M is length of the first and second string
respectively.
Auxiliary Space: (N * M)

1362
Chapter 183. Longest Common Subsequence | DP using Memoization

Source

https://www.geeksforgeeks.org/longest-common-subsequence-dp-using-memoization/

1363
Chapter 184

Longest Decreasing
Subsequence

Longest Decreasing Subsequence - GeeksforGeeks


Given an array of N integers, find the length of the longest subsequence of a given sequence
such that all elements of the subsequence are sorted in strictly decreasing order.
Examples :

Input: arr[] = [15, 27, 14, 38, 63, 55, 46, 65, 85]
Output: 3
Explanation: The longest decreasing sub sequence is {63, 55, 46}
Input: arr[] = {50, 3, 10, 7, 40, 80}
Output: 3
Explanation: The longest decreasing subsequence is {50, 10, 7}

The problem can be solved using Dynamic Programming


Optimal Substructure:
Let arr[0..n-1] be the input array and lds[i] be the length of the LDS ending at index i such
that arr[i] is the last element of the LDS.
Then, lds[i] can be recursively written as:

lds[i] = 1 + max( lds[j] ) where i > j > 0 and arr[j] > arr[i] or
lds[i] = 1, if no such j exists.

To find the LDS for a given array, we need to return max(lds[i]) where n > i > 0.

C++

1364
Chapter 184. Longest Decreasing Subsequence

// CPP program to find the length of the


// longest decreasing subsequence
#include <bits/stdc++.h>
using namespace std;
  
// Function that returns the length
// of the longest decreasing subsequence
int lds(int arr[], int n)
{
    int lds[n];
    int i, j, max = 0;
  
    // Initialize LDS with 1 for all index
    // The minimum LDS starting with any
    // element is always 1
    for (i = 0; i < n; i++)
        lds[i] = 1;
  
    // Compute LDS from every index
    // in bottom up manner
    for (i = 1; i < n; i++)
        for (j = 0; j < i; j++)
            if (arr[i] < arr[j] && lds[i] < lds[j] + 1)
                lds[i] = lds[j] + 1;
  
    // Select the maximum 
    // of all the LDS values
    for (i = 0; i < n; i++)
        if (max < lds[i])
            max = lds[i];
  
    // returns the length of the LDS
    return max;
}
// Driver Code
int main()
{
    int arr[] = { 15, 27, 14, 38, 63, 55, 46, 65, 85 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Length of LDS is " << lds(arr, n);
    return 0;
}

Java

// Java program to find the 


// length of the longest 
// decreasing subsequence

1365
Chapter 184. Longest Decreasing Subsequence

import java.io.*;
  
class GFG 
{
  
// Function that returns the 
// length of the longest 
// decreasing subsequence
static int lds(int arr[], int n)
{
    int lds[] = new int[n];
    int i, j, max = 0;
  
    // Initialize LDS with 1 
    // for all index. The minimum 
    // LDS starting with any
    // element is always 1
    for (i = 0; i < n; i++)
        lds[i] = 1;
  
    // Compute LDS from every 
    // index in bottom up manner
    for (i = 1; i < n; i++)
        for (j = 0; j < i; j++)
            if (arr[i] < arr[j] && 
                         lds[i] < lds[j] + 1)
                lds[i] = lds[j] + 1;
  
    // Select the maximum 
    // of all the LDS values
    for (i = 0; i < n; i++)
        if (max < lds[i])
            max = lds[i];
  
    // returns the length
    // of the LDS
    return max;
}
// Driver Code
public static void main (String[] args)
{
    int arr[] = { 15, 27, 14, 38, 
                  63, 55, 46, 65, 85 };
    int n = arr.length;
    System.out.print("Length of LDS is " + 
                             lds(arr, n));
}
}

1366
Chapter 184. Longest Decreasing Subsequence

  
// This code is contributed by anuj_67.

C#

// C# program to find the 


// length of the longest 
// decreasing subsequence
using System;
  
class GFG 
{
  
// Function that returns the 
// length of the longest 
// decreasing subsequence
static int lds(int []arr, int n)
{
    int []lds = new int[n];
    int i, j, max = 0;
  
    // Initialize LDS with 1 
    // for all index. The minimum 
    // LDS starting with any
    // element is always 1
    for (i = 0; i < n; i++)
        lds[i] = 1;
  
    // Compute LDS from every 
    // index in bottom up manner
    for (i = 1; i < n; i++)
        for (j = 0; j < i; j++)
            if (arr[i] < arr[j] && 
                        lds[i] < lds[j] + 1)
                lds[i] = lds[j] + 1;
  
    // Select the maximum 
    // of all the LDS values
    for (i = 0; i < n; i++)
        if (max < lds[i])
            max = lds[i];
  
    // returns the length
    // of the LDS
    return max;
}
// Driver Code
public static void Main ()

1367
Chapter 184. Longest Decreasing Subsequence

{
    int []arr = { 15, 27, 14, 38, 
                63, 55, 46, 65, 85 };
    int n = arr.Length;
    Console.Write("Length of LDS is " + 
                          lds(arr, n));
}
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to find the 
// length of the longest 
// decreasing subsequence
  
  
// Function that returns the 
// length of the longest 
// decreasing subsequence
function lds($arr, $n)
{
    $lds = array();
    $i; $j; $max = 0;
  
    // Initialize LDS with 1 
    // for all index The minimum
    // LDS starting with any
    // element is always 1
    for ($i = 0; $i < $n; $i++)
        $lds[$i] = 1;
  
    // Compute LDS from every 
    // index in bottom up manner
    for ($i = 1; $i < $n; $i++)
        for ($j = 0; $j < $i; $j++)
            if ($arr[$i] < $arr[$j] and 
                $lds[$i] < $lds[$j] + 1)
                {
                    $lds[$i] = $lds[$j] + 1;
                }
  
    // Select the maximum 
    // of all the LDS values
    for ($i = 0; $i < $n; $i++)
        if ($max < $lds[$i])

1368
Chapter 184. Longest Decreasing Subsequence

            $max = $lds[$i];
  
    // returns the length
    // of the LDS
    return $max;
}
  
// Driver Code
$arr = array(15, 27, 14, 38, 63,
             55, 46, 65, 85);
$n = count($arr);
echo "Length of LDS is " , 
            lds($arr, $n);
  
// This code is contributed by anuj_67.
?>

Output :

Length of LDS is 3

Time Complexity: O(n2 )


Auxiliary Space: O(n)
Related Article: https://www.geeksforgeeks.org/longest-increasing-subsequence/
Improved By : vt_m

Source

https://www.geeksforgeeks.org/longest-decreasing-subsequence/

1369
Chapter 185

Longest Even Length Substring


such that Sum of First and
Second Half is same

Longest Even Length Substring such that Sum of First and Second Half is same - Geeks-
forGeeks
Given a string ‘str’ of digits, find length of the longest substring of ‘str’, such that the length
of the substring is 2k digits and sum of left k digits is equal to the sum of right k digits.
Examples :

Input: str = "123123"


Output: 6
The complete string is of even length and sum of first and second
half digits is same

Input: str = "1538023"


Output: 4
The longest substring with same first and second half sum is "5380"

Simple Solution [ O(n3 ) ]


A Simple Solution is to check every substring of even length. The following is the
implementation of simple approach.

// A simple C based program to find length of longest  even length


// substring with same sum of digits in left and right 
#include<stdio.h>

1370
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

#include<string.h>
  
int findLength(char *str)
{
    int n = strlen(str);
    int maxlen =0;  // Initialize result
  
    // Choose starting point of every substring
    for (int i=0; i<n; i++)
    {
        // Choose ending point of even length substring
        for (int j =i+1; j<n; j += 2)
        {
            int length = j-i+1;//Find length of current substr
  
            // Calculate left & right sums for current substr
            int leftsum = 0, rightsum =0;
            for (int k =0; k<length/2; k++)
            {
                leftsum  += (str[i+k]-'0');
                rightsum += (str[i+k+length/2]-'0');
            }
  
            // Update result if needed
            if (leftsum == rightsum && maxlen < length)
                    maxlen = length;
        }
    }
    return maxlen;
}
  
// Driver program to test above function
int main(void)
{
    char str[] = "1538023";
    printf("Length of the substring is %d", findLength(str));
    return 0;
}

Java

// A simple Java based program to find 


// length of longest even length substring 
// with same sum of digits in left and right 
import java.io.*;
  
class GFG {
  

1371
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

static int findLength(String str)


{
    int n = str.length();
    int maxlen = 0; // Initialize result
  
    // Choose starting point of every 
    // substring
    for (int i = 0; i < n; i++)
    {
        // Choose ending point of even 
        // length substring
        for (int j = i + 1; j < n; j += 2)
        {   
            // Find length of current substr
            int length = j - i + 1;
  
            // Calculate left & right sums
            // for current substr
            int leftsum = 0, rightsum = 0;
            for (int k = 0; k < length/2; k++)
            {
                leftsum += (str.charAt(i + k) - '0');
                rightsum += (str.charAt(i + k + length/2) - '0');
            }
  
            // Update result if needed
            if (leftsum == rightsum && maxlen < length)
                    maxlen = length;
        }
    }
    return maxlen;
}
  
// Driver program to test above function
public static void main(String[] args)
{
    String str = "1538023";
    System.out.println("Length of the substring is " 
                       + findLength(str));
}
}
  
// This code is contrtibuted by Prerna Saini

Python3

# A simple Python 3 based


# program to find length

1372
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

# of longest even length


# substring with same sum
# of digits in left and right 
  
def findLength(str):
  
    n = len(str)
    maxlen = 0 # Initialize result
  
    # Choose starting point
        # of every substring
    for i in range(0, n):
      
        # Choose ending point
                # of even length substring
        for j in range(i+1, n, 2):
                   
                        # Find length of current substr
            length = j - i + 1 
  
            # Calculate left & right 
                        # sums for current substr
            leftsum = 0
            rightsum =0
            for k in range(0,int(length/2)):
              
                leftsum += (int(str[i+k])-int('0'))
                rightsum += (int(str[i+k+int(length/2)])-int('0'))
              
  
            # Update result if needed
            if (leftsum == rightsum and maxlen < length):
                    maxlen = length
          
      
    return maxlen
  
  
# Driver program to
# test above function
str = "1538023"
print("Length of the substring is",
       findLength(str))
  
# This code is contributed by
# Smitha Dinesh Semwal

C#

1373
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

// A simple C# based program to find 


// length of longest even length substring 
// with same sum of digits in left and right 
using System;
  
class GFG {
  
static int findLength(String str)
{
    int n = str.Length;
    int maxlen = 0; // Initialize result
  
    // Choose starting point 
    // of every substring
    for (int i = 0; i < n; i++)
    {
        // Choose ending point of 
        // even length substring
        for (int j = i + 1; j < n; j += 2)
        { 
            // Find length of current substr
            int length = j - i + 1;
  
            // Calculate left & right sums
            // for current substr
            int leftsum = 0, rightsum = 0;
            for (int k = 0; k < length/2; k++)
            {
                leftsum += (str[i + k] - '0');
                rightsum += (str[i + k + length/2] - '0');
            }
  
            // Update result if needed
            if (leftsum == rightsum && 
                maxlen < length)
                    maxlen = length;
        }
    }
    return maxlen;
}
  
  // Driver program to test above function
  public static void Main()
  {
    String str = "1538023";
    Console.Write("Length of the substring is " +
                                findLength(str));
  }

1374
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

}
  
// This code is contrtibuted by nitin mittal

Output:

Length of the substring is 4

Dynamic Programming [ O(n2 ) and O(n2 ) extra space]


The above solution can be optimized to work in O(n2 ) using Dynamic Programming.
The idea is to build a 2D table that stores sums of substrings. The following is the
implementation of Dynamic Programming approach.

// A C based program that uses Dynamic Programming to find length of the


// longest even substring with same sum of digits in left and right half
#include <stdio.h>
#include <string.h>
  
int findLength(char *str)
{
    int n = strlen(str);
    int maxlen = 0; // Initialize result
  
    // A 2D table where sum[i][j] stores sum of digits
    // from str[i] to str[j].  Only filled entries are
    // the entries where j >= i
    int sum[n][n];
  
    // Fill the diagonal values for sunstrings of length 1
    for (int i =0; i<n; i++)
        sum[i][i] = str[i]-'0';
  
    // Fill entries for substrings of length 2 to n
    for (int len=2; len<=n; len++)
    {
        // Pick i and j for current substring
        for (int i=0; i<n-len+1; i++)
        {
            int j = i+len-1;
            int k = len/2;
  
            // Calculate value of sum[i][j]
            sum[i][j] = sum[i][j-k] + sum[j-k+1][j];
  
            // Update result if 'len' is even, left and right

1375
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

            // sums are same and len is more than maxlen


            if (len%2 == 0 && sum[i][j-k] == sum[(j-k+1)][j]
                           && len > maxlen)
                 maxlen = len;
        }
    }
    return maxlen;
}
  
// Driver program to test above function
int main(void)
{
    char str[] = "153803";
    printf("Length of the substring is %d", findLength(str));
    return 0;
}

Java

// A Java based program that uses Dynamic 


// Programming to find length of the longest
// even substring with same sum of digits 
// in left and right half
import java.io.*;
  
class GFG {
  
static int findLength(String str)
{
    int n = str.length();
    int maxlen = 0; // Initialize result
  
    // A 2D table where sum[i][j] stores 
    // sum of digits from str[i] to str[j]. 
    // Only filled entries are the entries
    // where j >= i
    int sum[][] = new int[n][n];
  
    // Fill the diagonal values for 
    // substrings of length 1
    for (int i = 0; i < n; i++)
        sum[i][i] = str.charAt(i) - '0';
  
    // Fill entries for substrings of
    // length 2 to n
    for (int len = 2; len <= n; len++)
    {
        // Pick i and j for current substring

1376
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

        for (int i = 0; i < n - len + 1; i++)


        {
            int j = i + len - 1;
            int k = len/2;
  
            // Calculate value of sum[i][j]
            sum[i][j] = sum[i][j-k] +
                        sum[j-k+1][j];
  
            // Update result if 'len' is even,
            // left and right sums are same
            // and len is more than maxlen
            if (len % 2 == 0 && sum[i][j-k] == 
                sum[(j-k+1)][j] && len > maxlen)
                maxlen = len;
        }
    }
    return maxlen;
}
  
// Driver program to test above function
public static void main(String[] args)
{
    String str = "153803";
    System.out.println("Length of the substring is "
                       + findLength(str));
}
}
  
// This code is contributd by Prerna Saini

Output:

Length of the substring is 4

Time complexity of the above solution is O(n2 ), but it requires O(n2 ) extra space.
[A O(n2 ) and O(n) extra space solution]
The idea is to use a single dimensional array to store cumulative sum.

C++

// A O(n^2) time and O(n) extra space solution


#include<bits/stdc++.h>
using namespace std;
  
int findLength(string str, int n)

1377
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

{
    int sum[n+1]; // To store cumulative sum from first digit to nth digit
    sum[0] = 0;
  
    /* Store cumulative sum of digits from first to last digit */
    for (int i = 1; i <= n; i++)
        sum[i] = (sum[i-1] + str[i-1]  - '0'); /* convert chars to int */
  
    int ans = 0; // initialize result
  
    /* consider all even length substrings one by one */
    for (int len = 2; len <= n; len += 2)
    {
        for (int i = 0; i <= n-len; i++)
        {
            int j = i + len - 1;
  
            /* Sum of first and second half is same than update ans */
            if (sum[i+len/2] - sum[i] == sum[i+len] - sum[i+len/2])
                ans = max(ans, len);
        }
    }
    return ans;
}
  
// Driver program to test above function
int main()
{
    string str = "123123";
    cout << "Length of the substring is " << findLength(str, str.length());
    return 0;
}

Java

// Java implementation of O(n^2) time


// and O(n) extra space solution
class GFG {
  
static int findLength(String str, int n)
{   
    // To store cumulative sum from
    // first digit to nth digit
    int sum[] = new int[ n + 1]; 
    sum[0] = 0;
  
    /* Store cumulative sum of digits 
    from first to last digit */

1378
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

    for (int i = 1; i <= n; i++)


          
        /* convert chars to int */
        sum[i] = (sum[i-1] + str.charAt(i-1) 
                                    - '0'); 
  
    int ans = 0; // initialize result
  
    /* consider all even length 
    substrings one by one */
    for (int len = 2; len <= n; len += 2)
    {
        for (int i = 0; i <= n-len; i++)
        {
            int j = i + len - 1;
  
            /* Sum of first and second half 
            is same than update ans */
            if (sum[i+len/2] - sum[i] == sum[i+len]
                                   - sum[i+len/2])
                ans = Math.max(ans, len);
        }
    }
    return ans;
}
  
// Driver program to test above function
public static void main(String[] args)
{
    String str = "123123";
    System.out.println("Length of the substring is " 
                    + findLength(str, str.length()));
}
}
  
// This code is contributed by Prerna Saini

C#

// C# implementation of O(n^2) time and O(n)


// extra space solution
using System;
  
class GFG {
  
    static int findLength(string str, int n)
    { 
          

1379
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

        // To store cumulative sum from


        // first digit to nth digit
        int []sum = new int[ n + 1]; 
        sum[0] = 0;
      
        /* Store cumulative sum of digits 
        from first to last digit */
        for (int i = 1; i <= n; i++)
              
            /* convert chars to int */
            sum[i] = (sum[i-1] + str[i-1] 
                                   - '0'); 
      
        int ans = 0; // initialize result
      
        /* consider all even length 
        substrings one by one */
        for (int len = 2; len <= n; len += 2)
        {
            for (int i = 0; i <= n-len; i++)
            {
                // int j = i + len - 1;
      
                /* Sum of first and second half 
                is same than update ans */
                if (sum[i+len/2] - sum[i] ==
                     sum[i+len] - sum[i+len/2])
                    ans = Math.Max(ans, len);
            }
        }
          
        return ans;
    }
      
    // Driver program to test above function
    public static void Main()
    {
        string str = "123123";
        Console.Write("Length of the substring"
        + " is " + findLength(str, str.Length));
    }
}
  
// This code is contributed by nitin mittal.

Output:

Length of the substring is 6

1380
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

Thanks to Gaurav Ahirwar for suggesting this method.


[A O(n2 ) time and O(1) extra space solution]
The idea is to consider all possible mid points (of even length substrings) and keep expanding
on both sides to get and update optimal length as the sum of two sides become equal.
Below is the implementation of the above idea.

// A O(n^2) time and O(1) extra space solution


#include<bits/stdc++.h>
using namespace std;
  
int findLength(string str, int n)
{
    int ans = 0; // Initialize result
  
    // Consider all possible midpoints one by one
    for (int i = 0; i <= n-2; i++)
    {
        /* For current midpoint 'i', keep expanding substring on
           both sides, if sum of both sides becomes equal update
           ans */
        int l = i, r = i + 1;
  
        /* initialize left and right sum */
        int lsum = 0, rsum = 0;
  
        /* move on both sides till indexes go out of bounds */
        while (r < n && l >= 0)
        {
            lsum += str[l] - '0';
            rsum += str[r] - '0';
            if (lsum == rsum)
                ans = max(ans, r-l+1);
            l--;
            r++;
        }
    }
    return ans;
}
  
// Driver program to test above function
int main()
{
    string str = "123123";
    cout << "Length of the substring is " << findLength(str, str.length());
    return 0;
}

1381
Chapter 185. Longest Even Length Substring such that Sum of First and Second Half is
same

Output:

Length of the substring is 6

Thanks to Gaurav Ahirwar for suggesting this method.


This article is contributed by Ashish Bansal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/longest-even-length-substring-sum-first-second-half/

1382
Chapter 186

Longest Geometric Progression

Longest Geometric Progression - GeeksforGeeks


Given a set of numbers, find the Length of the Longest Geometrix Progression (LLGP) in
it. The common ratio of GP must be an integer.
Examples:

set[] = {5, 7, 10, 15, 20, 29}


output = 3
The longest arithmetic progression is {5, 10, 20}

set[] = {3, 9, 27, 81}


output = 4

This problem is similar to Longest Arithmetic Progression Problem. We can solve this
problem using Dynamic Programming.
We first sort the given set. We use an auxiliary table L[n][n] to store results of subproblems.
An entry L[i][j] in this table stores LLGP with set[i] and set[j] as first two elements of GP
and j > i. The table is filled from bottom right to top left. To fill the table, j (second
element in GP) is first fixed. i and k are searched for a fixed j. If i and k are found such
that i, j, k form an GP, then the value of L[i][j] is set as L[j][k] + 1. Note that the value of
L[j][k] must have been filled before as the loop traverses from right to left columns.
Following is C++ implementation of the Dynamic Programming algorithm.

// C++ program to find length of the longest geometric


// progression in a given set
#include <iostream>
#include <algorithm>
using namespace std;
  

1383
Chapter 186. Longest Geometric Progression

// Returns length of the longest GP subset of set[]


int lenOfLongestGP(int set[], int n)
{
    // Base cases
    if (n < 2)
        return n;
    if (n == 2)
        return (set[1] % set[0] == 0);
  
    // Let us sort the set first
    sort(set, set+n);
  
    // An entry L[i][j] in this table stores LLGP with
    // set[i] and set[j] as first two elements of GP
    // and j > i.
    int L[n][n];
  
    // Initialize result (A single element is always a GP)
    int llgp = 1;
  
    // Initialize values of last column
    for (int i = 0; i < n; ++i)
        if (set[n-1] % set[i] == 0)
            L[i][n-1] = 2;
        else
            L[i][n-1] = 1;
  
  
    // Consider every element as second element of GP
    for (int j = n - 2; j >= 1; --j)
    {
        // Search for i and k for j
        int i = j - 1, k = j+1;
        while (i>=0 && k <= n-1)
        {
            // Two cases when i, j and k don't form
            // a GP.
            if (set[i] * set[k] < set[j]*set[j])
                ++k;
  
            else if (set[i] * set[k] > set[j]*set[j])
            {
                if (set[j] % set[i] == 0)
                    L[i][j] = 2;
                else
                    L[i][j] = 1;
                --i;
            }

1384
Chapter 186. Longest Geometric Progression

  
  
            // i, j and k form GP, LLGP with i and j as
            // first two elements is equal to LLGP with
            // j and k as first two elements plus 1.
            // L[j][k] must have been filled before as
            // we run the loop from right side
            else
            {
                L[i][j] = L[j][k] + 1;
  
                // Update overall LLGP
                if (L[i][j] > llgp)
                    llgp = L[i][j];
  
  
                // Change i and k to fill more L[i][j]
                // values for current j
                --i;
                ++k;
            }
        }
  
        // If the loop was stopped due to k becoming
        // more than n-1, set the remaining entties
        // in column j as 1 or 2 based on divisibility
        // of set[j] by set[i]
        while (i >= 0)
        {
            if (set[j] % set[i] == 0)
                L[i][j] = 2;
            else
                L[i][j] = 1;
            --i;
        }
    }
  
    // Return result
    return llgp;
}
  
// Driver code
int main()
{
    int set1[] = {1, 3, 9, 27, 81, 243};
    int n1 = sizeof(set1)/sizeof(set1[0]);
    cout << lenOfLongestGP(set1, n1) << "n";
  

1385
Chapter 186. Longest Geometric Progression

    int set2[] = {1, 3, 4, 9, 7, 27};


    int n2 = sizeof(set2)/sizeof(set2[0]);
    cout << lenOfLongestGP(set2, n2) << "n";
  
    int set3[] = {2, 3, 5, 7, 11, 13};
    int n3 = sizeof(set3)/sizeof(set3[0]);
    cout << lenOfLongestGP(set3, n3) << "n";
  
    return 0;
}

Output:

6
4
1

Time Complexity: O(n2 )


Auxiliary Space: O(n2 )

Source

https://www.geeksforgeeks.org/longest-geometric-progression/

1386
Chapter 187

Longest Increasing Odd Even


Subsequence

Longest Increasing Odd Even Subsequence - GeeksforGeeks


Given an array of size n. The problem is to find the length of the subsequence in the given
array such that all the elements of the subsequence are sorted in increasing order and also
they are alternately odd and even.
Note that the subsequence could start either with the odd number or with the even number.
Examples:

Input : arr[] = {5, 6, 9, 4, 7, 8}


Output : 4
{5, 6, 7, 8} is the required longest
increasing odd even subsequence.

Input : arr[] = {1, 12, 2, 22, 5, 30, 31, 14, 17, 11}
Output : 5

Naive Approach: Consider all subsequences and select the ones with alternate odd even
numbers in increasing order. Out of them select the longest one. This has an exponential
time complexity.
Efficient Approach:
Let L(i) be the length of the LIOES (Longest Increasing Odd Even Subsequence) ending at
index i such that arr[i] is the last element of the LIOES.
Then, L(i) can be recursively written as:
L(i) = 1 + max( L(j) ) where 0 < j < i and (arr[j] < arr[i]) and (arr[i]+arr[j])%2 != 0; or
L(i) = 1, if no such j exists.
To find the LIOES for a given array, we need to return max(L(i)) where 0 < i < n.
A dynamic programming approach has been implemented below for the above mentioned
recursive relation.

1387
Chapter 187. Longest Increasing Odd Even Subsequence

C++

// C++ implementation to find the longest


// increasing odd even subsequence
#include <bits/stdc++.h>
  
using namespace std;
  
// function to find the longest
// increasing odd even subsequence
int longOddEvenIncSeq(int arr[], int n)
{
    // lioes[i] stores longest increasing odd
    // even subsequence ending at arr[i]
    int lioes[n];
  
    // to store the length of longest increasing
    // odd even subsequence
    int maxLen = 0;
  
    // Initialize LIOES values for all indexes
    for (int i = 0; i < n; i++)
        lioes[i] = 1;
  
    // Compute optimized LIOES values
    // in bottom up manner
    for (int i = 1; i < n; i++)
        for (int j = 0; j < i; j++)
            if (arr[i] > arr[j] && 
               (arr[i] + arr[j]) % 2 != 0
                && lioes[i] < lioes[j] + 1)
                lioes[i] = lioes[j] + 1;
  
    // Pick maximum of all LIOES values
    for (int i = 0; i < n; i++)
        if (maxLen < lioes[i])
            maxLen = lioes[i];
  
    // required maximum length
    return maxLen;
}
  
// Driver program to test above
int main()
{
    int arr[] = { 1, 12, 2, 22, 5, 30, 
                    31, 14, 17, 11 };
    int n = sizeof(arr) / sizeof(n);

1388
Chapter 187. Longest Increasing Odd Even Subsequence

    cout << "Longest Increasing Odd Even "


         << "Subsequence: "
         << longOddEvenIncSeq(arr, n);
    return 0;
}

Java

// Java implementation to find the longest


// increasing odd even subsequence
import java.util.*;
import java.lang.*;
  
public class GfG{
      
    // function to find the longest
    // increasing odd even subsequence
    public static int longOddEvenIncSeq(int arr[], 
                                           int n)
    {
        // lioes[i] stores longest increasing odd
        // even subsequence ending at arr[i]
        int[] lioes = new int[n];
  
        // to store the length of longest 
        // increasing odd even subsequence
        int maxLen = 0;
  
        // Initialize LIOES values for all indexes
        for (int i = 0; i < n; i++)
            lioes[i] = 1;
  
        // Compute optimized LIOES values
        // in bottom up manner
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] > arr[j] && 
                (arr[i] + arr[j]) % 2 != 0
                    && lioes[i] < lioes[j] + 1)
                    lioes[i] = lioes[j] + 1;
  
        // Pick maximum of all LIOES values
        for (int i = 0; i < n; i++)
            if (maxLen < lioes[i])
                maxLen = lioes[i];
  
        // required maximum length
        return maxLen;

1389
Chapter 187. Longest Increasing Odd Even Subsequence

    }
    // driver function
    public static void main(String argc[]){
        int[] arr = new int[]{ 1, 12, 2, 22, 
                     5, 30, 31, 14, 17, 11 };
        int n = 10;
        System.out.println("Longest Increasing Odd"
                          + " Even Subsequence: "
                       + longOddEvenIncSeq(arr, n));
    }
}
  
/* This code is contributed by Sagar Shukla */

Python3

# Python3 implementation to find the longest


# increasing odd even subsequence
  
# function to find the longest
# increasing odd even subsequence
def longOddEvenIncSeq( arr , n ):
  
    # lioes[i] stores longest increasing odd
    # even subsequence ending at arr[i]
    lioes = list()
      
    # to store the length of longest increasing
    # odd even subsequence
    maxLen = 0
      
    # Initialize LIOES values for all indexes
    for i in range(n):
        lioes.append(1)
          
    # Compute optimized LIOES values
    # in bottom up manner
    i=1
    for i in range(n):
        for j in range(i):
            if (arr[i] > arr[j] and
                (arr[i] + arr[j]) % 2 != 0 and
                lioes[i] < lioes[j] + 1):
                    lioes[i] = lioes[j] + 1
      
    # Pick maximum of all LIOES values
    for i in range(n):
        if maxLen < lioes[i]:

1390
Chapter 187. Longest Increasing Odd Even Subsequence

            maxLen = lioes[i]
              
    # required maximum length
    return maxLen
      
# Driver to test above
arr = [ 1, 12, 2, 22, 5, 30, 31, 14, 17, 11 ]
n = len(arr)
print("Longest Increasing Odd Even " +
      "Subsequence: ",longOddEvenIncSeq(arr, n))
                  
# This code is contributed by "Sharad_Bhardwaj".

C#

// C# implementation to find the longest


// increasing odd even subsequence
using System;
  
class GFG {
  
    // function to find the longest
    // increasing odd even subsequence
    public static int longOddEvenIncSeq(int[] arr,
                                            int n)
    {
        // lioes[i] stores longest increasing odd
        // even subsequence ending at arr[i]
        int[] lioes = new int[n];
  
        // to store the length of longest
        // increasing odd even subsequence
        int maxLen = 0;
  
        // Initialize LIOES values for all indexes
        for (int i = 0; i < n; i++)
            lioes[i] = 1;
  
        // Compute optimized LIOES values
        // in bottom up manner
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] > arr[j] &&
                   (arr[i] + arr[j]) % 2 != 0 &&
                    lioes[i] < lioes[j] + 1)
                      
                    lioes[i] = lioes[j] + 1;
  

1391
Chapter 187. Longest Increasing Odd Even Subsequence

        // Pick maximum of all LIOES values


        for (int i = 0; i < n; i++)
            if (maxLen < lioes[i])
                maxLen = lioes[i];
  
        // required maximum length
        return maxLen;
    }
      
    // driver function
    public static void Main()
    {
        int[] arr = new int[]{ 1, 12, 2, 22,
                               5, 30, 31, 14, 17, 11 };
        int n = 10;
        Console.Write("Longest Increasing Odd"
                    + " Even Subsequence: "
                    + longOddEvenIncSeq(arr, n));
    }
}
  
// This code is contributed by Sam007

Output:

Longest Increasing Odd Even Subsequence: 5

Time Complexity: O(n2 ).


Auxiliary Space : O(n).

Source

https://www.geeksforgeeks.org/longest-increasing-odd-even-subsequence/

1392
Chapter 188

Longest Increasing Path in


Matrix

Longest Increasing Path in Matrix - GeeksforGeeks


Given a matrix of N rows and M columns. From m[i][j], we can move to m[i+1][j], if
m[i+1][j] > m[i][j], or can move to m[i][j+1] if m[i][j+1] > m[i][j]. The task is print longest
path length if we start from (0, 0).
Examples:

Input : N = 4, M = 4
m[][] = { { 1, 2, 3, 4 },
{ 2, 2, 3, 4 },
{ 3, 2, 3, 4 },
{ 4, 5, 6, 7 } };
Output : 7
Longest path is 1 2 3 4 5 6 7.

Input : N = 2, M =2
m[][] = { { 1, 2 },
{ 3, 4 } };
Output :3
Longest path is either 1 2 4 or
1 3 4.

The idea is to use dynamic programming. Maintain the 2D matrix, dp[][], where dp[i][j]
store the value of length of longest increasing sequence for sub matrix starting from ith row
and j-th column.
Let the longest increasing sub sequence values for m[i+1][j] and m[i][j+1] be known already
as v1 and v2 respectively. Then the value for m[i][j] will be max(v1, v2) + 1.
We can start from m[n-1][m-1] as base case with length of longest increasing sub sequence

1393
Chapter 188. Longest Increasing Path in Matrix

be 1, moving upwards and leftwards updating the value of cells. Then the LIP value for cell
m[0][0] will be the answer.
Below is the implementation of this approach:

C++

// CPP program to find longest increasing


// path in a matrix.
#include <bits/stdc++.h>
#define MAX 10
using namespace std;
  
// Return the length of LIP in 2D matrix
int LIP(int dp[][MAX], int mat[][MAX], int n, int m, int x, int y)
{
  // If value not calculated yet.
  if (dp[x][y] < 0)
  {
    int result = 0;
      
    // If reach bottom left cell, return 1.
    if (x == n-1 && y == m-1)
     return dp[x][y] = 1;
       
    // If reach the corner of the matrix.
    if (x == n-1 || y == m-1)
      result = 1;
      
    // If value greater than below cell.
    if (mat[x][y] < mat[x+1][y])
      result = 1 + LIP(dp, mat, n, m, x+1, y);
        
    // If value greater than left cell.
    if (mat[x][y] < mat[x][y+1])
      result = max(result, 1 + LIP(dp, mat, n, m, x, y+1));
        
    dp[x][y] = result;
  }
  
  return dp[x][y];
}
  
// Wrapper function
int wrapper(int mat[][MAX], int n, int m)
{
  int dp[MAX][MAX];
  memset(dp, -1, sizeof dp);

1394
Chapter 188. Longest Increasing Path in Matrix

    
  return LIP(dp, mat, n, m, 0, 0);
}
  
// Driven Program
int main()
{
  int mat[][MAX] = {
                    { 1, 2, 3, 4 },
                    { 2, 2, 3, 4 },
                    { 3, 2, 3, 4 },
                    { 4, 5, 6, 7 },
                  };
    int n = 4, m = 4;    
    cout << wrapper(mat, n, m) << endl;
  
    return 0;
}

Java

// Java program to find longest increasing


// path in a matrix.
import java.util.*;
  
class GFG {
      
    // Return the length of LIP in 2D matrix
    static int LIP(int dp[][], int mat[][], int n,
                        int m, int x, int y)
    {
      // If value not calculated yet.
      if (dp[x][y] < 0)
      {
        int result = 0;
           
        // If reach bottom left cell, return 1.
        if (x == n-1 && y == m-1)
         return dp[x][y] = 1;
            
        // If reach the corner of the matrix.
         if (x == n-1 || y == m-1)
          result = 1;
           
        // If value greater than below cell.
         if (x + 1 < n && mat[x][y] < mat[x+1][y])
          result = 1 + LIP(dp, mat, n, m, x+1, y);
             

1395
Chapter 188. Longest Increasing Path in Matrix

        // If value greater than left cell.


         if (y + 1 < m && mat[x][y] < mat[x][y+1])
          result = Math.max(result, 1 + 
                    LIP(dp, mat, n, m, x, y+1));
             
        dp[x][y] = result;
      }
       
      return dp[x][y];
    }
      
    // Wrapper function
    static int wrapper(int mat[][], int n, int m)
    {
      int dp[][] = new int[10][10];
      for(int i = 0; i < 10; i++)
          Arrays.fill(dp[i],-1);
       
      return LIP(dp, mat, n, m, 0, 0);
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int mat[][] = {
                          { 1, 2, 3, 4 },
                          { 2, 2, 3, 4 },
                          { 3, 2, 3, 4 },
                          { 4, 5, 6, 7 },
                                         };
        int n = 4, m = 4;    
        System.out.println(wrapper(mat, n, m));
              
        }
}
  
// This code is contributed by Arnav Kr. Mandal.    

Output:

Time Complexity: O(N*M).

Source
https://www.geeksforgeeks.org/longest-increasing-path-matrix/

1396
Chapter 189

Longest Increasing Subsequence


Size (N log N)

Longest Increasing Subsequence Size (N log N) - GeeksforGeeks


Given an array of random numbers. Find longest increasing subsequence (LIS) in the array.
I know many of you might have read recursive and dynamic programming (DP) solutions.
There are few requests for O(N log N) algo in the forum posts.
For the time being, forget about recursive and DP solutions. Let us take small samples and
extend the solution to large instances. Even though it may look complex at first time, once
if we understood the logic, coding is simple.
Consider an input array A = {2, 5, 3}. I will extend the array during explanation.
By observation we know that the LIS is either {2, 3} or {2, 5}. Note that I am consid-
ering only strictly increasing sequences.
Let us add two more elements, say 7, 11 to the array. These elements will extend the existing
sequences. Now the increasing sequences are {2, 3, 7, 11} and {2, 5, 7, 11} for the input
array {2, 5, 3, 7, 11}.
Further, we add one more element, say 8 to the array i.e. input array becomes {2, 5, 3, 7, 11,
8}. Note that the latest element 8 is greater than smallest element of any active sequence
(will discuss shortly about active sequences). How can we extend the existing sequences with
8? First of all, can 8 be part of LIS? If yes, how? If we want to add 8, it should come after
7 (by replacing 11).
Since the approach is offline (what we mean by offline?), we are not sure whether adding 8
will extend the series or not. Assume there is 9 in the input array, say {2, 5, 3, 7, 11, 8, 7,
9 …}. We can replace 11 with 8, as there is potentially best candidate (9) that can extend
the new series {2, 3, 7, 8} or {2, 5, 7, 8}.
Our observation is, assume that the end element of largest sequence is E. We can add
(replace) current element A[i] to the existing sequence if there is an element A[j] (j > i) such
that E < A[i] < A[j] or (E > A[i] < A[j] – for replace). In the above example, E = 11, A[i]
= 8 and A[j] = 9.

1397
Chapter 189. Longest Increasing Subsequence Size (N log N)

In case of our original array {2, 5, 3}, note that we face same situation when we are adding
3 to increasing sequence {2, 5}. I just created two increasing sequences to make explanation
simple. Instead of two sequences, 3 can replace 5 in the sequence {2, 5}.
I know it will be confusing, I will clear it shortly!
The question is, when will it be safe to add or replace an element in the existing sequence?
Let us consider another sample A = {2, 5, 3}. Say, the next element is 1. How can it extend
the current sequences {2,3} or {2, 5}. Obviously, it can’t extend either. Yet, there is a
potential that the new smallest element can be start of an LIS. To make it clear, consider
the array is {2, 5, 3, 1, 2, 3, 4, 5, 6}. Making 1 as new sequence will create new sequence
which is largest.
The observation is, when we encounter new smallest element in the array, it can be a potential
candidate to start new sequence.
From the observations, we need to maintain lists of increasing sequences.
In general, we have set of active lists of varying length. We are adding an element A[i] to
these lists. We scan the lists (for end elements) in decreasing order of their length. We will
verify the end elements of all the lists to find a list whose end element is smaller than A[i]
(floor value).
Our strategy determined by the following conditions,

1. If A[i] is smallest among all end


candidates of active lists, we will start
new active list of length 1.

2. If A[i] is largest among all end candidates of


active lists, we will clone the largest active
list, and extend it by A[i].

3. If A[i] is in between, we will find a list with


largest end element that is smaller than A[i].
Clone and extend this list by A[i]. We will discard all
other lists of same length as that of this modified list.

Note that at any instance during our construction of active lists, the following condition is
maintained.
“end element of smaller list is smaller than end elements of larger lists”.
It will be clear with an example, let us take example from wiki {0, 8, 4, 12, 2, 10, 6, 14, 1,
9, 5, 13, 3, 11, 7, 15}.

A[0] = 0. Case 1. There are no active lists, create one.


0.
-----------------------------------------------------------------------------

1398
Chapter 189. Longest Increasing Subsequence Size (N log N)

A[1] = 8. Case 2. Clone and extend.


0.
0, 8.
-----------------------------------------------------------------------------
A[2] = 4. Case 3. Clone, extend and discard.
0.
0, 4.
0, 8. Discarded
-----------------------------------------------------------------------------
A[3] = 12. Case 2. Clone and extend.
0.
0, 4.
0, 4, 12.
-----------------------------------------------------------------------------
A[4] = 2. Case 3. Clone, extend and discard.
0.
0, 2.
0, 4. Discarded.
0, 4, 12.
-----------------------------------------------------------------------------
A[5] = 10. Case 3. Clone, extend and discard.
0.
0, 2.
0, 2, 10.
0, 4, 12. Discarded.
-----------------------------------------------------------------------------
A[6] = 6. Case 3. Clone, extend and discard.
0.
0, 2.
0, 2, 6.
0, 2, 10. Discarded.
-----------------------------------------------------------------------------
A[7] = 14. Case 2. Clone and extend.
0.
0, 2.
0, 2, 6.
0, 2, 6, 14.
-----------------------------------------------------------------------------
A[8] = 1. Case 3. Clone, extend and discard.
0.
0, 1.
0, 2. Discarded.
0, 2, 6.
0, 2, 6, 14.
-----------------------------------------------------------------------------
A[9] = 9. Case 3. Clone, extend and discard.
0.
0, 1.

1399
Chapter 189. Longest Increasing Subsequence Size (N log N)

0, 2, 6.
0, 2, 6, 9.
0, 2, 6, 14. Discarded.
-----------------------------------------------------------------------------
A[10] = 5. Case 3. Clone, extend and discard.
0.
0, 1.
0, 1, 5.
0, 2, 6. Discarded.
0, 2, 6, 9.
-----------------------------------------------------------------------------
A[11] = 13. Case 2. Clone and extend.
0.
0, 1.
0, 1, 5.
0, 2, 6, 9.
0, 2, 6, 9, 13.
-----------------------------------------------------------------------------
A[12] = 3. Case 3. Clone, extend and discard.
0.
0, 1.
0, 1, 3.
0, 1, 5. Discarded.
0, 2, 6, 9.
0, 2, 6, 9, 13.
-----------------------------------------------------------------------------
A[13] = 11. Case 3. Clone, extend and discard.
0.
0, 1.
0, 1, 3.
0, 2, 6, 9.
0, 2, 6, 9, 11.
0, 2, 6, 9, 13. Discarded.
-----------------------------------------------------------------------------
A[14] = 7. Case 3. Clone, extend and discard.
0.
0, 1.
0, 1, 3.
0, 1, 3, 7.
0, 2, 6, 9. Discarded.
0, 2, 6, 9, 11.
----------------------------------------------------------------------------
A[15] = 15. Case 2. Clone and extend.
0.
0, 1.
0, 1, 3.
0, 1, 3, 7.
0, 2, 6, 9, 11.

1400
Chapter 189. Longest Increasing Subsequence Size (N log N)

0, 2, 6, 9, 11, 15. <-- LIS List


----------------------------------------------------------------------------

It is required to understand above strategy to devise an algorithm. Also, ensure we have


maintained the condition, “end element of smaller list is smaller than end elements of larger
lists“. Try with few other examples, before reading further. It is important to understand
what happening to end elements.
Algorithm:
Querying length of longest is fairly easy. Note that we are dealing with end elements only.
We need not to maintain all the lists. We can store the end elements in an array. Discarding
operation can be simulated with replacement, and extending a list is analogous to adding
more elements to array.
We will use an auxiliary array to keep end elements. The maximum length of this array
is that of input. In the worst case the array divided into N lists of size one (note that it
does’t lead to worst case complexity). To discard an element, we will trace ceil value of A[i]
in auxiliary array (again observe the end elements in your rough work), and replace ceil
value with A[i]. We extend a list by adding element to auxiliary array. We also maintain a
counter to keep track of auxiliary array length.
Bonus: You have learnt Patience Sorting technique partially �
Here is a proverb, “Tell me and I will forget. Show me and I will remember. Involve me
and I will understand.” So, pick a suit from deck of cards. Find the longest increasing
sub-sequence of cards from the shuffled suit. You will never forget the approach. �
Update – 17 July, 2016: Quite impressive reponses from the readers and few sites refer-
ring the post, feeling happy as my hardwork helping others. It looks like readers are not
doing any homework prior to posting comments. Requesting to run through some examples
after reading the article, and please do your work on paper (don’t use editor/compiler).
The request is to help yourself. Profess to ‘know’ is different from real understanding (no
disrespect). Given below was my personal experience.
Initial content preparation took roughly 6 hours to me. But, it was a good lesson. I finished
initial code in an hour. When I start writing content to explain the reader, I realized I didn’t
understand the cases. Took my note book (I have habit of maintaining binded note book to
keep track of my rough work), and after few hours I filled nearly 15 pages of rough work.
Whatever the content you are seeing in the gray colored example is from these pages. All the
thought process for the solution triggered by a note in the book ‘Introduction to Algorithms
by Udi Manber’, I strongly recommend to practice the book.
I suspect, many readers might not get the logic behind CeilIndex (binary search). I leave
it as an exercise to the reader to understand how it works. Run through few examples on
paper. I realized I have already covered the algorithm in another post.
Update – 5th August, 2016:
The following link worth referring after you do your work. I got to know the link via my
recently created Disqus profile. The link has explanation of approach mentioned in the
Wiki.
http://stackoverflow.com/questions/2631726/how-to-determine-the-longest-increasing-subsequence-using-dynamic-

1401
Chapter 189. Longest Increasing Subsequence Size (N log N)

Given below is code to find length of LIS (updated to C++11 code, no C-style arrays),
C++

#include <iostream>
#include <vector>
  
// Binary search (note boundaries in the caller)
int CeilIndex(std::vector<int> &v, int l, int r, int key) {
    while (r-l > 1) {
    int m = l + (r-l)/2;
    if (v[m] >= key)
        r = m;
    else
        l = m;
    }
  
    return r;
}
  
int LongestIncreasingSubsequenceLength(std::vector<int> &v) {
    if (v.size() == 0)
        return 0;
  
    std::vector<int> tail(v.size(), 0);
    int length = 1; // always points empty slot in tail
  
    tail[0] = v[0];
    for (size_t i = 1; i < v.size(); i++) {
        if (v[i] < tail[0])
            // new smallest value
            tail[0] = v[i];
        else if (v[i] > tail[length-1])
            // v[i] extends largest subsequence
            tail[length++] = v[i];
        else
            // v[i] will become end candidate of an existing subsequence or
            // Throw away larger elements in all LIS, to make room for upcoming grater elements t
            // (and also, v[i] would have already appeared in one of LIS, identify the location a
            tail[CeilIndex(tail, -1, length-1, v[i])] = v[i];
    }
  
    return length;
}
  
int main() {
    std::vector<int> v{ 2, 5, 3, 7, 11, 8, 10, 13, 6 };
    std::cout << "Length of Longest Increasing Subsequence is " << LongestIncreasingSubsequenceLe
   return 0;

1402
Chapter 189. Longest Increasing Subsequence Size (N log N)

Java

// Java program to find length of longest increasing subsequence


// in O(n Log n) time
import java.io.*;
import java.util.*;
import java.lang.Math;
  
class LIS
{
    // Binary search (note boundaries in the caller)
    // A[] is ceilIndex in the caller
    static int CeilIndex(int A[], int l, int r, int key)
    {
        while (r - l > 1)
        {
            int m = l + (r - l)/2;
            if (A[m]>=key)
                r = m;
            else
                l = m;
        }
  
        return r;
    }
  
    static int LongestIncreasingSubsequenceLength(int A[], int size)
    {
        // Add boundary case, when array size is one
  
        int[] tailTable   = new int[size];
        int len; // always points empty slot
  
        tailTable[0] = A[0];
        len = 1;
        for (int i = 1; i < size; i++)
        {
            if (A[i] < tailTable[0])
                // new smallest value
                tailTable[0] = A[i];
  
            else if (A[i] > tailTable[len-1])
                // A[i] wants to extend largest subsequence
                tailTable[len++] = A[i];
  
            else

1403
Chapter 189. Longest Increasing Subsequence Size (N log N)

                // A[i] wants to be current end candidate of an existing


                // subsequence. It will replace ceil value in tailTable
                tailTable[CeilIndex(tailTable, -1, len-1, A[i])] = A[i];
        }
  
        return len;
    }
  
    // Driver program to test above function
    public static void main(String[] args)
    {
        int A[] = { 2, 5, 3, 7, 11, 8, 10, 13, 6 };
        int n = A.length;
        System.out.println("Length of Longest Increasing Subsequence is "+
                            LongestIncreasingSubsequenceLength(A, n));
    }
}
/* This code is contributed by Devesh Agrawal*/

Python3

# Python program to find


# length of longest
# increasing subsequence
# in O(n Log n) time
  
# Binary search (note
# boundaries in the caller)
# A[] is ceilIndex
# in the caller
def CeilIndex(A, l, r, key):
  
    while (r - l > 1):
      
        m = l + (r - l)//2
        if (A[m] >= key):
            r = m
        else:
            l = m
    return r
   
def LongestIncreasingSubsequenceLength(A, size):
  
    # Add boundary case,
    # when array size is one
   
    tailTable = [0 for i in range(size+1)]
    len=0 # always points empty slot

1404
Chapter 189. Longest Increasing Subsequence Size (N log N)

   
    tailTable[0] = A[0]
    len = 1
    for i in range(1, size):
      
        if (A[i] < tailTable[0]):
  
            # new smallest value
            tailTable[0] = A[i]
   
        elif (A[i] > tailTable[len-1]):
  
            # A[i] wants to extend
            # largest subsequence
            tailTable[len] = A[i]
            len+=1
   
        else:
            # A[i] wants to be current
            # end candidate of an existing
            # subsequence. It will replace
            # ceil value in tailTable
            tailTable[CeilIndex(tailTable, -1, len-1, A[i])] = A[i]
          
   
    return len
  
   
# Driver program to
# test above function
  
A = [ 2, 5, 3, 7, 11, 8, 10, 13, 6 ]
n =len(A)
  
print("Length of Longest Increasing Subsequence is ",
       LongestIncreasingSubsequenceLength(A, n))
  
# This code is contributed
# by Anant Agarwal.

C#

// C# program to find length of longest 


// increasing subsequence in O(n Log n) 
// time
using System;
  
class GFG {

1405
Chapter 189. Longest Increasing Subsequence Size (N log N)

      
    // Binary search (note boundaries 
    // in the caller) A[] is ceilIndex 
    // in the caller
    static int CeilIndex(int []A, int l,
                         int r, int key)
    {
        while (r - l > 1)
        {
            int m = l + (r - l)/2;
              
            if (A[m] >= key)
                r = m;
            else
                l = m;
        }
  
        return r;
    }
  
    static int LongestIncreasingSubsequenceLength(
                                int []A, int size)
    {
          
        // Add boundary case, when array size
        // is one
  
        int []tailTable = new int[size];
        int len; // always points empty slot
  
        tailTable[0] = A[0];
        len = 1;
        for (int i = 1; i < size; i++)
        {
            if (A[i] < tailTable[0])
                // new smallest value
                tailTable[0] = A[i];
  
            else if (A[i] > tailTable[len-1])
              
                // A[i] wants to extend largest 
                // subsequence
                tailTable[len++] = A[i];
  
            else
              
                // A[i] wants to be current end
                // candidate of an existing

1406
Chapter 189. Longest Increasing Subsequence Size (N log N)

                // subsequence. It will replace


                // ceil value in tailTable
                tailTable[CeilIndex(tailTable, -1,
                             len-1, A[i])] = A[i];
        }
  
        return len;
    }
  
    // Driver program to test above function
    public static void Main()
    {
        int []A ={ 2, 5, 3, 7, 11, 8, 10, 13, 6 };
        int n = A.Length;
        Console.Write("Length of Longest "
                 + "Increasing Subsequence is " +
        LongestIncreasingSubsequenceLength(A, n));
    }
}
  
// This code is contributed by nitin mittal.

Output:

Length of Longest Increasing Subsequence is 6

Complexity:
The loop runs for N elements. In the worst case (what is worst case input?), we may end
up querying ceil value using binary search (log i) for many A[i].
Therefore, T(n) < O( log N! ) = O(N log N). Analyse to ensure that the upper and lower
bounds are also O( N log N ). The complexity is THETA (N log N).
Exercises:
1. Design an algorithm to construct the longest increasing list. Also, model your solution
using DAGs.
2. Design an algorithm to construct all increasing lists of equal longest size.
3. Is the above algorithm an online algorithm?
4. Design an algorithm to construct the longest decreasing list..
— Venki. Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Improved By : nitin mittal

1407
Chapter 189. Longest Increasing Subsequence Size (N log N)

Source

https://www.geeksforgeeks.org/longest-monotonically-increasing-subsequence-size-n-log-n/

1408
Chapter 190

Longest Increasing consecutive


subsequence

Longest Increasing consecutive subsequence - GeeksforGeeks


Given N elements, write a program that prints the length of the longest increasing subse-
quence whose adjacent element difference is one.
Examples:

Input : a[] = {3, 10, 3, 11, 4, 5, 6, 7, 8, 12}


Output : 6
Explanation: 3, 4, 5, 6, 7, 8 is the longest increasing subsequence whose adjacent
element differs by one.
Input : a[] = {6, 7, 8, 3, 4, 5, 9, 10}
Output : 5
Explanation: 6, 7, 8, 9, 10 is the longest increasing subsequence

Naive Approach: A normal approach will be to iterate for every element and find out
the longest increasing subsequence. For any particular element, find the length of the
subsequence starting from that element. Print the longest length of the subsequence thus
formed. The time complexity of this approach will be O(n2 ).
Dynamic Programming Approach: Let DP[i] store the length of the longest subse-
quence which ends with A[i]. For every A[i], if A[i]-1 is present in the array before i-th
index, then A[i] will add to the increasing subsequence which has A[i]-1. Hence DP[i] =
DP[ index(A[i]-1) ] + 1. If A[i]-1 is not present in the array before i-th index, then
DP[i]=1 since the A[i] element forms a subsequence which starts with A[i]. Hence the
relation for DP[i] is:

If A[i]-1 is present before i-th index:


DP[i] = DP[ index(A[i]-1) ] + 1

1409
Chapter 190. Longest Increasing consecutive subsequence

else:
DP[i] = 1

Given below is the illustration of the above approach:

// CPP program to find length of the


// longest increasing subsequence
// whose adjacent element differ by 1
#include <bits/stdc++.h>
using namespace std;
  
// function that returns the length of the
// longest increasing subsequence
// whose adjacent element differ by 1
int longestSubsequence(int a[], int n)
{
    // stores the index of elements
    unordered_map<int, int> mp;
  
    // stores the length of the longest 
    // subsequence that ends with a[i]
    int dp[n];
    memset(dp, 0, sizeof(dp)); 
  
    int maximum = INT_MIN;
  
    // iterate for all element
    for (int i = 0; i < n; i++) {
  
        // if a[i]-1 is present before i-th index
        if (mp.find(a[i] - 1) != mp.end()) {
  
            // last index of a[i]-1
            int lastIndex = mp[a[i] - 1] - 1;
  
            // relation
            dp[i] = 1 + dp[lastIndex];
        }
        else
            dp[i] = 1;
  
        // stores the index as 1-index as we need to
        // check for occurrence, hence 0-th index
        // will not be possible to check
        mp[a[i]] = i + 1;
  
        // stores the longest length

1410
Chapter 190. Longest Increasing consecutive subsequence

        maximum = max(maximum, dp[i]);


    }
  
    return maximum;
}
  
// Driver Code
int main()
{
    int a[] = { 3, 10, 3, 11, 4, 5, 6, 7, 8, 12 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << longestSubsequence(a, n);
    return 0;
}

Output:

Time Complexity : O(n)


Auxiliary Space : O(n)

Source

https://www.geeksforgeeks.org/longest-increasing-consecutive-subsequence/

1411
Chapter 191

Longest Palindromic Substring |


Set 1

Longest Palindromic Substring | Set 1 - GeeksforGeeks


Given a string, find the longest substring which is palindrome. For example, if the given
string is “forgeeksskeegfor”, the output should be “geeksskeeg”.
Method 1 ( Brute Force )
The simple approach is to check each substring whether the substring is a palindrome or
not. We can run three loops, the outer two loops pick all substrings one by one by fixing
the corner characters, the inner loop checks whether the picked substring is palindrome or
not.
Time complexity: O ( n^3 )
Auxiliary complexity: O ( 1 )
Method 2 ( Dynamic Programming )
The time complexity can be reduced by storing results of subproblems. The idea is
similar to thispost. We maintain a boolean table[n][n] that is filled in bottom up man-
ner. The value of table[i][j] is true, if the substring is palindrome, otherwise false. To
calculate table[i][j], we first check the value of table[i+1][j-1], if the value is true and str[i]
is same as str[j], then we make table[i][j] true. Otherwise, the value of table[i][j] is made false.

// A dynamic programming solution for longest palindr.


// This code is adopted from following link
// http://www.leetcode.com/2011/11/longest-palindromic-substring-part-i.html
  
#include <stdio.h>
#include <string.h>
  
// A utility function to print a substring str[low..high]

1412
Chapter 191. Longest Palindromic Substring | Set 1

void printSubStr( char* str, int low, int high )


{
    for( int i = low; i <= high; ++i )
        printf("%c", str[i]);
}
  
// This function prints the longest palindrome substring
// of str[].
// It also returns the length of the longest palindrome
int longestPalSubstr( char *str )
{
    int n = strlen( str ); // get length of input string
  
    // table[i][j] will be false if substring str[i..j]
    // is not palindrome.
    // Else table[i][j] will be true
    bool table[n][n];
    memset(table, 0, sizeof(table));
  
    // All substrings of length 1 are palindromes
    int maxLength = 1;
    for (int i = 0; i < n; ++i)
        table[i][i] = true;
  
    // check for sub-string of length 2.
    int start = 0;
    for (int i = 0; i < n-1; ++i)
    {
        if (str[i] == str[i+1])
        {
            table[i][i+1] = true;
            start = i;
            maxLength = 2;
        }
    }
  
    // Check for lengths greater than 2. k is length
    // of substring
    for (int k = 3; k <= n; ++k)
    {
        // Fix the starting index
        for (int i = 0; i < n-k+1 ; ++i)
        {
            // Get the ending index of substring from
            // starting index i and length k
            int j = i + k - 1;
  
            // checking for sub-string from ith index to

1413
Chapter 191. Longest Palindromic Substring | Set 1

            // jth index iff str[i+1] to str[j-1] is a


            // palindrome
            if (table[i+1][j-1] && str[i] == str[j])
            {
                table[i][j] = true;
  
                if (k > maxLength)
                {
                    start = i;
                    maxLength = k;
                }
            }
        }
    }
  
    printf("Longest palindrome substring is: ");
    printSubStr( str, start, start + maxLength - 1 );
  
    return maxLength; // return length of LPS
}
  
// Driver program to test above functions
int main()
{
    char str[] = "forgeeksskeegfor";
    printf("\nLength is: %d\n", longestPalSubstr( str ) );
    return 0;
}

Java

// Java Solution
public class LongestPalinSubstring 
{
    // A utility function to print a substring str[low..high]
    static void printSubStr(String str, int low, int high) {
        System.out.println(str.substring(low, high + 1));
    }
  
    // This function prints the longest palindrome substring
    // of str[].
    // It also returns the length of the longest palindrome
    static int longestPalSubstr(String str) {
        int n = str.length();   // get length of input string
  
        // table[i][j] will be false if substring str[i..j]
        // is not palindrome.
        // Else table[i][j] will be true

1414
Chapter 191. Longest Palindromic Substring | Set 1

        boolean table[][] = new boolean[n][n];


  
        // All substrings of length 1 are palindromes
        int maxLength = 1;
        for (int i = 0; i < n; ++i)
            table[i][i] = true;
  
        // check for sub-string of length 2.
        int start = 0;
        for (int i = 0; i < n - 1; ++i) {
            if (str.charAt(i) == str.charAt(i + 1)) {
                table[i][i + 1] = true;
                start = i;
                maxLength = 2;
            }
        }
          
        // Check for lengths greater than 2. k is length
        // of substring
        for (int k = 3; k <= n; ++k) {
              
                  // Fix the starting index
            for (int i = 0; i < n - k + 1; ++i) 
            {
                // Get the ending index of substring from
                // starting index i and length k
                int j = i + k - 1;
  
                // checking for sub-string from ith index to
                // jth index iff str.charAt(i+1) to 
                // str.charAt(j-1) is a palindrome
                if (table[i + 1][j - 1] && str.charAt(i) == 
                                          str.charAt(j)) {
                    table[i][j] = true;
  
                    if (k > maxLength) {
                        start = i;
                        maxLength = k;
                    }
                }
            }
        }
        System.out.print("Longest palindrome substring is; ");
        printSubStr(str, start, start + maxLength - 1);
          
        return maxLength; // return length of LPS
    }
  

1415
Chapter 191. Longest Palindromic Substring | Set 1

    // Driver program to test above functions


    public static void main(String[] args) {
  
        String str = "forgeeksskeegfor";
        System.out.println("Length is: " + 
                                 longestPalSubstr(str));
    }
}
  
// This code is contributed by Sumit Ghosh

Python

# Python program
  
import sys
  
# A utility function to print a
# substring str[low..high]
def printSubStr(st,low,high) :
    sys.stdout.write(st[low : high + 1])
    sys.stdout.flush()
    return ''
  
# This function prints the longest palindrome
# substring of st[]. It also returns the length
# of the longest palindrome
def longestPalSubstr(st) :
    n = len(st) # get length of input string
  
    # table[i][j] will be false if substring 
    # str[i..j] is not palindrome. Else 
    # table[i][j] will be true
    table = [[0 for x in range(n)] for y
                          in range(n)] 
      
    # All substrings of length 1 are
    # palindromes
    maxLength = 1
    i = 0
    while (i < n) :
        table[i][i] = True
        i = i + 1
      
    # check for sub-string of length 2.
    start = 0
    i = 0
    while i < n - 1 :

1416
Chapter 191. Longest Palindromic Substring | Set 1

        if (st[i] == st[i + 1]) :


            table[i][i + 1] = True
            start = i
            maxLength = 2
        i = i + 1
      
    # Check for lengths greater than 2. 
    # k is length of substring
    k = 3
    while k <= n :
        # Fix the starting index
        i = 0
        while i < (n - k + 1) :
              
            # Get the ending index of 
            # substring from starting 
            # index i and length k
            j = i + k - 1
      
            # checking for sub-string from
            # ith index to jth index iff 
            # st[i+1] to st[(j-1)] is a 
            # palindrome
            if (table[i + 1][j - 1] and 
                      st[i] == st[j]) :
                table[i][j] = True
      
                if (k > maxLength) :
                    start = i
                    maxLength = k
            i = i + 1
        k = k + 1
    print "Longest palindrome substring is: ",printSubStr(st, start,
                                               start + maxLength - 1)
  
    return maxLength # return length of LPS
  
  
# Driver program to test above functions
st = "forgeeksskeegfor"
l = longestPalSubstr(st)
print "Length is:", l
  
# This code is contributed by Nikita Tiwari.

Output:

Longest palindrome substring is: geeksskeeg

1417
Chapter 191. Longest Palindromic Substring | Set 1

Length is: 10

Time complexity: O ( n^2 )


Auxiliary Space: O ( n^2 )
We will soon be adding more optimized methods as separate posts.

Source

https://www.geeksforgeeks.org/longest-palindrome-substring-set-1/

1418
Chapter 192

Longest Repeated Subsequence

Longest Repeated Subsequence - GeeksforGeeks


Given a string, print the longest repeating subsequence such that the two subsequence don’t
have same string character at same position, i.e., any i’th character in the two subsequences
shouldn’t have the same index in the original string.

More Examples:

Input: str = "aabb"


Output: "ab"

Input: str = "aab"


Output: "a"
The two subsequence are 'a'(first) and 'a'
(second). Note that 'b' cannot be considered
as part of subsequence as it would be at same
index in both.

This problem is just the modification of Longest Common Subsequence problem. The idea

1419
Chapter 192. Longest Repeated Subsequence

is to find the LCS(str, str) where str is the input string with the restriction that
when both the characters are same, they shouldn’t be on the same index in the
two strings.
We have discussed a solution to find length of the longest repeated subsequence.

C++

// Refer https://www.geeksforgeeks.org/longest-repeating-subsequence/
// for complete code.
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered. 
int findLongestRepeatingSubSeq(string str)
{
    int n = str.length();
   
    // Create and initialize DP table
    int dp[n+1][n+1];
    for (int i=0; i<=n; i++)
        for (int j=0; j<=n; j++)
            dp[i][j] = 0;
   
    // Fill dp table (similar to LCS loops)
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n; j++)
        {
            // If characters match and indexes are 
            // not same
            if (str[i-1] == str[j-1] && i != j)
                dp[i][j] =  1 + dp[i-1][j-1];          
                        
            // If characters do not match
            else
                dp[i][j] = max(dp[i][j-1], dp[i-1][j]);
        }
    }
    return dp[n][n];
}

Python3

# Python method for Longest Repeated


# Subsequence
  
# Refer https://www.geeksforgeeks.org/longest-repeating-subsequence/

1420
Chapter 192. Longest Repeated Subsequence

# for complete code.


# This fuction mainly returns LCS(str, str)
# with a condition that same characters at
# same index are not considered.
def findLongestRepeatingSubSeq(str):
    n = len(str)
  
    # Create and initialize DP table
    dp = [[0 for k in range(n+1)] for l in range(n+1)]
  
    # Fill dp table (similar to LCS loops)
    for i in range(1, n+1):
        for j in range(1, n+1):
            # If characters match and indices are not same
            if (str[i-1] == str[j-1] and i != j):
                dp[i][j] = 1 + dp[i-1][j-1]
  
            # If characters do not match
            else:
                dp[i][j] = max(dp[i][j-1], dp[i-1][j])
  
    return dp[n][n]
  
# This code is contributed by Soumen Ghosh

How to print the subsequence?


The above solution only finds length of subsequence. We can print the subsequence using
dp[n+1][n+1] table built. The idea is similar to printing LCS.

// Pseudo code to find longest repeated


// subsequence using the dp[][] table filled
// above.

// Initialize result
string res = "";

// Traverse dp[][] from bottom right


i = n, j = n;
while (i > 0 && j > 0)
{
// If this cell is same as diagonally
// adjacent cell just above it, then
// same characters are present at
// str[i-1] and str[j-1]. Append any
// of them to result.
if (dp[i][j] == dp[i-1][j-1] + 1)
{

1421
Chapter 192. Longest Repeated Subsequence

res = res + str[i-1];


i--;
j--;
}

// Otherwise we move to the side


// that that gave us maximum result
else if (dp[i][j] == dp[i-1][j])
i--;
else
j--;
}

// Since we traverse dp[][] from bottom,


// we get result in reverse order.
reverse(res.begin(), res.end());

return res;

Below is implementation of above steps.


C++

// C++ program to find the longest repeated


// subsequence
#include <bits/stdc++.h>
using namespace std;
  
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered.
string longestRepeatedSubSeq(string str)
{
    // THIS PART OF CODE IS SAME AS BELOW POST. 
    // IT FILLS dp[][]
    // https://www.geeksforgeeks.org/longest-repeating-subsequence/
    // OR the code mentioned above.
    int n = str.length();
    int dp[n+1][n+1];
    for (int i=0; i<=n; i++)
        for (int j=0; j<=n; j++)
            dp[i][j] = 0;
    for (int i=1; i<=n; i++)
        for (int j=1; j<=n; j++)
            if (str[i-1] == str[j-1] && i != j)
                dp[i][j] =  1 + dp[i-1][j-1];
            else
                dp[i][j] = max(dp[i][j-1], dp[i-1][j]);

1422
Chapter 192. Longest Repeated Subsequence

  
  
    // THIS PART OF CODE FINDS THE RESULT STRING USING DP[][]
    // Initialize result
    string res = "";
  
    // Traverse dp[][] from bottom right
    int i = n, j = n;
    while (i > 0 && j > 0)
    {
        // If this cell is same as diagonally
        // adjacent cell just above it, then 
        // same characters are present at 
        // str[i-1] and str[j-1]. Append any 
        // of them to result.
        if (dp[i][j] == dp[i-1][j-1] + 1)
        {
           res = res + str[i-1];
           i--;
           j--;
        }
  
        // Otherwise we move to the side
        // that that gave us maximum result
        else if (dp[i][j] == dp[i-1][j])
            i--;
        else
            j--;
    }
  
    // Since we traverse dp[][] from bottom,
    // we get result in reverse order.
    reverse(res.begin(), res.end());
  
    return res;
}
  
// Driver Program
int main()
{
    string str = "AABEBCDD";
    cout << longestRepeatedSubSeq(str);
    return 0;
}

Python3

# Python3 program to find the 

1423
Chapter 192. Longest Repeated Subsequence

# longest repeated subsequence


  
# This function mainly returns LCS(str, str) 
# with a condition that same characters 
# at same index are not considered.
def longestRepeatedSubSeq(str):
    # This part of code is same as 
    # below post it fills dp[][]
    # https://www.geeksforgeeks.org/longest-repeating-subsequence/
    # OR the code mentioned above
    n = len(str)
    dp = [[0 for i in range(n+1)] for j in range(n+1)]
      
    for i in range(1, n + 1):
        for j in range(1, n + 1):
            if (str[i-1] == str[j-1] and i != j):
                dp[i][j] = 1 + dp[i-1][j-1]
            else:
                dp[i][j] = max(dp[i][j-1], dp[i-1][j])
  
    # This part of code finds the result
    # string using dp[][] Initialize result
    res = ''
  
    # Traverse dp[][] from bottom right
    i = n
    j = n
    while (i > 0 and j > 0):
        # If this cell is same as diagonally
        # adjacent cell just above it, then
        # same characters are present at
        # str[i-1] and str[j-1]. Append any
        # of them to result.
        if (dp[i][j] == dp[i-1][j-1] + 1):
            res += str[i-1]
            i -= 1
            j -= 1
  
        # Otherwise we move to the side
        # that gave us maximum result.
        elif (dp[i][j] == dp[i-1][j]):
            i -= 1
        else:
            j -= 1
  
    # Since we traverse dp[][] from bottom,
    # we get result in reverse order.
    res = ''.join(reversed(res))

1424
Chapter 192. Longest Repeated Subsequence

      
    return res
      
# Driver Program
str = 'AABEBCDD'
print(longestRepeatedSubSeq(str))
  
# This code is contributed by Soumen Ghosh

Output:

ABD

Time Complexity : O(n2 )


Auxiliary Space : O(n2 )

Source

https://www.geeksforgeeks.org/longest-repeated-subsequence/

1425
Chapter 193

Longest Repeating Subsequence

Longest Repeating Subsequence - GeeksforGeeks


Given a string, find length of the longest repeating subseequence such that the two subse-
quence don’t have same string character at same position, i.e., any i’th character in the two
subsequences shouldn’t have the same index in the original string.

Examples:

Input: str = "abc"


Output: 0
There is no repeating subsequence

Input: str = "aab"


Output: 1
The two subssequence are 'a'(first) and 'a'(second).
Note that 'b' cannot be considered as part of subsequence

1426
Chapter 193. Longest Repeating Subsequence

as it would be at same index in both.

Input: str = "aabb"


Output: 2

Input: str = "axxxy"


Output: 2

This problem is just the modification of Longest Common Subsequence problem. The idea
is to find the LCS(str, str)where str is the input string with the restriction that
when both the characters are same, they shouldn’t be on the same index in the
two strings.
Below is the implementation of the idea.
C++

// C++ program to find the longest repeating


// subsequence
#include <iostream>
#include <string>
using namespace std;
  
// This function mainly returns LCS(str, str)
// with a condition that same characters at
// same index are not considered. 
int findLongestRepeatingSubSeq(string str)
{
    int n = str.length();
  
    // Create and initialize DP table
    int dp[n+1][n+1];
    for (int i=0; i<=n; i++)
        for (int j=0; j<=n; j++)
            dp[i][j] = 0;
  
    // Fill dp table (similar to LCS loops)
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=n; j++)
        {
            // If characters match and indexes are 
            // not same
            if (str[i-1] == str[j-1] && i != j)
                dp[i][j] =  1 + dp[i-1][j-1];          
                       
            // If characters do not match
            else
                dp[i][j] = max(dp[i][j-1], dp[i-1][j]);

1427
Chapter 193. Longest Repeating Subsequence

        }
    }
    return dp[n][n];
}
  
// Driver Program
int main()
{
    string str = "aabb";
    cout << "The length of the largest subsequence that"
            " repeats itself is : "
        << findLongestRepeatingSubSeq(str);
    return 0;
}

Java

// Java program to find the longest 


// repeating subsequence
import java.io.*;
import java.util.*;
  
class LRS 
{
    // Function to find the longest repeating subsequence
    static int findLongestRepeatingSubSeq(String str)
    {
        int n = str.length();
   
        // Create and initialize DP table
        int[][] dp = new int[n+1][n+1];
   
        // Fill dp table (similar to LCS loops)
        for (int i=1; i<=n; i++)
        {
            for (int j=1; j<=n; j++)
            {
                // If characters match and indexes are not same
                if (str.charAt(i-1) == str.charAt(j-1) && i!=j)
                    dp[i][j] =  1 + dp[i-1][j-1];          
                        
                // If characters do not match
                else
                    dp[i][j] = Math.max(dp[i][j-1], dp[i-1][j]);
            }
        }
        return dp[n][n];
    }

1428
Chapter 193. Longest Repeating Subsequence

      
    // driver program to check above function
    public static void main (String[] args) 
    {
        String str = "aabb";
        System.out.println("The length of the largest subsequence that"
            +" repeats itself is : "+findLongestRepeatingSubSeq(str));
    }
}
  
// This code is contributed by Pramod Kumar

C#

// C# program to find the longest repeating 


// subsequence
using System;
  
class GFG {
      
    // Function to find the longest repeating
    // subsequence
    static int findLongestRepeatingSubSeq(string str)
    {
        int n = str.Length;
  
        // Create and initialize DP table
        int [,]dp = new int[n+1,n+1];
  
        // Fill dp table (similar to LCS loops)
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= n; j++)
            {
                  
                // If characters match and indexes
                // are not same
                if (str[i-1] == str[j-1] && i != j)
                    dp[i,j] = 1 + dp[i-1,j-1];         
                          
                // If characters do not match
                else
                    dp[i,j] = Math.Max(dp[i,j-1], 
                                       dp[i-1,j]);
            }
        }
        return dp[n,n];
    }

1429
Chapter 193. Longest Repeating Subsequence

      
    // driver program to check above function
    public static void Main () 
    {
        string str = "aabb";
        Console.Write("The length of the largest "
         + "subsequence that repeats itself is : "
               + findLongestRepeatingSubSeq(str));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to find the 
// longest repeating subsequence
  
// This function mainly returns 
// LCS(str, str) with a condition 
// that same characters at same 
// index are not considered. 
function findLongestRepeatingSubSeq($str)
{
    $n = strlen($str);
  
    // Create and initialize
    // DP table
    $dp = array(array());
    for ($i = 0; $i <= $n; $i++)
        for ($j = 0; $j <= $n; $j++)
            $dp[$i][$j] = 0;
  
    // Fill dp table 
    // (similar to LCS loops)
    for ($i = 1; $i <= $n; $i++)
    {
        for ($j = 1; $j <= $n; $j++)
        {
            // If characters match and 
            // indexes are not same
            if ($str[$i - 1] == $str[$j - 1] && 
                                $i != $j)
                $dp[$i][$j] = 1 + $dp[$i - 1][$j - 1];     
                      
            // If characters 
            // do not match

1430
Chapter 193. Longest Repeating Subsequence

            else
                $dp[$i][$j] = max($dp[$i][$j - 1], 
                                  $dp[$i - 1][$j]);
        }
    }
    return $dp[$n][$n];
}
  
// Driver Code
$str = "aabb";
echo "The length of the largest ". 
     "subsequence that repeats itself is : ",
            findLongestRepeatingSubSeq($str);
  
// This code is contributed
// by shiv_bhakt.
?>

Output:

The length of the largest subsequence that repeats itself is : 2

This article is contributed by Ekta Goel. Please write comments if you find anything incor-
rect, or you want to share more information about the topic discussed above.
Improved By : nitin mittal, shiv_bhakt

Source

https://www.geeksforgeeks.org/longest-repeating-subsequence/

1431
Chapter 194

Longest Zig-Zag Subsequence

Longest Zig-Zag Subsequence - GeeksforGeeks


The longest Zig-Zag subsequence problem is to find length of the longest subsequence of
given sequence such that all elements of this are alternating.
If a sequence {x1, x2, .. xn} is alternating sequence then its element satisfy one of the
following relation :

x1 < x2 > x3 < x4 > x5 < …. xn or


x1 > x2 < x3 > x4 < x5 > …. xn

Examples :

Input: arr[] = {1, 5, 4}


Output: 3
The whole arrays is of the form x1 < x2 > x3

Input: arr[] = {1, 4, 5}


Output: 2
All subsequences of length 2 are either of the form
x1 < x2; or x1 > x2

Input: arr[] = {10, 22, 9, 33, 49, 50, 31, 60}


Output: 6
The subsequences {10, 22, 9, 33, 31, 60} or
{10, 22, 9, 49, 31, 60} or {10, 22, 9, 50, 31, 60}
are longest Zig-Zag of length 6.

This problem is an extension of longest increasing subsequence problem, but requires more
thinking for finding optimal substructure property in this.

1432
Chapter 194. Longest Zig-Zag Subsequence

We will solve this problem by dynamic Programming method, Let A is given array of
length n of integers. We define a 2D array Z[n][2] such that Z[i][0] contains longest Zig-Zag
subsequence ending at index i and last element is greater than its previous element and
Z[i][1] contains longest Zig-Zag subsequence ending at index i and last element is smaller
than its previous element, then we have following recurrence relation between them,

Z[i][0] = Length of the longest Zig-Zag subsequence


ending at index i and last element is greater
than its previous element
Z[i][1] = Length of the longest Zig-Zag subsequence
ending at index i and last element is smaller
than its previous element

Recursive Formulation:
Z[i][0] = max (Z[i][0], Z[j][1] + 1);
for all j < i and A[j] < A[i]
Z[i][1] = max (Z[i][1], Z[j][0] + 1);
for all j < i and A[j] > A[i]

The first recurrence relation is based on the fact that, If we are at position i and this
element has to bigger than its previous element then for this sequence (upto i) to be bigger
we will try to choose an element j ( < i) such that A[j] < A[i] i.e. A[j] can become A[i]’s
previous element and Z[j][1] + 1 is bigger than Z[i][0] then we will update Z[i][0].
Remember we have chosen Z[j][1] + 1 not Z[j][0] + 1 to satisfy alternate property because
in Z[j][0] last element is bigger than its previous one and A[i] is greater than A[j] which will
break the alternating property if we update. So above fact derives first recurrence relation,
similar argument can be made for second recurrence relation also.

// C program to find longest Zig-Zag subsequence in


// an array
#include <stdio.h>
#include <stdlib.h>
  
// function to return max of two numbers
int max(int a, int b) {  return (a > b) ? a : b; }
  
// Function to return longest Zig-Zag subsequence length
int zzis(int arr[], int n)
{
    /*Z[i][0] = Length of the longest Zig-Zag subsequence
          ending at index i and last element is greater
          than its previous element
     Z[i][1] = Length of the longest Zig-Zag subsequence
          ending at index i and last element is smaller
          than its previous element   */

1433
Chapter 194. Longest Zig-Zag Subsequence

    int Z[n][2];
  
    /* Initialize all values from 1  */
    for (int i = 0; i < n; i++)
        Z[i][0] = Z[i][1] = 1;
  
    int res = 1; // Initialize result
  
    /* Compute values in bottom up manner */
    for (int i = 1; i < n; i++)
    {
        // Consider all elements as previous of arr[i]
        for (int j = 0; j < i; j++)
        {
            // If arr[i] is greater, then check with Z[j][1]
            if (arr[j] < arr[i] && Z[i][0] < Z[j][1] + 1)
                Z[i][0] = Z[j][1] + 1;
  
            // If arr[i] is smaller, then check with Z[j][0]
            if( arr[j] > arr[i] && Z[i][1] < Z[j][0] + 1)
                Z[i][1] = Z[j][0] + 1;
        }
  
        /* Pick maximum of both values at index i  */
        if (res < max(Z[i][0], Z[i][1]))
            res = max(Z[i][0], Z[i][1]);
    }
  
    return res;
}
  
/* Driver program */
int main()
{
    int arr[] = { 10, 22, 9, 33, 49, 50, 31, 60 };
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Length of Longest Zig-Zag subsequence is %d\n",
            zzis(arr, n) );
    return 0;
}

Java

// Java program to find longest


// Zig-Zag subsequence in an array
import java.io.*;
  
class GFG {

1434
Chapter 194. Longest Zig-Zag Subsequence

  
// Function to return longest 
// Zig-Zag subsequence length
static int zzis(int arr[], int n)
{
    /*Z[i][0] = Length of the longest 
        Zig-Zag subsequence ending at
        index i and last element is 
        greater than its previous element
    Z[i][1] = Length of the longest 
        Zig-Zag subsequence ending at
        index i and last element is 
        smaller than its previous 
        element */
    int Z[][] = new int[n][2];
  
    /* Initialize all values from 1 */
    for (int i = 0; i < n; i++)
        Z[i][0] = Z[i][1] = 1;
  
    int res = 1; // Initialize result
  
    /* Compute values in bottom up manner */
    for (int i = 1; i < n; i++)
    {
        // Consider all elements as 
        // previous of arr[i]
        for (int j = 0; j < i; j++)
        {
            // If arr[i] is greater, then 
            // check with Z[j][1]
            if (arr[j] < arr[i] && 
                Z[i][0] < Z[j][1] + 1)
                Z[i][0] = Z[j][1] + 1;
  
            // If arr[i] is smaller, then
            // check with Z[j][0]
            if( arr[j] > arr[i] &&
              Z[i][1] < Z[j][0] + 1)
                Z[i][1] = Z[j][0] + 1;
        }
  
        /* Pick maximum of both values at
        index i */
        if (res < Math.max(Z[i][0], Z[i][1]))
            res = Math.max(Z[i][0], Z[i][1]);
    }
  

1435
Chapter 194. Longest Zig-Zag Subsequence

    return res;
}
  
/* Driver program */
public static void main(String[] args)
{
    int arr[] = { 10, 22, 9, 33, 49, 
                  50, 31, 60 };
    int n = arr.length;
    System.out.println("Length of Longest "+
                    "Zig-Zag subsequence is " +
                    zzis(arr, n));
}
}
// This code is contributed by Prerna Saini

C#

// C# program to find longest


// Zig-Zag subsequence in an array
using System;
  
class GFG
{
      
// Function to return longest 
// Zig-Zag subsequence length
static int zzis(int []arr, int n)
{
    /*Z[i][0] = Length of the longest 
        Zig-Zag subsequence ending at
        index i and last element is 
        greater than its previous element
    Z[i][1] = Length of the longest 
        Zig-Zag subsequence ending at
        index i and last element is 
        smaller than its previous 
        element */
    int [,]Z = new int[n, 2];
  
    /* Initialize all values from 1 */
    for (int i = 0; i < n; i++)
        Z[i, 0] = Z[i, 1] = 1;
  
    // Initialize result
    int res = 1; 
  
    /* Compute values in

1436
Chapter 194. Longest Zig-Zag Subsequence

    bottom up manner */
    for (int i = 1; i < n; i++)
    {
        // Consider all elements as 
        // previous of arr[i]
        for (int j = 0; j < i; j++)
        {
            // If arr[i] is greater, then 
            // check with Z[j][1]
            if (arr[j] < arr[i] && 
                Z[i, 0] < Z[j, 1] + 1)
                Z[i, 0] = Z[j, 1] + 1;
                  
            // If arr[i] is smaller, then
            // check with Z[j][0]
            if( arr[j] > arr[i] &&
            Z[i, 1] < Z[j, 0] + 1)
                Z[i, 1] = Z[j, 0] + 1;
        }
  
        /* Pick maximum of both values at
        index i */
        if (res < Math.Max(Z[i, 0], Z[i, 1]))
            res = Math.Max(Z[i, 0], Z[i, 1]);
    }
  
    return res;
}
  
// Driver Code 
static public void Main ()
{
    int []arr = {10, 22, 9, 33, 
                 49, 50, 31, 60};
    int n = arr.Length;
    Console.WriteLine("Length of Longest "+
                      "Zig-Zag subsequence is " +
                                   zzis(arr, n));
    }
}
  
// This code is contributed by ajit

PHP

<?php
//PHP program to find longest Zig-Zag 
//subsequence in  an array

1437
Chapter 194. Longest Zig-Zag Subsequence

  
// function to return max of two numbers
function  maxD($a, $b) {
    return ($a > $b) ? $a : $b;
    }
  
// Function to return longest Zig-Zag subsequence length
function  zzis($arr, $n)
{
    /*Z[i][0] = Length of the longest Zig-Zag subsequence
        ending at index i and last element is greater
        than its previous element
    Z[i][1] = Length of the longest Zig-Zag subsequence
        ending at index i and last element is smaller
        than its previous element */
     //$Z[$n][2];
  
    /* Initialize all values from 1 */
    for ($i = 0; $i < $n; $i++)
        $Z[$i][0] = $Z[$i][1] = 1;
  
     $res = 1; // Initialize result
  
    /* Compute values in bottom up manner */
    for ($i = 1; $i < $n; $i++)
    {
        // Consider all elements as previous of arr[i]
        for ($j = 0; $j < $i; $j++)
        {
            // If arr[i] is greater, then check with Z[j][1]
            if ($arr[$j] < $arr[$i] && $Z[$i][0] < $Z[$j][1] + 1)
                $Z[$i][0] = $Z[$j][1] + 1;
  
            // If arr[i] is smaller, then check with Z[j][0]
            if( $arr[$j] > $arr[$i] && $Z[$i][1] < $Z[$j][0] + 1)
                $Z[$i][1] = $Z[$j][0] + 1;
        }
  
        /* Pick maximum of both values at index i */
        if ($res < max($Z[$i][0], $Z[$i][1]))
            $res = max($Z[$i][0], $Z[$i][1]);
    }
  
    return $res;
}
  
/* Driver program */
  

1438
Chapter 194. Longest Zig-Zag Subsequence

     $arr = array( 10, 22, 9, 33, 49, 50, 31, 60 );


    $n = sizeof($arr);
    echo "Length of Longest Zig-Zag subsequence is ",
            zzis($arr, $n) ;
    echo "\n";
  
  
  
#This code is contributed by aj_36
?>

Output :

Length of Longest Zig-Zag subsequence is 6

Time Complexity : O(n2 )


Auxiliary Space : O(n)
This article is contributed by Utkarsh Trivedi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : jit_t

Source

https://www.geeksforgeeks.org/longest-zig-zag-subsequence/

1439
Chapter 195

Longest alternating (positive


and negative) subarray starting
at every index

Longest alternating (positive and negative) subarray starting at every index - GeeksforGeeks
A subarray is called alternating if any two consecutive numbers in it have opposite signs (i.e.
one of them should be negative, whereas the other should be positive).
Given an array of n integers. For each index i, we need to find the length if the longest
alternating subarray starting at i.
Examples:

Input : a[] = {1, -5, 1, -5}


Output : For index 0, {1, -5, 1, -5} = 4
index 1, {-5, 1, -5} = 3
index 2, {1, -5} = 2
index 3, {-5} = 1.

Input :a[] = {-5, -1, -1, 2, -2, -3}


Output : index 0 = 1,
index 1 = 1,
index 2 = 3,
index 3 = 2,
index 4 = 1,
index 5 = 1,

A Naive approach is to use two loops in which we traverse the whole array starting from
every index i (0 to n-1) and calculate the length of the alternating subarray.
Time Complexity: O(n2 ).

1440
Chapter 195. Longest alternating (positive and negative) subarray starting at every index

Efficient Approach:
Observe that when a[i] and a[i+1] have opposite signs, count[i] will be 1 more than
count[i+1]. Otherwise when they have same sign count[i] will be 1.
We use Dynamic Programminghere.

C++

// CPP program to find longest alternating


// subarray starting from every index.
#include <bits/stdc++.h>
using namespace std;
  
void longestAlternating(int arr[], int n)
{
    int count[n];
  
    // Fill count[] from end. 
    count[n - 1] = 1;
    for (int i = n - 2; i >= 0; i--) {
        if (arr[i] * arr[i + 1] < 0)
            count[i] = count[i + 1] + 1;
        else
            count[i] = 1;
    }
  
    // Print result
    for (int i = 0; i < n; i++)
        cout << count[i] << " ";
}
  
// Driver code
int main()
{
    int a[] = { -5, -1, -1, 2, -2, -3 };
    int n = sizeof(a) / sizeof(a[0]);
    longestAlternating(a, n);
    return 0;
}

Java

// Java program to find longest alternating


// subarray starting from every index.
import java.util.*;
  
class Longest{

1441
Chapter 195. Longest alternating (positive and negative) subarray starting at every index

      
    public static void longestAlternating(int arr[], 
                                             int n)
    {
        int[] count = new int[n];
  
        // Fill count[] from end. 
        count[n - 1] = 1;
        for (int i = n - 2; i >= 0; i--) {
            if (arr[i] * arr[i + 1] < 0)
                count[i] = count[i + 1] + 1;
            else
                count[i] = 1;
        }
  
        // Print result
        for (int i = 0; i < n; i++)
            System.out.print(count[i] + " ");
    }
      
    // driver program
    public static void main(String[] args)
    {
        int a[] = { -5, -1, -1, 2, -2, -3 };
        int n = 6;
        longestAlternating(a, n);
    }
}
  
// This code is contributed by rishabh_jain

Python3

# Python3 program to find longest alternating


# subarray starting from every index.
  
def longestAlternating(arr, n) :
    count = [None] * n
  
    # Fill count[] from end. 
    count[n - 1] = 1
    i = n - 2
      
    while i >= 0 :
        if (arr[i] * arr[i + 1] < 0) :
            count[i] = count[i + 1] + 1
        else :
            count[i] = 1;

1442
Chapter 195. Longest alternating (positive and negative) subarray starting at every index

        i = i - 1
  
    i = 0
      
    # Print result
    while i < n :
        print (count[i], end = " ")
        i = i + 1
  
# Driver Code
a = [ -5, -1, -1, 2, -2, -3 ]
n = len(a)
longestAlternating(a, n);
  
  
# This code is contributed by rishabh_jain 

C#

//C# program to find longest alternating


// subarray starting from every index.
using System;
  
class Longest
{
      
    public static void longestAlternating(int []arr, 
                                            int n)
    {
        int[] count = new int[n];
  
        // Fill count[] from end. 
        count[n - 1] = 1;
        for (int i = n - 2; i >= 0; i--) 
        {
            if (arr[i] * arr[i + 1] < 0)
                count[i] = count[i + 1] + 1;
            else
                count[i] = 1;
        }
  
        // Print result
        for (int i = 0; i < n; i++)
            Console.Write(count[i] + " ");
    }
      
    // Driver program
    public static void Main()

1443
Chapter 195. Longest alternating (positive and negative) subarray starting at every index

    {
        int []a = { -5, -1, -1, 2, -2, -3 };
        int n = 6;
        longestAlternating(a, n);
    }
}
  
// This code is contributed by vt_m

PHP

<?php
// PHP program to find longest alternating
// subarray starting from every index.
  
function longestAlternating( $arr, $n)
{
    $count = array();
  
    // Fill count[] from end. 
    $count[$n - 1] = 1;
    for ( $i = $n - 2; $i >= 0; $i--) 
    {
        if ($arr[$i] * $arr[$i + 1] < 0)
            $count[$i] = $count[$i + 1] + 1;
        else
            $count[$i] = 1;
    }
  
    // Print result
    for ( $i = 0; $i < $n; $i++)
        echo $count[$i] , " ";
}
  
    // Driver code
    $a = array( -5, -1, -1, 2, -2, -3 );
    $n =count($a);
    longestAlternating($a, $n);
  
// This code is contributed by anuj_67.
?>

Output:

1 1 3 2 1 1

Improved By : vt_m

1444
Chapter 195. Longest alternating (positive and negative) subarray starting at every index

Source

https://www.geeksforgeeks.org/longest-alternating-positive-negative-subarray-starting-every-index/

1445
Chapter 196

Longest alternating sub-array


starting from every index in a
Binary Array

Longest alternating sub-array starting from every index in a Binary Array - GeeksforGeeks
Given an array containing only 0s and 1s. For each index ‘i‘(0 index), find length of the
longest alternating sub-array starting from ‘i‘ to ‘j‘ i.e., ai..j for i <= j < n. Alternating
sub-array means that any two adjacent elements should be different.

Input: arr[] = {1, 0, 1, 0, 0, 1}


Output: 4 3 2 1 2 1
Explanation
Length for index '0': {1 0 1 0} => 4
Length for index '1': {0 1 0} => 3
Length for index '2': {1 0} => 2
Length for index '3': {0} => 1
Length for index '4': {0 1} => 2
Length for index '5': {1} => 1

Simple approach is to iterate for every index by using two ‘for loops’ for finding the length
of each index. The outer loop picks a starting point ‘i’ and the inner loop considers all sub-
arrays starting from ‘i’. Time complexity of this approach is O(n2 ) which is not sufficient
for large value of ‘n’.
Better approach is to use Dynamic programming. First of all, let’s see how to check
for alternating sub-array. To check whether two elements are alternating or not, we can
simply take XOR(Ex-OR) of both of them and then compare with ‘0’ and ‘1’.

• If there XOR is ‘0’, that means both numbers are not alternating(equal elements).

1446
Chapter 196. Longest alternating sub-array starting from every index in a Binary Array

• If there XOR is ‘1’, that means both are alternating(different elements)

Let len[i] denotes length of an alternating sub-array starting at position ‘i’. If arr[i] and
arr[i+1] have different values, then len[i] will be one more than len[i+1]. Otherwise if they
are same elements, len[i] will be just 1.

C++

// C++ program to calculate longest alternating


// sub-array for each index elements
#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate alternating sub-
// array for each index of array elements
void alternateSubarray(bool arr[], int n)
{
    int len[n];
  
    // Initialize the base state of len[]
    len[n - 1] = 1;
  
    // Calculating value for each element
    for (int i = n - 2; i >= 0; --i) {
        // If both elements are different
        // then add 1 to next len[i+1]
        if (arr[i] ^ arr[i + 1] == 1)
            len[i] = len[i + 1] + 1;
  
        // else initialize to 1
        else
            len[i] = 1;
    }
  
    // Print lengths of binary subarrays.
    for (int i = 0; i < n; ++i)
        cout << len[i] << " ";
}
  
// Driver program
int main()
{
    bool arr[] = { 1, 0, 1, 0, 0, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    alternateSubarray(arr, n);
    return 0;
}

1447
Chapter 196. Longest alternating sub-array starting from every index in a Binary Array

Java

// Java program to calculate longest alternating


// sub-array for each index elements
  
class GFG {
      
// Function to calculate alternating sub-
// array for each index of array elements
static void alternateSubarray(boolean arr[], int n) 
{
    int len[] = new int[n];
  
    // Initialize the base state of len[]
    len[n - 1] = 1;
  
    // Calculating value for each element
    for (int i = n - 2; i >= 0; --i) {
          
    // If both elements are different
    // then add 1 to next len[i+1]
    if (arr[i] ^ arr[i + 1] == true)
        len[i] = len[i + 1] + 1;
  
    // else initialize to 1
    else
        len[i] = 1;
    }
  
    // Print lengths of binary subarrays.
    for (int i = 0; i < n; ++i)
    System.out.print(len[i] + " ");
}
  
// Driver code
public static void main(String[] args) 
{
    boolean arr[] = {true, false, true, false, false, true};
    int n = arr.length;
    alternateSubarray(arr, n);
}
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python program to calculate

1448
Chapter 196. Longest alternating sub-array starting from every index in a Binary Array

# longest alternating
# sub-array for each index elements
  
# Function to calculate alternating sub-
# array for each index of array elements
def alternateSubarray(arr,n):
  
    len=[]
    for i in range(n+1):
        len.append(0)
          
    # Initialize the base state of len[]
    len[n - 1] = 1
   
    # Calculating value for each element
    for i in range(n - 2,-1,-1):
          
        # If both elements are different
        # then add 1 to next len[i+1]
        if (arr[i] ^ arr[i + 1] == True):
            len[i] = len[i + 1] + 1
   
        # else initialize to 1
        else:
            len[i] = 1
      
   
    # Print lengths of binary subarrays.
    for i in range(n):
        print(len[i] , " ",end="")
   
# Driver code
  
arr = [ True,False, True, False, False, True ]
n = len(arr)
  
alternateSubarray(arr, n)
  
# This code is contributed
# by Anant Agarwal.

C#

// C# program to calculate longest 


// alternating sub-array for each 
// index elements
using System;
  

1449
Chapter 196. Longest alternating sub-array starting from every index in a Binary Array

class GFG {
      
    // Function to calculate alternating sub-
    // array for each index of array elements
    static void alternateSubarray(bool []arr,
                                        int n) 
    {
          
        int []len = new int[n];
      
        // Initialize the base state of len[]
        len[n - 1] = 1;
      
        // Calculating value for each element
        for (int i = n - 2; i >= 0; --i)
        {
              
            // If both elements are different
            // then add 1 to next len[i+1]
            if (arr[i] ^ arr[i + 1] == true)
                len[i] = len[i + 1] + 1;
          
            // else initialize to 1
            else
                len[i] = 1;
        }
      
        // Print lengths of binary subarrays.
        for (int i = 0; i < n; ++i)
            Console.Write(len[i] + " ");
    }
      
    // Driver code
    public static void Main() 
    {
        bool []arr = {true, false, true, 
                         false, false, true};
        int n = arr.Length;
          
        alternateSubarray(arr, n);
    }
}
  
// This code is contributed by vt_m.

Output :

1450
Chapter 196. Longest alternating sub-array starting from every index in a Binary Array

4 3 2 1 2 1

Time complexity: O(n)


Auxiliary space: O(n)
Another Efficient approach is, instead of storing all the sub-array elements in len[]
array, we can directly print it until mismatch(equal adjacent elements) is found. When a
mismatch is found, we print count from current value to 0.

C++

// C++ program to calculate longest alternating


// sub-array for each index elements
#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate alternating sub-array
// for each index of array elements
void alternateSubarray(bool arr[], int n)
{
    // Initialize count variable for storing
    // length of sub-array
    int count = 1;
  
    // Initialize 'prev' variable which
    // indicates the previous element
    // while traversing for index 'i'
    int prev = arr[0];
    for (int i = 1; i < n; ++i) {
  
        // If both elements are same
        // print elements because alternate
        // element is not found for current
        // index
        if ((arr[i] ^ prev) == 0)
        {
            // print count and decrement it.
            while (count)
                cout << count-- << " ";
        }
  
        // Increment count for next element
        ++count;
  
        // Re-initialize previous variable
        prev = arr[i];
    }
  

1451
Chapter 196. Longest alternating sub-array starting from every index in a Binary Array

    // If elements are still available after


    // traversing whole array, print it
    while (count)
        cout << count-- << " ";
}
  
// Driver program
int main()
{
    bool arr[] = { 1, 0, 1, 0, 0, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    alternateSubarray(arr, n);
    return 0;
}

PHP

<?php
// PHP program to calculate longest alternating
// sub-array for each index elements
  
// Function to calculate alternating sub-array
// for each index of array elements
function alternateSubarray($arr, $n)
{
      
    // Initialize count variable for storing
    // length of sub-array
    $count = 1;
  
    // Initialize 'prev' variable which
    // indicates the previous element
    // while traversing for index 'i'
    $prev = $arr[0];
    for ($i = 1; $i < $n; ++$i)
    {
  
        // If both elements are same
        // print elements because alternate
        // element is not found for current
        // index
        if (($arr[$i] ^ $prev) == 0)
        {
            // print count and decrement it.
            while ($count)
                echo $count-- , " ";
        }
  

1452
Chapter 196. Longest alternating sub-array starting from every index in a Binary Array

        // Increment count for next element


        ++$count;
  
        // Re-initialize previous variable
        $prev = $arr[$i];
    }
  
    // If elements are still available after
    // traversing whole array, print it
    while ($count)
        echo $count-- , " ";
}
  
    // Driver Code
    $arr = array(1, 0, 1, 0, 0, 1);
    $n = sizeof($arr) ;
    alternateSubarray($arr, $n);
      
// This code is contributed by jit_t.
?>

Output :

4 3 2 1 2 1

Time complexity: O(n)


Auxiliary space: O(1)
Improved By : vt_m, jit_t

Source

https://www.geeksforgeeks.org/longest-alternating-sub-array-starting-every-index-binary-array/

1453
Chapter 197

Longest alternating subsequence

Longest alternating subsequence - GeeksforGeeks


A sequence {x1, x2, .. xn} is alternating sequence if its elements satisfy one of the following
relations :

x1 < x2 > x3 < x4 > x5 < …. xn or


x1 > x2 < x3 > x4 < x5 > …. xn

Examples :

Input: arr[] = {1, 5, 4}


Output: 3
The whole arrays is of the form x1 < x2 > x3

Input: arr[] = {1, 4, 5}


Output: 2
All subsequences of length 2 are either of the form
x1 < x2; or x1 > x2

Input: arr[] = {10, 22, 9, 33, 49, 50, 31, 60}


Output: 6
The subsequences {10, 22, 9, 33, 31, 60} or
{10, 22, 9, 49, 31, 60} or {10, 22, 9, 50, 31, 60}
are longest subsequence of length 6.

This problem is an extension of longest increasing subsequence problem, but requires more
thinking for finding optimal substructure property in this.
We will solve this problem by dynamic Programming method, Let A is given array of length
n of integers. We define a 2D array las[n][2] such that las[i][0] contains longest alternating

1454
Chapter 197. Longest alternating subsequence

subsequence ending at index i and last element is greater than its previous element and
las[i][1] contains longest alternating subsequence ending at index i and last element is smaller
than its previous element, then we have following recurrence relation between them,

las[i][0] = Length of the longest alternating subsequence


ending at index i and last element is greater
than its previous element
las[i][1] = Length of the longest alternating subsequence
ending at index i and last element is smaller
than its previous element

Recursive Formulation:
las[i][0] = max (las[i][0], las[j][1] + 1);
for all j < i and A[j] < A[i]
las[i][1] = max (las[i][1], las[j][0] + 1);
for all j < i and A[j] > A[i]

The first recurrence relation is based on the fact that, If we are at position i and this
element has to bigger than its previous element then for this sequence (upto i) to be bigger
we will try to choose an element j ( < i) such that A[j] < A[i] i.e. A[j] can become A[i]’s
previous element and las[j][1] + 1 is bigger than las[i][0] then we will update las[i][0].
Remember we have chosen las[j][1] + 1 not las[j][0] + 1 to satisfy alternate property because
in las[j][0] last element is bigger than its previous one and A[i] is greater than A[j] which
will break the alternating property if we update. So above fact derives first recurrence
relation, similar argument can be made for second recurrence relation also.

// C program to find longest alternating subsequence in


// an array
#include <stdio.h>
#include <stdlib.h>
  
// function to return max of two numbers
int max(int a, int b) {  return (a > b) ? a : b; }
  
// Function to return longest alternating subsequence length
int zzis(int arr[], int n)
{
    /*las[i][0] = Length of the longest alternating subsequence
          ending at index i and last element is greater
          than its previous element
     las[i][1] = Length of the longest alternating subsequence
          ending at index i and last element is smaller
          than its previous element   */
    int las[n][2];
  

1455
Chapter 197. Longest alternating subsequence

    /* Initialize all values from 1  */


    for (int i = 0; i < n; i++)
        las[i][0] = las[i][1] = 1;
  
    int res = 1; // Initialize result
  
    /* Compute values in bottom up manner */
    for (int i = 1; i < n; i++)
    {
        // Consider all elements as previous of arr[i]
        for (int j = 0; j < i; j++)
        {
            // If arr[i] is greater, then check with las[j][1]
            if (arr[j] < arr[i] && las[i][0] < las[j][1] + 1)
                las[i][0] = las[j][1] + 1;
  
            // If arr[i] is smaller, then check with las[j][0]
            if( arr[j] > arr[i] && las[i][1] < las[j][0] + 1)
                las[i][1] = las[j][0] + 1;
        }
  
        /* Pick maximum of both values at index i  */
        if (res < max(las[i][0], las[i][1]))
            res = max(las[i][0], las[i][1]);
    }
  
    return res;
}
  
/* Driver program */
int main()
{
    int arr[] = { 10, 22, 9, 33, 49, 50, 31, 60 };
    int n = sizeof(arr)/sizeof(arr[0]);
    printf("Length of Longest alternating subsequence is %d\n",
            zzis(arr, n) );
    return 0;
}

Java

// Java program to find longest


// alternating subsequence in an array
import java.io.*;
  
class GFG {
  
// Function to return longest 

1456
Chapter 197. Longest alternating subsequence

// alternating subsequence length


static int zzis(int arr[], int n)
{
    /*las[i][0] = Length of the longest 
        alternating subsequence ending at
        index i and last element is 
        greater than its previous element
    las[i][1] = Length of the longest 
        alternating subsequence ending at
        index i and last element is 
        smaller than its previous 
        element */
    int las[][] = new int[n][2];
  
    /* Initialize all values from 1 */
    for (int i = 0; i < n; i++)
        las[i][0] = las[i][1] = 1;
  
    int res = 1; // Initialize result
  
    /* Compute values in bottom up manner */
    for (int i = 1; i < n; i++)
    {
        // Consider all elements as 
        // previous of arr[i]
        for (int j = 0; j < i; j++)
        {
            // If arr[i] is greater, then 
            // check with las[j][1]
            if (arr[j] < arr[i] && 
                las[i][0] < las[j][1] + 1)
                las[i][0] = las[j][1] + 1;
  
            // If arr[i] is smaller, then
            // check with las[j][0]
            if( arr[j] > arr[i] &&
              las[i][1] < las[j][0] + 1)
                las[i][1] = las[j][0] + 1;
        }
  
        /* Pick maximum of both values at
        index i */
        if (res < Math.max(las[i][0], las[i][1]))
            res = Math.max(las[i][0], las[i][1]);
    }
  
    return res;
}

1457
Chapter 197. Longest alternating subsequence

  
/* Driver program */
public static void main(String[] args)
{
    int arr[] = { 10, 22, 9, 33, 49, 
                  50, 31, 60 };
    int n = arr.length;
    System.out.println("Length of Longest "+
                    "alternating subsequence is " +
                    zzis(arr, n));
}
}
// This code is contributed by Prerna Saini

C#

// C# program to find longest


// alternating subsequence 
// in an array
using System;
  
class GFG 
{
  
// Function to return longest 
// alternating subsequence length
static int zzis(int []arr, int n)
{
    /*las[i][0] = Length of the 
        longest alternating subsequence 
        ending at index i and last  
        element is greater than its 
        previous element
    las[i][1] = Length of the longest 
        alternating subsequence ending at
        index i and last element is 
        smaller than its previous 
        element */
    int [,]las = new int[n, 2];
  
    /* Initialize all values from 1 */
    for (int i = 0; i < n; i++)
        las[i, 0] = las[i, 1] = 1;
  
    // Initialize result
    int res = 1; 
  
    /* Compute values in 

1458
Chapter 197. Longest alternating subsequence

    bottom up manner */
    for (int i = 1; i < n; i++)
    {
        // Consider all elements as 
        // previous of arr[i]
        for (int j = 0; j < i; j++)
        {
            // If arr[i] is greater, then 
            // check with las[j][1]
            if (arr[j] < arr[i] && 
                las[i, 0] < las[j, 1] + 1)
                las[i, 0] = las[j, 1] + 1;
  
            // If arr[i] is smaller, then
            // check with las[j][0]
            if( arr[j] > arr[i] &&
            las[i, 1] < las[j, 0] + 1)
                las[i, 1] = las[j, 0] + 1;
        }
  
        /* Pick maximum of both 
        values at index i */
        if (res < Math.Max(las[i, 0], 
                           las[i, 1]))
            res = Math.Max(las[i, 0], 
                           las[i, 1]);
    }
  
    return res;
}
  
// Driver Code
public static void Main()
{
    int []arr = {10, 22, 9, 33, 
                 49, 50, 31, 60};
    int n = arr.Length;
    Console.WriteLine("Length of Longest "+ 
            "alternating subsequence is " +
                             zzis(arr, n));
}
}
  
// This code is contributed by anuj_67.

PHP

<?php

1459
Chapter 197. Longest alternating subsequence

// PHP program to find longest 


// alternating subsequence in 
// an array
  
// Function to return longest
// alternating subsequence length
function zzis($arr, $n)
{
    /*las[i][0] = Length of the 
        longest alternating subsequence 
        ending at index i and last element 
        is greater than its previous element
    las[i][1] = Length of the longest 
        alternating subsequence ending at 
        index i and last element is 
        smaller than its previous element */
    $las = array(array());
  
    /* Initialize all values from 1 */
    for ( $i = 0; $i < $n; $i++)
        $las[$i][0] = $las[$i][1] = 1;
  
    $res = 1; // Initialize result
  
    /* Compute values in
    bottom up manner */
    for ( $i = 1; $i < $n; $i++)
    {
        // Consider all elements 
        // as previous of arr[i]
        for ($j = 0; $j < $i; $j++)
        {
            // If arr[i] is greater, then 
            // check with las[j][1]
            if ($arr[$j] < $arr[$i] and
                $las[$i][0] < $las[$j][1] + 1)
               $las[$i][0] = $las[$j][1] + 1;
  
            // If arr[i] is smaller, then
            // check with las[j][0]
            if($arr[$j] > $arr[$i] and 
               $las[$i][1] < $las[$j][0] + 1)
                $las[$i][1] = $las[$j][0] + 1;
        }
  
        /* Pick maximum of both
        values at index i */
        if ($res < max($las[$i][0], $las[$i][1]))

1460
Chapter 197. Longest alternating subsequence

            $res = max($las[$i][0], $las[$i][1]);


    }
  
    return $res;
}
  
// Driver Code
$arr = array(10, 22, 9, 33, 
             49, 50, 31, 60 );
$n = count($arr);
echo "Length of Longest alternating " .
    "subsequence is ", zzis($arr, $n) ;
  
// This code is contributed by anuj_67.
?>

Output :

Length of Longest alternating subsequence is 6

Time Complexity : O(n2 )


Auxiliary Space : O(n)
This article is contributed by Utkarsh Trivedi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : vt_m

Source

https://www.geeksforgeeks.org/longest-alternating-subsequence/

1461
Chapter 198

Longest palindrome
subsequence with O(n) space

Longest palindrome subsequence with O(n) space - GeeksforGeeks


Given a sequence, find the length of the longest palindromic subsequence in it.

Examples:

Input : abbaab
Output : 4

Input : geeksforgeeks
Output : 5

We have discussed a Dynamic Programming solution for Longest Palindromic Subse-


quencewhich is based on below recursive formula.

// Every single character is a palindrome of length 1


L(i, i) = 1 for all indexes i in given sequence
// IF first and last characters are not same
If (X[i] != X[j]) L(i, j) = max{L(i + 1, j), L(i, j – 1)}

1462
Chapter 198. Longest palindrome subsequence with O(n) space

// If there are only 2 characters and both are same


Else if (j == i + 1) L(i, j) = 2
// If there are more than two characters, and first
// and last characters are same
Else L(i, j) = L(i + 1, j – 1) + 2

The solution discussed above takes O(n2 ) extra space. In this post a space optimized
solution is discussed that requires O(n) extra space. The idea is to create a one dimensional
array a[] of same size as given string. We make sure that a[i] stores length of longest
palindromic subsequence of prefix ending with i (or substring s[0..i]).

C++

// A Space optimized Dynamic Programming based C++


// program for LPS problem
#include <bits/stdc++.h>
using namespace std;
  
// Returns the length of the longest palindromic
// subsequence in str
int lps(string &s)
{
    int n = s.length();
  
    // a[i] is going to store length of longest
    // palindromic subsequence of substring s[0..i]
    int a[n];
  
    // Pick starting point
    for (int i = n - 1; i >= 0; i--) {
  
        int back_up = 0;
          
  
        // Pick ending points and see if s[i]
        // increases length of longest common
        // subsequence ending with s[j].
        for (int j = i; j < n; j++) {
  
            // similar to 2D array L[i][j] == 1
            // i.e., handling substrings of length
            // one.
            if (j == i)
                a[j] = 1; 
  
            // Similar to 2D array L[i][j] = L[i+1][j-1]+2
            // i.e., handling case when corner characters

1463
Chapter 198. Longest palindrome subsequence with O(n) space

            // are same. 


            else if (s[i] == s[j])
            {
                  
                // value a[j] is depend upon previous 
                // unupdated value of a[j-1] but in 
                // previous loop value of a[j-1] is 
                // changed. To store the unupdated 
                // value of a[j-1] back_up variable 
                // is used.
                int temp = a[j];
                a[j] = back_up + 2;
                back_up = temp;
            }
  
            // similar to 2D array L[i][j] = max(L[i][j-1],
            // a[i+1][j])
            else
            {
                back_up = a[j];
                a[j] = max(a[j - 1], a[j]);
            }
        }
    }
      
    return a[n - 1];
}
  
/* Driver program to test above functions */
int main()
{
    string str = "GEEKSFORGEEKS";
    cout << lps(str);
    return 0;
}

Java

// A Space optimized Dynamic Programming 


// based Java program for LPS problem
  
class GFG {
  
    // Returns the length of the longest 
    // palindromic subsequence in str
    static int lps(String s)
    {
        int n = s.length();

1464
Chapter 198. Longest palindrome subsequence with O(n) space

  
    // a[i] is going to store length
    // of longest palindromic subsequence
    // of substring s[0..i]
        int a[] = new int[n];
  
        // Pick starting point
        for (int i = n - 1; i >= 0; i--) 
            {
            int back_up = 0;
  
    // Pick ending points and see if s[i]
    // increases length of longest common
    // subsequence ending with s[j].
    for (int j = i; j < n; j++) {
  
    // similar to 2D array L[i][j] == 1
    // i.e., handling substrings of length
    // one.
        if (j == i)
        a[j] = 1;
  
    // Similar to 2D array L[i][j] = L[i+1][j-1]+2
    // i.e., handling case when corner characters
    // are same.
    else if (s.charAt(i) == s.charAt(j)) 
        {
        int temp = a[j];
        a[j] = back_up + 2;
        back_up = temp;
        }
  
    // similar to 2D array L[i][j] = max(L[i][j-1],
    // a[i+1][j])
      else   
            {
                back_up = a[j];
                a[j] = Math.max(a[j - 1], a[j]);
            }
          }
    }
    return a[n - 1];
    }
  
/* Driver program to test above functions */
    public static void main(String[] args)
    {
        String str = "GEEKSFORGEEKS";

1465
Chapter 198. Longest palindrome subsequence with O(n) space

        System.out.println(lps(str));
    }
}
  
//This article is contributed by prerna saini.

Python3

# A Space optimized Dynamic Programming 


# based Python3 program for LPS problem
  
# Returns the length of the longest 
# palindromic subsequence in str
def lps(s):
      
    n = len(s)
  
    # a[i] is going to store length
    # of longest palindromic subsequence
    # of substring s[0..i]
    a = [0] * n
  
    # Pick starting point
    for i in range(n-1, -1, -1):
  
        back_up = 0
  
    # Pick ending points and see if s[i]
    # increases length of longest common
    # subsequence ending with s[j].
        for j in range(i, n):
  
    # similar to 2D array L[i][j] == 1
    # i.e., handling substrings of length
    # one.
            if j == i: 
                a[j] = 1 
  
    # Similar to 2D array L[i][j] = L[i+1][j-1]+2
    # i.e., handling case when corner characters
    # are same. 
            elif s[i] == s[j]:
                temp = a[j]
                a[j] = back_up + 2
                back_up = temp
  
    # similar to 2D array L[i][j] = max(L[i][j-1],
    # a[i+1][j])

1466
Chapter 198. Longest palindrome subsequence with O(n) space

            else:
                back_up = a[j]
                a[j] = max(a[j - 1], a[j])
  
    return a[n - 1]
  
  
# Driver Code
string = "GEEKSFORGEEKS"
print(lps(string))
  
  
# This code is contributed by Ansu Kumari.

C#

// A Space optimized Dynamic Programming 


// based C# program for LPS problem
using System;
  
class GFG {
  
    // Returns the length of the longest 
    // palindromic subsequence in str
    static int lps(string s)
    {
        int n = s.Length;
  
    // a[i] is going to store length
    // of longest palindromic subsequence
    // of substring s[0..i]
        int []a = new int[n];
  
        // Pick starting point
        for (int i = n - 1; i >= 0; i--) 
            {
            int back_up = 0;
  
    // Pick ending points and see if s[i]
    // increases length of longest common
    // subsequence ending with s[j].
    for (int j = i; j < n; j++) {
  
    // similar to 2D array L[i][j] == 1
    // i.e., handling substrings of length
    // one.
        if (j == i)
        a[j] = 1;

1467
Chapter 198. Longest palindrome subsequence with O(n) space

  
    // Similar to 2D array L[i][j] = L[i+1][j-1]+2
    // i.e., handling case when corner characters
    // are same.
    else if (s[i] == s[j]) 
        {
        int temp = a[j];
        a[j] = back_up + 2;
        back_up = temp;
        }
  
    // similar to 2D array L[i][j] = max(L[i][j-1],
    // a[i+1][j])
    else
            {
                back_up = a[j];
                a[j] = Math.Max(a[j - 1], a[j]);
            }
        }
    }
    return a[n - 1];
    }
  
    // Driver program 
    public static void Main()
    {
        string str = "GEEKSFORGEEKS";
        Console.WriteLine(lps(str));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// A Space optimized Dynamic
// Programming based PHP
// program for LPS problem
  
// Returns the length of 
// the longest palindromic .
// subsequence in str
function lps($s)
{
    $n = strlen($s);
  
    // Pick starting point

1468
Chapter 198. Longest palindrome subsequence with O(n) space

    for ($i = $n - 1; 


         $i >= 0; $i--) 
    {
        $back_up = 0;
          
        // Pick ending points and 
        // see if s[i] increases 
        // length of longest common
        // subsequence ending with s[j].
        for ($j = $i; $j < $n; $j++) 
        {
  
            // similar to 2D array 
            // L[i][j] == 1 i.e.,
            // handling substrings 
            // of length one.
            if ($j == $i)
                $a[$j] = 1; 
  
            // Similar to 2D array 
            // L[i][j] = L[i+1][j-1]+2
            // i.e., handling case when 
            // corner characters are same. 
            else if ($s[$i] == $s[$j])
            {
                  
                // value a[j] is depend 
                // upon previous unupdated 
                // value of a[j-1] but in 
                // previous loop value of 
                // a[j-1] is changed. To 
                // store the unupdated value
                // of a[j-1] back_up variable 
                // is used.
                $temp = $a[$j];
                $a[$j] = $back_up + 2;
                $back_up = $temp;
            }
  
            // similar to 2D array
            // L[i][j] = max(L[i][j-1],
            // a[i+1][j])
            else
            {
                $back_up = $a[$j];
                $a[$j] = max($a[$j - 1], 
                             $a[$j]);
            }

1469
Chapter 198. Longest palindrome subsequence with O(n) space

        }
    }
      
    return $a[$n - 1];
}
  
// Driver Code
$str = "GEEKSFORGEEKS";
echo lps($str);
  
// This code is contributed
// by shiv_bhakt.
?>

Time Complexity : O(n*n)


Auxiliary Space : O(n)
Improved By : shiv_bhakt

Source

https://www.geeksforgeeks.org/longest-palindrome-subsequence-space/

1470
Chapter 199

Longest repeating and


non-overlapping substring

Longest repeating and non-overlapping substring - GeeksforGeeks


Given a string str, find the longest repeating non-overlapping substring in it. In other words
find 2 identical substrings of maximum length which do not overlap. If there exists more
than one such substring return any of them.
Examples:

Input : str = "geeksforgeeks"


Output : geeks

Input : str = "aab"


Output : a

Input : str = "aabaabaaba"


Output : aaba

Input : str = "aaaaaaaaaaa"


Output : aaaaa

Input : str = "banana"


Output : an
or na

Naive Solution : The problem can be solved easily by taking all the possible substrings
and for all the substrings check it for the remaining(non-overlapping) string if there exists
an identical substring. There are O(n2 ) total substrings and checking them against the
remaining string will take O(n) time. So overall time complexity of above solution is O(n3 ).

1471
Chapter 199. Longest repeating and non-overlapping substring

Dynamic Programming : This problem can be solved in O(n2 ) time using Dynamic
Programming. The basic idea is to find the longest repeating suffix for all prefixes in the
string str.

Length of longest non-repeating substring can be recursively


defined as below.

LCSRe(i, j) stores length of the matching and


non-overlapping substrings ending
with i'th and j'th characters.

If str[i-1] == str[j-1] && (j-i) > LCSRe(i-1, j-1)


LCSRe(i, j) = LCSRe(i-1, j-1) + 1,
Else
LCSRe(i, j) = 0

Where i varies from 1 to n and


j varies from i+1 to n

To avoid overlapping we have to ensure that the length of suffix is less than (j-i) at any
instant.
The maximum value of LCSRe(i, j) provides the length of the longest repeating substring
and the substring itself can be found using the length and the ending index of the common
suffix.
Below is C++ implementation of the recurrence.

// C++ program to find the longest repeated


// non-overlapping substring
#include<bits/stdc++.h>
using namespace std;
  
// Returns the longest repeating non-overlapping
// substring in str
string longestRepeatedSubstring(string str)
{
    int n = str.length();
    int LCSRe[n+1][n+1];
  
    // Setting all to 0
    memset(LCSRe, 0, sizeof(LCSRe));
  
    string res; // To store result
    int res_length  = 0; // To store length of result
  
    // building table in bottom-up manner
    int i, index = 0;

1472
Chapter 199. Longest repeating and non-overlapping substring

    for (i=1; i<=n; i++)


    {
        for (int j=i+1; j<=n; j++)
        {
            // (j-i) > LCSRe[i-1][j-1] to remove
            // overlapping
            if (str[i-1] == str[j-1] &&
                LCSRe[i-1][j-1] < (j - i))
            {
                LCSRe[i][j] = LCSRe[i-1][j-1] + 1;
  
                // updating maximum length of the
                // substring and updating the finishing
                // index of the suffix
                if (LCSRe[i][j] > res_length)
                {
                    res_length = LCSRe[i][j];
                    index = max(i, index);
                }
            }
            else
                LCSRe[i][j] = 0;
        }
    }
  
    // If we have non-empty result, then insert all
    // characters from first character to last
    // character of string
    if (res_length > 0)
        for (i = index - res_length + 1; i <= index; i++)
            res.push_back(str[i-1]);
  
    return res;
}
  
// Driver program to test the above function
int main()
{
    string str = "geeksforgeeks";
    cout << longestRepeatedSubstring(str);
    return 0;
}

Output:

geeks

1473
Chapter 199. Longest repeating and non-overlapping substring

Time Complexity: O(n2 )


Auxiliary Space: O(n2 )
References:
https://www.geeksforgeeks.org/longest-common-substring/

Source

https://www.geeksforgeeks.org/longest-repeating-and-non-overlapping-substring/

1474
Chapter 200

Longest subarray having


maximum sum

Longest subarray having maximum sum - GeeksforGeeks


Given an array arr[] containing n integers. The problem is to find the length of the subarray
having maximum sum. If there exists two or more subarrays with maximum sum then print
the length of the longest subarray.
Examples:

Input : arr[] = {5, -2, -1, 3, -4}


Output : 4
There are two subarrays with maximum sum:
First is {5}
Second is {5, -2, -1, 3}
Therefore longest one is of length 4.

Input : arr[] = {-2, -3, 4, -1, -2, 1, 5, -3}


Output : 5
The subarray is {4, -1, -2, 1, 5}

Approach: Following are the steps:

1. Find the maximum sum contiguous subarray. Let this sum be maxSum.
2. Find the length of the longest subarray having sum equal to maxSum. Refer this
post.

// C++ implementation to find the length of the longest


// subarray having maximum sum
#include <bits/stdc++.h>

1475
Chapter 200. Longest subarray having maximum sum

using namespace std;


  
// function to find the maximum sum that
// exists in a subarray
int maxSubArraySum(int arr[], int size)
{
    int max_so_far = arr[0];
    int curr_max = arr[0];
  
    for (int i = 1; i < size; i++) {
        curr_max = max(arr[i], curr_max + arr[i]);
        max_so_far = max(max_so_far, curr_max);
    }
    return max_so_far;
}
  
// function to find the length of longest
// subarray having sum k
int lenOfLongSubarrWithGivenSum(int arr[], int n, int k)
{
    // unordered_map 'um' implemented
    // as hash table
    unordered_map<int, int> um;
    int sum = 0, maxLen = 0;
  
    // traverse the given array
    for (int i = 0; i < n; i++) {
  
        // accumulate sum
        sum += arr[i];
  
        // when subarray starts from index '0'
        if (sum == k)
            maxLen = i + 1;
  
        // make an entry for 'sum' if it is
        // not present in 'um'
        if (um.find(sum) == um.end())
            um[sum] = i;
  
        // check if 'sum-k' is present in 'um'
        // or not
        if (um.find(sum - k) != um.end()) {
  
            // update maxLength
            if (maxLen < (i - um[sum - k]))
                maxLen = i - um[sum - k];
        }

1476
Chapter 200. Longest subarray having maximum sum

    }
  
    // required maximum length
    return maxLen;
}
  
// function to find the length of the longest
// subarray having maximum sum
int lenLongSubarrWithMaxSum(int arr[], int n)
{
    int maxSum = maxSubArraySum(arr, n);
    return lenOfLongSubarrWithGivenSum(arr, n, maxSum);
}
  
// Driver program to test above
int main()
{
    int arr[] = { 5, -2, -1, 3, -4 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Length of longest subarray having maximum sum = "
         << lenLongSubarrWithMaxSum(arr, n);
    return 0;
}

Output:

Length of longest subarray having maximum sum = 4

Time Complexity: O(n).


Auxiliary Space: O(n).

Source

https://www.geeksforgeeks.org/longest-subarray-having-maximum-sum/

1477
Chapter 201

Longest subsequence such that


difference between adjacents is
one

Longest subsequence such that difference between adjacents is one - GeeksforGeeks


Given an array of n size, the task is to find the longest subsequence such that difference
between adjacents is one.
Examples:

Input : arr[] = {10, 9, 4, 5, 4, 8, 6}


Output : 3
As longest subsequences with difference 1 are, "10, 9, 8",
"4, 5, 4" and "4, 5, 6"

Input : arr[] = {1, 2, 3, 2, 3, 7, 2, 1}


Output : 7
As longest consecutive sequence is "1, 2, 3, 2, 3, 2, 1"

This problem is based upon the concept of Longest Increasing Subsequence Problem.

Let arr[0..n-1] be the input array and


dp[i] be the length of the longest subsequence (with
differences one) ending at index i such that arr[i]
is the last element of the subsequence.

Then, dp[i] can be recursively written as:


dp[i] = 1 + max(dp[j]) where 0 < j < i and

1478
Chapter 201. Longest subsequence such that difference between adjacents is one

[arr[j] = arr[i] -1 or arr[j] = arr[i] + 1]


dp[i] = 1, if no such j exists.

To find the result for a given array, we need


to return max(dp[i]) where 0 < i < n.

Following is a Dynamic Programming based implementation. It follows the recursive


structure discussed above.

C++

// C++ program to find the longest subsequence such


// the difference between adjacent elements of the
// subsequence is one.
#include<bits/stdc++.h>
using namespace std;
  
// Function to find the length of longest subsequence
int longestSubseqWithDiffOne(int arr[], int n)
{
    // Initialize the dp[] array with 1 as a
    // single element will be of 1 length
    int dp[n];
    for (int i = 0; i< n; i++)
        dp[i] = 1;
  
    // Start traversing the given array
    for (int i=1; i<n; i++)
    {
        // Compare with all the previous elements
        for (int j=0; j<i; j++)
        {
            // If the element is consecutive then
            // consider this subsequence and update
            // dp[i] if required.
            if ((arr[i] == arr[j]+1) ||
                (arr[i] == arr[j]-1))
  
                dp[i] = max(dp[i], dp[j]+1);
        }
    }
  
    // Longest length will be the maximum value
    // of dp array.
    int result = 1;
    for (int i = 0 ; i < n ; i++)
        if (result < dp[i])

1479
Chapter 201. Longest subsequence such that difference between adjacents is one

            result = dp[i];
    return result;
}
  
// Driver code
int main()
{
    // Longest subsequence with one difference is
    // {1, 2, 3, 4, 3, 2}
    int arr[] = {1, 2, 3, 4, 5, 3, 2};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << longestSubseqWithDiffOne(arr, n);
    return 0;
}

Java

// Java program to find the longest subsequence


// such that the difference between adjacent
// elements of the subsequence is one.
import java.io.*;
  
class GFG {
      
    // Function to find the length of longest 
    // subsequence
    static int longestSubseqWithDiffOne(int arr[], 
                                           int n)
    {
        // Initialize the dp[] array with 1 as a
        // single element will be of 1 length
        int dp[] = new int[n];
        for (int i = 0; i< n; i++)
            dp[i] = 1;
  
        // Start traversing the given array
        for (int i = 1; i < n; i++)
        {
            // Compare with all the previous
            // elements
            for (int j = 0; j < i; j++)
            {
                // If the element is consecutive 
                // then consider this subsequence
                // and update dp[i] if required.
                if ((arr[i] == arr[j] + 1) ||
                    (arr[i] == arr[j] - 1))
  

1480
Chapter 201. Longest subsequence such that difference between adjacents is one

                dp[i] = Math.max(dp[i], dp[j]+1);


            }
        }
  
        // Longest length will be the maximum 
        // value of dp array.
        int result = 1;
        for (int i = 0 ; i < n ; i++)
            if (result < dp[i])
                result = dp[i];
        return result;
    }
  
    // Driver code
    public static void main(String[] args)
    {
        // Longest subsequence with one 
        // difference is
        // {1, 2, 3, 4, 3, 2}
        int arr[] = {1, 2, 3, 4, 5, 3, 2};
        int n = arr.length;
        System.out.println(longestSubseqWithDiffOne(
                                           arr, n));
    }
}
  
// This code is contributed by Prerna Saini

Python

# Function to find the length of longest subsequence


def longestSubseqWithDiffOne(arr, n):
    # Initialize the dp[] array with 1 as a
    # single element will be of 1 length
    dp = [1 for i in range(n)]
  
    # Start traversing the given array
    for i in range(n):
        # Compare with all the previous elements
        for j in range(i):
            # If the element is consecutive then
            # consider this subsequence and update
            # dp[i] if required.
            if ((arr[i] == arr[j]+1) or (arr[i] == arr[j]-1)):
                dp[i] = max(dp[i], dp[j]+1)
  
    # Longest length will be the maximum value
    # of dp array.

1481
Chapter 201. Longest subsequence such that difference between adjacents is one

    result = 1   
    for i in range(n):
        if (result < dp[i]):
            result = dp[i]
             
    return result
  
# Driver code
arr = [1, 2, 3, 4, 5, 3, 2]
# Longest subsequence with one difference is
# {1, 2, 3, 4, 3, 2}
n = len(arr)
print longestSubseqWithDiffOne(arr, n)
  
# This code is contributed by Afzal Ansari

C#

// C# program to find the longest subsequence


// such that the difference between adjacent
// elements of the subsequence is one.
using System;
  
class GFG {
      
    // Function to find the length of longest 
    // subsequence
    static int longestSubseqWithDiffOne(int []arr, 
                                           int n)
    {
          
        // Initialize the dp[] array with 1 as a
        // single element will be of 1 length
        int []dp = new int[n];
          
        for (int i = 0; i< n; i++)
            dp[i] = 1;
  
        // Start traversing the given array
        for (int i = 1; i < n; i++)
        {
              
            // Compare with all the previous
            // elements
            for (int j = 0; j < i; j++)
            {
                // If the element is consecutive 
                // then consider this subsequence

1482
Chapter 201. Longest subsequence such that difference between adjacents is one

                // and update dp[i] if required.


                if ((arr[i] == arr[j] + 1) ||
                         (arr[i] == arr[j] - 1))
  
                dp[i] = Math.Max(dp[i], dp[j]+1);
            }
        }
  
        // Longest length will be the maximum 
        // value of dp array.
        int result = 1;
        for (int i = 0 ; i < n ; i++)
            if (result < dp[i])
                result = dp[i];
                  
        return result;
    }
  
    // Driver code
    public static void Main()
    {
          
        // Longest subsequence with one 
        // difference is
        // {1, 2, 3, 4, 3, 2}
        int []arr = {1, 2, 3, 4, 5, 3, 2};
        int n = arr.Length;
          
        Console.Write(
            longestSubseqWithDiffOne(arr, n));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to find the longest
// subsequence such the difference 
// between adjacent elements of the
// subsequence is one.
  
// Function to find the length of
// longest subsequence
function longestSubseqWithDiffOne($arr, $n)
{
      

1483
Chapter 201. Longest subsequence such that difference between adjacents is one

    // Initialize the dp[] 


    // array with 1 as a
    // single element will 
    // be of 1 length
    $dp[$n] = 0;
      
    for($i = 0; $i< $n; $i++)
        $dp[$i] = 1;
  
    // Start traversing the
    // given array
    for($i = 1; $i < $n; $i++)
    {
          
        // Compare with all the 
        // previous elements
        for($j = 0; $j < $i; $j++)
        {
              
            // If the element is
            // consecutive then
            // consider this 
            // subsequence and 
            // update dp[i] if 
            // required.
            if (($arr[$i] == $arr[$j] + 1) ||
                ($arr[$i] == $arr[$j] - 1))
  
                $dp[$i] = max($dp[$i],
                         $dp[$j] + 1);
        }
    }
  
    // Longest length will be 
    // the maximum value
    // of dp array.
    $result = 1;
    for($i = 0 ; $i < $n ; $i++)
        if ($result < $dp[$i])
            $result = $dp[$i];
    return $result;
}
  
    // Driver code
    // Longest subsequence with
    // one difference is
    // {1, 2, 3, 4, 3, 2}
    $arr = array(1, 2, 3, 4, 5, 3, 2);

1484
Chapter 201. Longest subsequence such that difference between adjacents is one

    $n = sizeof($arr);
    echo longestSubseqWithDiffOne($arr, $n);
      
// This code is contributed by nitin mittal. 
?>

Output:

Time Complexity: O(n2 )


Auxiliary Space: O(n)
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/longest-subsequence-such-that-difference-between-adjacents-is-one/

1485
Chapter 202

Lucas Numbers

Lucas Numbers - GeeksforGeeks


Lucas numbers are similar to Fibonacci numbers. Lucas numbers are also defined as the
sum of its two immediate previous terms. But here the first two terms are 2 and 1 where
as in Fibonacci numbers the first two terms are 0 and 1 respectively.
Mathematically, Lucas Numbers may be defined as:

The Lucas numbers are in the following integer sequence:


2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123 …………..
Write a function int lucas(int n) n as argument and returns the n’th Lucas number.
Examples :

Input : 3
Output : 4

Input : 7
Output : 29

Method 1 ( Recursive Solution )


Below is recursive implementation based on simple recursive formula.

C/C++

1486
Chapter 202. Lucas Numbers

// Recursive C/C++ program 


// to find n'th Lucas number
#include <stdio.h>
  
// recursive function
int lucas(int n)
{
    // Base cases
    if (n == 0)
        return 2;
    if (n == 1)
        return 1;
  
    // recurrence relation
    return lucas(n - 1) + 
           lucas(n - 2);
}
  
// Driver Code
int main()
{
    int n = 9;
    printf("%d", lucas(n));
    return 0;
}

Java

// Recursive Java program to


// find n'th Lucas number
  
class GFG 
{
  
    // recursive function
    public static int lucas(int n)
    {
  
        // Base cases
        if (n == 0)
            return 2;
        if (n == 1)
            return 1;
  
        // recurrence relation
        return lucas(n - 1) + 
               lucas(n - 2);
    }

1487
Chapter 202. Lucas Numbers

  
    // Driver Code
    public static void main(String args[])
    {
        int n = 9;
        System.out.println(lucas(n));
    }
}
// This code is contributed 
// by Nikita Tiwari.

Python3

# Recursive Python 3 program 


# to find n'th Lucas number
  
# recursive function
def lucas(n) :
      
    # Base cases 
    if (n == 0) :
        return 2
    if (n == 1) :
        return 1
  
    # recurrence relation 
    return lucas(n - 1) + lucas(n - 2) 
  
  
# Driver code
n = 9
print(lucas(n))
  
# This code is contributed by Nikita Tiwari.

C#

// Recursive C# program to
// find n'th Lucas number
using System;
  
class GFG {
  
    // recursive function
    public static int lucas(int n)
    {
  

1488
Chapter 202. Lucas Numbers

        // Base cases


        if (n == 0)
            return 2;
        if (n == 1)
            return 1;
  
        // recurrence relation
        return lucas(n - 1) + lucas(n - 2);
    }
  
    // Driver program
    public static void Main()
    {
  
        int n = 9;
  
        Console.WriteLine(lucas(n));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// Recursive php program to
// find n'th Lucas number
  
// recursive function
function lucas($n)
{
      
// Base cases 
if ($n == 0) 
    return 2;
if ($n == 1) 
    return 1;
  
// recurrence relation 
return lucas($n - 1) + 
       lucas($n - 2); 
}
  
// Driver Code
$n = 9;
echo lucas($n);
  
// This code is contributed by ajit.

1489
Chapter 202. Lucas Numbers

?>

Output :

76

Method 2 ( Iterative Solution )


The time complexity of above implementation is exponential. We can optimize it to work
in O(n) time using iteration.

C/C++

// Iterative C/C++ program


// to find n'th Lucas Number
#include <stdio.h>
  
// Iterative function
int lucas(int n)
{
    // declaring base values
    // for positions 0 and 1
    int a = 2, b = 1, c, i;
  
    if (n == 0)
        return a;
  
    // generating number
    for (i = 2; i <= n; i++) 
    {
        c = a + b;
        a = b;
        b = c;
    }
    return b;
}
  
// Driver Code
int main()
{
    int n = 9;
    printf("%d", lucas(n));
    return 0;
}

Java

1490
Chapter 202. Lucas Numbers

// Iterative Java program to


// find n'th Lucas Number
class GFG 
{
    // Iterative function
    static int lucas(int n)
    {
        // declaring base values
        // for positions 0 and 1
        int a = 2, b = 1, c, i;
  
        if (n == 0)
            return a;
  
        // generating number
        for (i = 2; i <= n; i++) 
        {
            c = a + b;
            a = b;
            b = c;
        }
        return b;
    }
  
    // Driver Code
    public static void main(String args[])
    {
        int n = 9;
        System.out.println(lucas(n));
    }
}
  
// This code is contributed 
// by Nikita tiwari.

Pyhton3

# Iterative Python 3 program 


# to find n'th Lucas Number
  
# Iterative function
def lucas(n) :
  
    # declaring base values
    # for positions 0 and 1
    a = 2
    b = 1
      

1491
Chapter 202. Lucas Numbers

    if (n == 0) :
        return a
   
    # generating number
    for i in range(2, n + 1) :
        c = a + b
        a = b
        b = c
      
    return b
      
   
# Driver Code
n = 9
print(lucas(n))
  
# This code is contributed
# by Nikita tiwari.

C#

// Iterative C# program to
// find n'th Lucas Number
using System;
  
class GFG {
  
    // Iterative function
    static int lucas(int n)
    {
  
        // declaring base values
        // for positions 0 and 1
        int a = 2, b = 1, c, i;
  
        if (n == 0)
            return a;
  
        // generating number
        for (i = 2; i <= n; i++) {
            c = a + b;
            a = b;
            b = c;
        }
  
        return b;
    }
  

1492
Chapter 202. Lucas Numbers

    // Driver Code


    public static void Main()
    {
        int n = 9;
  
        Console.WriteLine(lucas(n));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// Iterative php program 
// to find n'th Lucas Number
  
function lucas($n)
{
    // declaring base values
    // for positions 0 and 1
    $a = 2; $b = 1; $c; $i;
  
    if ($n == 0)
        return $a;
  
    // generating number
    for ($i = 2; $i <= $n; $i++) 
    {
        $c = $a + $b;
        $a = $b;
        $b = $c;
    }
    return $b;
}
  
// Driver Code
$n = 9;
echo lucas($n);
  
// This code is contributed by ajit
?>

Output :

76

1493
Chapter 202. Lucas Numbers

References:
https://en.wikipedia.org/wiki/Lucas_number
Improved By : jit_t

Source

https://www.geeksforgeeks.org/lucas-numbers/

1494
Chapter 203

Matrix Exponentiation

Matrix Exponentiation - GeeksforGeeks


This is one of the most used techniques in competitive programming. Let us first consider
below simple question.
What is the minimum time complexity to find n’th Fibonacci Number?
We can find n’th Fibonacci Number in O(Log n) time using Matrix Exponentiation. Refer
method 4 of this for details. In this post, a general implementation of Matrix Exponentiation
is discussed.

For solving the matrix exponentiation we are assuming a


linear recurrence equation like below:

F(n) = a*F(n-1) + b*F(n-2) + c*F(n-3) for n >= 3


. . . . . Equation (1)
where a, b and c are constants.

For this recurrence relation it depends on three previous values.


Now we will try to represent Equation (1) in terms of matrix.

[First Matrix] = [Second matrix] * [Third Matrix]


| F(n) | = Matrix 'C' * | F(n-1) |
| F(n-1) | | F(n-2) |
| F(n-2) | | F(n-3) |

Dimension of the first matrix is 3 x 1 .


Dimension of third matrix is also 3 x 1.

So the dimension of the second matrix must be 3 x 3


[For multiplication rule to be satisfied.]

Now we need to fill the Matrix 'C'.

1495
Chapter 203. Matrix Exponentiation

So according to our equation.


F(n) = a*F(n-1) + b*F(n-2) + c*F(n-3)
F(n-1) = F(n-1)
F(n-2) = F(n-2)

C = [a b c
1 0 0
0 1 0]

Now the relation between matrix becomes :


[First Matrix] [Second matrix] [Third Matrix]
| F(n) | = | a b c | * | F(n-1) |
| F(n-1) | | 1 0 0 | | F(n-2) |
| F(n-2) | | 0 1 0 | | F(n-3) |

Lets assume the initial values for this case :-


F(0) = 0
F(1) = 1
F(2) = 1

So, we need to get F(n) in terms of these values.

So, for n = 3 Equation (1) changes to


| F(3) | = | a b c | * | F(2) |
| F(2) | | 1 0 0 | | F(1) |
| F(1) | | 0 1 0 | | F(0) |

Now similarly for n = 4


| F(4) | = | a b c | * | F(3) |
| F(3) | | 1 0 0 | | F(2) |
| F(2) | | 0 1 0 | | F(1) |

- - - - 2 times - - -
| F(4) | = | a b c | * | a b c | * | F(2) |
| F(3) | | 1 0 0 | | 1 0 0 | | F(1) |
| F(2) | | 0 1 0 | | 0 1 0 | | F(0) |

So for n, the Equation (1) changes to

- - - - - - - - n -2 times - - - - -
| F(n) | = | a b c | * | a b c | * ... * | a b c | * | F(2) |
| F(n-1) | | 1 0 0 | | 1 0 0 | | 1 0 0 | | F(1) |
| F(n-2) | | 0 1 0 | | 0 1 0 | | 0 1 0 | | F(0) |

| F(n) | = [ | a b c | ] ^ (n-2) * | F(2) |


| F(n-1) | [ | 1 0 0 | ] | F(1) |

1496
Chapter 203. Matrix Exponentiation

| F(n-2) | [ | 0 1 0 | ] | F(0) |

So we can simply multiply our Second matrix n-2 times and then multiply it with the
third matrix to get the result. Multiplication can be done in (log n) time using Divide and
Conquer algorithm for power (See this or this)
Let us consider the problem of finding n’th term of a series defined using below recurrence.

n'th term,
F(n) = F(n-1) + F(n-2) + F(n-3), n >= 3
Base Cases :
F(0) = 0, F(1) = 1, F(2) = 1

We can find n’th term using following :

Putting a = 1, b = 1 and c = 1 in above formula

| F(n) | = [ | 1 1 1 | ] ^ (n-2) * | F(2) |


| F(n-1) | [ | 1 0 0 | ] | F(1) |
| F(n-2) | [ | 0 1 0 | ] | F(0) |

Below is the implementation of above idea.


C++

// C++ program to find value of f(n) where f(n)


// is defined as
//    F(n) = F(n-1) + F(n-2) + F(n-3), n >= 3
// Base Cases :
//    F(0) = 0, F(1) = 1, F(2) = 1
#include<bits/stdc++.h>
using namespace std;
  
// A utility function to multiply two matrices
// a[][] and b[][].  Multiplication result is
// stored back in b[][]
void multiply(int a[3][3], int b[3][3])
{
    // Creating an auxiliary matrix to store elements 
    // of the multiplication matrix
    int mul[3][3];
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            mul[i][j] = 0;
            for (int k = 0; k < 3; k++)

1497
Chapter 203. Matrix Exponentiation

                mul[i][j] += a[i][k]*b[k][j];
        }
    }
  
    // storing the muliplication resul in a[][]
    for (int i=0; i<3; i++)
        for (int j=0; j<3; j++)
            a[i][j] = mul[i][j];  // Updating our matrix
}
  
// Function to compute F raise to power n-2.
int power(int F[3][3], int n)
{
    int M[3][3] = {{1,1,1}, {1,0,0}, {0,1,0}};
  
    // Multiply it with initial values i.e with
    // F(0) = 0, F(1) = 1, F(2) = 1
    if (n==1)
        return F[0][0] + F[0][1];
  
    power(F, n/2);
  
    multiply(F, F);
  
    if (n%2 != 0)
        multiply(F, M);
  
    // Multiply it with initial values i.e with
    // F(0) = 0, F(1) = 1, F(2) = 1
    return F[0][0] + F[0][1] ;
}
  
// Return n'th term of a series defined using below
// recurrence relation.
// f(n) is defined as
//    f(n) = f(n-1) + f(n-2) + f(n-3), n>=3
// Base Cases :
//    f(0) = 0, f(1) = 1, f(2) = 1
int findNthTerm(int n)
{
    int F[3][3] = {{1,1,1}, {1,0,0}, {0,1,0}} ;
  
    return power(F, n-2);
}
  
// Driver code
int main()
{

1498
Chapter 203. Matrix Exponentiation

   int n = 5;
  
   cout << "F(5) is " << findNthTerm(n);
  
   return 0;
}

Java

// JAVA program to find value of f(n) where


// f(n) is defined as
// F(n) = F(n-1) + F(n-2) + F(n-3), n >= 3
// Base Cases :
// F(0) = 0, F(1) = 1, F(2) = 1
import java.io.*;
  
class GFG {
      
    // A utility function to multiply two 
    // matrices a[][] and b[][]. 
    // Multiplication result is
    // stored back in b[][]
    static void multiply(int a[][], int b[][])
    {
        // Creating an auxiliary matrix to 
        // store elements of the 
        // multiplication matrix
        int mul[][] = new int[3][3];
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                mul[i][j] = 0;
                for (int k = 0; k < 3; k++)
                    mul[i][j] += a[i][k]
                                * b[k][j];
            }
        }
      
        // storing the muliplication 
        // resul in a[][]
        for (int i=0; i<3; i++)
            for (int j=0; j<3; j++)
              
                // Updating our matrix
                a[i][j] = mul[i][j]; 
    }
      

1499
Chapter 203. Matrix Exponentiation

    // Function to compute F raise to


    // power n-2.
    static int power(int F[][], int n)
    {
        int M[][] = {{1, 1, 1}, {1, 0, 0},
                               {0, 1, 0}};
      
        // Multiply it with initial values
        // i.e with F(0) = 0, F(1) = 1, 
        // F(2) = 1
        if (n == 1)
            return F[0][0] + F[0][1];
      
        power(F, n / 2);
      
        multiply(F, F);
      
        if (n%2 != 0)
            multiply(F, M);
      
        // Multiply it with initial values 
        // i.e with F(0) = 0, F(1) = 1, 
        // F(2) = 1
        return F[0][0] + F[0][1] ;
    }
      
    // Return n'th term of a series defined 
    // using below recurrence relation.
    // f(n) is defined as
    // f(n) = f(n-1) + f(n-2) + f(n-3), n>=3
    // Base Cases :
    // f(0) = 0, f(1) = 1, f(2) = 1
    static int findNthTerm(int n)
    {
        int F[][] = {{1, 1, 1}, {1, 0, 0},
                                  {0, 1, 0}} ;
      
        return power(F, n-2);
    }
      
    // Driver code
    public static void main (String[] args) {
          
        int n = 5;
          
        System.out.println("F(5) is "
                           + findNthTerm(n));
    }

1500
Chapter 203. Matrix Exponentiation

}
  
//This code is contributed by vt_m.

C#

// C# program to find value of f(n) where 


// f(n) is defined as
// F(n) = F(n-1) + F(n-2) + F(n-3), n >= 3
// Base Cases :
// F(0) = 0, F(1) = 1, F(2) = 1
using System;
  
class GFG {
  
    // A utility function to multiply two 
    // matrices a[][] and b[][]. Multiplication
    // result is stored back in b[][]
    static void multiply(int[, ] a, int[, ] b)
    {
          
        // Creating an auxiliary matrix to store 
        // elements of the multiplication matrix
        int[, ] mul = new int[3, 3];
          
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                mul[i, j] = 0;
                for (int k = 0; k < 3; k++)
                    mul[i, j] += a[i, k] * b[k, j];
            }
        }
  
        // storing the muliplication resul 
        // in a[][]
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
              
                // Updating our matrix
                a[i, j] = mul[i, j]; 
    }
  
    // Function to compute F raise to power n-2.
    static int power(int[, ] F, int n)
    {
          
        int[, ] M = { { 1, 1, 1 }, { 1, 0, 0 }, 
                                   { 0, 1, 0 } };

1501
Chapter 203. Matrix Exponentiation

  
        // Multiply it with initial values i.e
        // with F(0) = 0, F(1) = 1, F(2) = 1
        if (n == 1)
            return F[0, 0] + F[0, 1];
  
        power(F, n / 2);
  
        multiply(F, F);
  
        if (n % 2 != 0)
            multiply(F, M);
  
        // Multiply it with initial values i.e 
        // with F(0) = 0, F(1) = 1, F(2) = 1
        return F[0, 0] + F[0, 1];
    }
  
    // Return n'th term of a series defined 
    // using below recurrence relation.
    // f(n) is defined as
    // f(n) = f(n-1) + f(n-2) + f(n-3), n>=3
    // Base Cases :
    // f(0) = 0, f(1) = 1, f(2) = 1
    static int findNthTerm(int n)
    {
        int[, ] F = { { 1, 1, 1 }, { 1, 0, 0 },
                                 { 0, 1, 0 } };
  
        return power(F, n - 2);
    }
  
    // Driver code
    public static void Main()
    {
        int n = 5;
          
        Console.WriteLine("F(5) is " 
                      + findNthTerm(n));
    }
}
  
// This code is contributed by vt_m.

Output :

F(5) is 7

1502
Chapter 203. Matrix Exponentiation

Time Complexity of this solution : O(log n)


This article is contributed by Abhiraj Smit. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/matrix-exponentiation/

1503
Chapter 204

Maximize arr[j] – arr[i] + arr[l]


– arr[k], such that i < j < k < l

Maximize arr[j] - arr[i] + arr[l] - arr[k], such that i < j < k < l - GeeksforGeeks
Maximize arr[l] – arr[k] + arr[j] – arr[i], such that i < j < k < l. Find the maximum value
of arr[l] – arr[k] + arr[j] – arr[i], such that i < j < k < l
Example:

Let us say our array is {4, 8, 9, 2, 20}


Then the maximum such value is 23 (9 - 4 + 20 - 2)

Brute Force Method:


We can simply find all the combinations of size 4 with given constraints. The maximum
value will be the required answer. This method is very inefficient.

Efficient Method (Dynamic Programming):


We will use Dynamic Programming to solve this problem. For this we create four
1-Dimensional DP tables.
Let us say there are four DP tables as – table1[], table2[], table3[], table4[]
Then to find the maximum value of arr[l] – arr[k] + arr[j] – arr[i], such that i < j < k < l
table1[] should store the maximum value of arr[l]
table2[] should store the maximum value of arr[l] – arr[k]
table3[] should store the maximum value of arr[l] – arr[k] + arr[j]
table4[] should store the maximum value of arr[l] – arr[k] + arr[j] – arr[i]
Then the maximum value would be present in index 0 of table4 which will be our required
answer.
Below is C++ implementation of above idea –

1504
Chapter 204. Maximize arr[j] – arr[i] + arr[l] – arr[k], such that i < j < k < l

/* A C++ Program to find maximum value of


arr[l] - arr[k] + arr[j] - arr[i] and i < j < k < l,
given that the array has atleast 4 elements */
#include <bits/stdc++.h>
using namespace std;
  
// To reprsent minus infinite
#define MIN -100000000
  
// A Dynamic Programing based function to find maximum
// value of arr[l] - arr[k] + arr[j] - arr[i] is maximum
// and i < j < k < l
int findMaxValue(int arr[], int n)
{
    // If the array has less than 4 elements
    if (n < 4)
    {
        printf("The array should have atlest 4 elements\n");
        return MIN;
    }
  
    // We create 4 DP tables
    int table1[n + 1], table2[n], table3[n - 1], table4[n - 2];
  
    // Initialize all the tables to MIN
    for (int i=0; i<=n; i++)
        table1[i] = table2[i] = table3[i] = table4[i] =  MIN;
  
    // table1[] stores the maximum value of arr[l]
    for (int i = n - 1; i >= 0; i--)
        table1[i] = max(table1[i + 1], arr[i]);
  
    // table2[] stores the maximum value of arr[l] - arr[k]
    for (int i = n - 2; i >= 0; i--)
        table2[i] = max(table2[i + 1], table1[i + 1] - arr[i]);
  
    // table3[] stores the maximum value of arr[l] - arr[k]
    // + arr[j]
    for (int i = n - 3; i >= 0; i--)
        table3[i] = max(table3[i + 1], table2[i + 1] + arr[i]);
  
    // table4[] stores the maximum value of arr[l] - arr[k]
    // + arr[j] - arr[i]
    for (int i = n - 4; i >= 0; i--)
        table4[i] = max(table4[i + 1], table3[i + 1] - arr[i]);
  
    /*for (int i = 0; i < n + 1; i++)
        cout << table1[i] << " " ;

1505
Chapter 204. Maximize arr[j] – arr[i] + arr[l] – arr[k], such that i < j < k < l

    cout << endl;


  
    for (int i = 0; i < n; i++)
        cout << table2[i] << " " ;
    cout << endl;
  
    for (int i = 0; i < n - 1; i++)
        cout << table3[i] << " " ;
    cout << endl;
  
    for (int i = 0; i < n - 2; i++)
        cout << table4[i] << " " ;
    cout << endl;
    */
  
    // maximum value would be present in table4[0]
    return table4[0];
}
  
// Driver Program to test above functions
int main()
{
    int arr[] = { 4, 8, 9, 2, 20 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    printf("%d\n", findMaxValue(arr, n));
  
    return 0;
}

Output:

23

Time Complexity : O(n), where n is the size of input array


Auxiliary Space : Since we are creating four tables to store our values, space is 4*O(n)
= O(4*n) = O(n)

Source

https://www.geeksforgeeks.org/maximize-arrj-arri-arrl-arrk-such-that-i-j-k-l/

1506
Chapter 205

Maximize array elements upto


given number

Maximize array elements upto given number - GeeksforGeeks


Given an array of integers, a number and a maximum value, task is to compute the maximum
value that can be obtained from the array elements. Every value on the array traversing
from the beginning can be either added to or subtracted from the result obtained from
previous index such that at any point the result is not less than 0 and not greater than the
given maximum value. For index 0 take previous result equal to given number. In case of
no possible answer print -1.
Examples :

Input : arr[] = {2, 1, 7}


Number = 3
Maximum value = 7
Output : 7
The order of addition and subtraction
is: 3(given number) - 2(arr[0]) -
1(arr[1]) + 7(arr[2]).

Input : arr[] = {3, 10, 6, 4, 5}


Number = 1
Maximum value = 15
Output : 9
The order of addition and subtraction
is: 1 + 3 + 10 - 6 - 4 + 5

Prerequisite : Dynamic Programming | Recursion.


Naive Approach : Use recursion to find maximum value. At every index position there are
two choices, either add current array element to value obtained so far from previous elements

1507
Chapter 205. Maximize array elements upto given number

or subtract current array element from value obtained so far from previous elements. Start
from index 0, add or subtract arr[0] from given number and recursively call for next index
along with updated number. When entire array is traversed, compare the updated number
with overall maximum value of number obtained so far.
Below is the implementation of above approach :

C++

// CPP code to find maximum


// value of number obtained by
// using array elements recursively.
#include <bits/stdc++.h>
using namespace std;
  
// Utility function to find maximum possible value
void findMaxValUtil(int arr[], int n, int num,
                    int maxLimit, int ind, int& ans)
{
    // If entire array is traversed, then compare
    // current value in num to overall maximum
    // obtained so far.
    if (ind == n) {
        ans = max(ans, num);
        return;
    }
  
    // Case 1: Subtract current element from value so
    // far if result is greater than or equal to zero.
    if (num - arr[ind] >= 0) 
    {
        findMaxValUtil(arr, n, num - arr[ind],
                       maxLimit, ind + 1, ans);
    }
  
    // Case 2 : Add current element to value so far
    // if result is less than or equal to maxLimit.
    if (num + arr[ind] <= maxLimit) 
    {
        findMaxValUtil(arr, n, num + arr[ind],
                       maxLimit, ind + 1, ans);
    }
}
  
// Function to find maximum possible
// value that can be obtained using
// array elements and given number.
int findMaxVal(int arr[], int n, 

1508
Chapter 205. Maximize array elements upto given number

               int num, int maxLimit)


{
    // variable to store maximum value
    // that can be obtained.
    int ans = 0;
  
    // variable to store current index position.
    int ind = 0;
  
    // call to utility function to find maximum
    // possible value that can be obtained.
    findMaxValUtil(arr, n, num, maxLimit, ind, ans);
  
    return ans;
}
  
// Driver code
int main()
{
    int num = 1;
    int arr[] = { 3, 10, 6, 4, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int maxLimit = 15;
  
    cout << findMaxVal(arr, n, num, maxLimit);
    return 0;
}

Java

// Java code to find maximum


// value of number obtained by
// using array elements recursively.
import java.io.*;
import java.lang.*;
   
public class GFG {
  
    // variable to store maximum value
    // that can be obtained.
    static int ans;
      
    // Utility function to find maximum 
    // possible value
    static void findMaxValUtil(int []arr, int n, int num,
                              int maxLimit, int ind)
    {
           

1509
Chapter 205. Maximize array elements upto given number

        // If entire array is traversed, then compare


        // current value in num to overall maximum
        // obtained so far.
        if (ind == n) {
            ans = Math.max(ans, num);
            return;
        }
       
        // Case 1: Subtract current element from value so
        // far if result is greater than or equal to zero.
        if (num - arr[ind] >= 0) 
        {
            findMaxValUtil(arr, n, num - arr[ind],
                            maxLimit, ind + 1);
        }
       
        // Case 2 : Add current element to value so far
        // if result is less than or equal to maxLimit.
        if (num + arr[ind] <= maxLimit) 
        {
            findMaxValUtil(arr, n, num + arr[ind],
                          maxLimit, ind + 1);
        }
    }
       
    // Function to find maximum possible
    // value that can be obtained using
    // array elements and given number.
    static int findMaxVal(int []arr, int n, 
                             int num, int maxLimit)
    {
           
          
       
        // variable to store current index position.
        int ind = 0;
       
        // call to utility function to find maximum
        // possible value that can be obtained.
        findMaxValUtil(arr, n, num, maxLimit, ind);
       
        return ans;
    }
       
    // Driver code
    public static void main(String args[])
    {
        int num = 1;

1510
Chapter 205. Maximize array elements upto given number

        int []arr = { 3, 10, 6, 4, 5 };


        int n = arr.length;
        int maxLimit = 15;
       
        System.out.print(findMaxVal(arr, n, num, 
                                        maxLimit));
    }
}
  
// This code is contributed by Manish Shaw
// (manishshaw1)

Python3

# Python3 code to find maximum


# value of number obtained by
# using array elements recursively.
  
# Utility def to find 
# maximum possible value
  
# variable to store maximum value
# that can be obtained.
ans = 0;
def findMaxValUtil(arr, n, num, maxLimit, ind):
    global ans
      
    # If entire array is traversed, 
    # then compare current value 
    # in num to overall maximum
    # obtained so far.
    if (ind == n) :
        ans = max(ans, num)
        return
  
    # Case 1: Subtract current element 
    # from value so far if result is 
    # greater than or equal to zero.
    if (num - arr[ind] >= 0) :
        findMaxValUtil(arr, n, num - arr[ind],
                            maxLimit, ind + 1)
  
    # Case 2 : Add current element to 
    # value so far if result is less
    # than or equal to maxLimit.
    if (num + arr[ind] <= maxLimit) :
        findMaxValUtil(arr, n, num + arr[ind],
                            maxLimit, ind + 1)

1511
Chapter 205. Maximize array elements upto given number

  
# def to find maximum possible
# value that can be obtained using
# array elements and given number.
def findMaxVal(arr, n, num, maxLimit) :
    global ans
    # variable to store 
    # current index position.
    ind = 0
  
    # call to utility def to 
    # find maximum possible value
    # that can be obtained.
    findMaxValUtil(arr, n, num, maxLimit, ind)
    return ans
  
  
# Driver code
num = 1
arr = [3, 10, 6, 4, 5]
n = len(arr)
maxLimit = 15
  
print (findMaxVal(arr, n, num, maxLimit))
  
# This code is contributed by Manish Shaw
# (manishshaw1)

C#

// C# code to find maximum


// value of number obtained by
// using array elements recursively.
using System;
using System.Collections.Generic;
  
class GFG {
      
    // Utility function to find maximum 
    // possible value
    static void findMaxValUtil(int []arr, int n, int num,
                      int maxLimit, int ind, ref int ans)
    {
          
        // If entire array is traversed, then compare
        // current value in num to overall maximum
        // obtained so far.
        if (ind == n) {

1512
Chapter 205. Maximize array elements upto given number

            ans = Math.Max(ans, num);


            return;
        }
      
        // Case 1: Subtract current element from value so
        // far if result is greater than or equal to zero.
        if (num - arr[ind] >= 0) 
        {
            findMaxValUtil(arr, n, num - arr[ind],
                            maxLimit, ind + 1, ref ans);
        }
      
        // Case 2 : Add current element to value so far
        // if result is less than or equal to maxLimit.
        if (num + arr[ind] <= maxLimit) 
        {
            findMaxValUtil(arr, n, num + arr[ind],
                          maxLimit, ind + 1, ref ans);
        }
    }
      
    // Function to find maximum possible
    // value that can be obtained using
    // array elements and given number.
    static int findMaxVal(int []arr, int n, 
                             int num, int maxLimit)
    {
          
        // variable to store maximum value
        // that can be obtained.
        int ans = 0;
      
        // variable to store current index position.
        int ind = 0;
      
        // call to utility function to find maximum
        // possible value that can be obtained.
        findMaxValUtil(arr, n, num, maxLimit, ind, 
                                           ref ans);
      
        return ans;
    }
      
    // Driver code
    public static void Main()
    {
        int num = 1;
        int []arr = { 3, 10, 6, 4, 5 };

1513
Chapter 205. Maximize array elements upto given number

        int n = arr.Length;
        int maxLimit = 15;
      
        Console.Write(findMaxVal(arr, n, num, 
                                        maxLimit));
    }
}
  
// This code is contributed by Manish Shaw
// (manishshaw1)

PHP

<?php
// PHP code to find maximum
// value of number obtained by
// using array elements recursively.
  
// Utility function to find 
// maximum possible value
function findMaxValUtil($arr, $n, 
                        $num, $maxLimit, 
                        $ind, &$ans)
{
    // If entire array is traversed, 
    // then compare current value 
    // in num to overall maximum
    // obtained so far.
    if ($ind == $n) 
    {
        $ans = max($ans, $num);
        return;
    }
  
    // Case 1: Subtract current element 
    // from value so far if result is 
    // greater than or equal to zero.
    if ($num - $arr[$ind] >= 0) 
    {
        findMaxValUtil($arr, $n, 
                       $num - $arr[$ind],
                       $maxLimit, $ind + 1, 
                       $ans);
    }
  
    // Case 2 : Add current element to 
    // value so far if result is less
    // than or equal to maxLimit.

1514
Chapter 205. Maximize array elements upto given number

    if ($num + $arr[$ind] <= $maxLimit) 


    {
        findMaxValUtil($arr, $n, 
                       $num + $arr[$ind], 
                       $maxLimit, $ind + 1, 
                       $ans);
    }
}
  
// Function to find maximum possible
// value that can be obtained using
// array elements and given number.
function findMaxVal($arr, $n, 
                    $num, $maxLimit)
{
    // variable to store maximum value
    // that can be obtained.
    $ans = 0;
  
    // variable to store 
    // current index position.
    $ind = 0;
  
    // call to utility function to 
    // find maximum possible value
    // that can be obtained.
    findMaxValUtil($arr, $n, $num, 
                   $maxLimit, $ind, $ans);
  
    return $ans;
}
  
// Driver code
$num = 1;
$arr = array(3, 10, 6, 4, 5);
$n = count($arr);
$maxLimit = 15;
  
echo (findMaxVal($arr, $n, $num, $maxLimit));
  
//This code is contributed by Manish Shaw
//(manishshaw1)
?>

Output:

1515
Chapter 205. Maximize array elements upto given number

Time Complexity : O(2^n).


Note : For small values of n <= 20, this solution will work. But as array size increases,
this will not be an optimal solution.
An efficient solution is to use Dynamic Programming. Observe that the value at every step
is constrained between 0 and maxLimit and hence, the required maximum value will also
lie in this range. At every index position, after arr[i] is added to or subtracted from result,
the new value of result will also lie in this range. Lets try to build the solution backwards.
Suppose the required maximum possible value is x, where 0 � x � maxLimit. This value x
is obtained by either adding or subtracting arr[n-1] to/from the value obtained until index
position n-2. The same reason can be given for value obtained at index position n-2 that it
depends on value at index position n-3 and so on. The resulting recurrence relation can be
given as :

Check can x be obtained from arr[0..n-1]:


Check can x - arr[n-1] be obtained from arr[0..n-2]
|| Check can x + arr[n-1] be obtained from arr[0..n-2]

A boolean DP table can be created in which dp[i][j] is 1 if value j can be obtained using
arr[0..i] and 0 if not. For each index position, start from j = 0 and move to value maxLimit,
and set dp[i][j] either 0 or 1 as described above. Find the maximum possible value that can
be obtained at index position n-1 by finding maximum j when i = n-1 and dp[n-1][j] = 1.
C++

// C++ program to find maximum value of


// number obtained by using array
// elements by using dynamic programming.
#include <bits/stdc++.h>
using namespace std;
   
// Function to find maximum possible
// value of number that can be 
// obtained using array elements.
int findMaxVal(int arr[], int n, 
               int num, int maxLimit)
{
    // Variable to represent current index.
    int ind;
       
    // Variable to show value between
    //  0 and maxLimit.
    int val;
       
    // Table to store whether a value can
    // be obtained or not upto a certain index.
    // 1. dp[i][j] = 1 if value j can be

1516
Chapter 205. Maximize array elements upto given number

    //    obtained upto index i.


    // 2. dp[i][j] = 0 if value j cannot be
    //    obtained upto index i.
    int dp[n][maxLimit+1];
       
    for(ind = 0; ind < n; ind++)
    {
        for(val = 0; val <= maxLimit; val++)
        {
            // Check for index 0 if given value
            // val can be obtained by either adding
            // to or subtracting arr[0] from num.
            if(ind == 0)
            {
                if(num - arr[ind] == val || 
                    num + arr[ind] == val)
                {
                    dp[ind][val] = 1;
                }
                else
                {
                    dp[ind][val] = 0;
                }
            }
            else
            {
                // 1. If arr[ind] is added to
                // obtain given val then val-
                // arr[ind] should be obtainable
                // from index ind-1.
                // 2. If arr[ind] is subtracted to
                // obtain given val then val+arr[ind]
                // should be obtainable from index ind-1.
                // Check for both the conditions.
                if(val - arr[ind] >= 0 && 
                   val + arr[ind] <= maxLimit)
                {
                    // If either of one condition is true,
                    // then val is obtainable at index ind.
                    dp[ind][val] = dp[ind-1][val-arr[ind]] || 
                                     dp[ind-1][val+arr[ind]];
                }
                else if(val - arr[ind] >= 0)
                {
                    dp[ind][val] = dp[ind-1][val-arr[ind]];
                }
                else if(val + arr[ind] <= maxLimit)
                {

1517
Chapter 205. Maximize array elements upto given number

                    dp[ind][val] = dp[ind-1][val+arr[ind]];
                }
                else
                {
                    dp[ind][val] = 0;
                }
            }
        }
    }
       
    // Find maximum value that is obtained
    // at index n-1.
    for(val = maxLimit; val >= 0; val--)
    {
        if(dp[n-1][val])
        {
            return val;
        }
    }
       
    // If no solution exists return -1.
    return -1;
}
   
// Driver Code 
int main() 
{
    int num = 1;
    int arr[] = {3, 10, 6, 4, 5};
    int n = sizeof(arr) / sizeof(arr[0]);
    int maxLimit = 15;
        
    cout << findMaxVal(arr, n, num, maxLimit);
    return 0;
}

Java

// Java program to find maximum 


// value of number obtained by 
// using array elements by using
// dynamic programming.
import java.io.*;
  
class GFG 
{
      
    // Function to find maximum 

1518
Chapter 205. Maximize array elements upto given number

    // possible value of number 


    // that can be obtained
    // using array elements.
    static int findMaxVal(int []arr, int n, 
                          int num, int maxLimit)
    {
          
        // Variable to represent
        // current index.
        int ind;
          
        // Variable to show value 
        // between 0 and maxLimit.
        int val;
          
        // Table to store whether 
        // a value can be obtained 
        // or not upto a certain
        // index 1. dp[i,j] = 1 if 
        // value j can be obtained 
        // upto index i.
        // 2. dp[i,j] = 0 if value j 
        // cannot be obtained upto index i.
        int [][]dp = new int[n][maxLimit + 1];
          
        for(ind = 0; ind < n; ind++)
        {
            for(val = 0; val <= maxLimit; val++)
            {
                // Check for index 0 if given
                // value val can be obtained 
                // by either adding to or 
                // subtracting arr[0] from num.
                if(ind == 0)
                {
                    if(num - arr[ind] == val || 
                       num + arr[ind] == val)
                    {
                        dp[ind][val] = 1;
                    }
                    else
                    {
                        dp[ind][val] = 0;
                    }
                }
                else
                {
                    // 1. If arr[ind] is added

1519
Chapter 205. Maximize array elements upto given number

                    // to obtain given val then


                    // val- arr[ind] should be 
                    // obtainable from index 
                    // ind-1.
                    // 2. If arr[ind] is subtracted
                    // to obtain given val then 
                    // val+arr[ind] should be 
                    // obtainable from index ind-1.
                    // Check for both the conditions.
                    if(val - arr[ind] >= 0 && 
                        val + arr[ind] <= maxLimit)
                    {
                          
                        // If either of one condition
                        // is true, then val is 
                        // obtainable at index ind.
                        if(dp[ind - 1][val - arr[ind]] == 1
                        || dp[ind - 1][val + arr[ind]] == 1)
                            dp[ind][val] = 1;
                          
                    }
                    else if(val - arr[ind] >= 0)
                    {
                        dp[ind][val] = dp[ind - 1][val - 
                                                   arr[ind]];
                    }
                    else if(val + arr[ind] <= maxLimit)
                    {
                        dp[ind][val] = dp[ind - 1][val + 
                                                   arr[ind]];
                    }
                    else
                    {
                        dp[ind][val] = 0;
                    }
                }
            }
        }
          
        // Find maximum value that 
        // is obtained at index n-1.
        for(val = maxLimit; val >= 0; val--)
        {
            if(dp[n - 1][val] == 1)
            {
                return val;
            }
        }

1520
Chapter 205. Maximize array elements upto given number

          
        // If no solution 
        // exists return -1.
        return -1;
    }
      
    // Driver Code 
    public static void main(String args[])
    {
        int num = 1;
        int []arr = new int[]{3, 10, 6, 4, 5};
        int n = arr.length;
        int maxLimit = 15;
              
        System.out.print(findMaxVal(arr, n, 
                                    num, maxLimit));
    }
}
  
// This code is contributed 
// by Manish Shaw(manishshaw1)

C#

// C# program to find maximum value of


// number obtained by using array
// elements by using dynamic programming.
using System;
  
class GFG {
      
    // Function to find maximum possible
    // value of number that can be 
    // obtained using array elements.
    static int findMaxVal(int []arr, int n, 
                    int num, int maxLimit)
    {
          
        // Variable to represent current index.
        int ind;
          
        // Variable to show value between
        // 0 and maxLimit.
        int val;
          
        // Table to store whether a value can
        // be obtained or not upto a certain
        // index 1. dp[i,j] = 1 if value j 

1521
Chapter 205. Maximize array elements upto given number

        // can be obtained upto index i.


        // 2. dp[i,j] = 0 if value j cannot be
        // obtained upto index i.
        int [,]dp = new int[n,maxLimit+1];
          
        for(ind = 0; ind < n; ind++)
        {
            for(val = 0; val <= maxLimit; val++)
            {
                // Check for index 0 if given
                // value val can be obtained 
                // by either adding to or 
                // subtracting arr[0] from num.
                if(ind == 0)
                {
                    if(num - arr[ind] == val || 
                        num + arr[ind] == val)
                    {
                        dp[ind,val] = 1;
                    }
                    else
                    {
                        dp[ind,val] = 0;
                    }
                }
                else
                {
                    // 1. If arr[ind] is added
                    // to obtain given val then
                    // val- arr[ind] should be 
                    // obtainable from index 
                    // ind-1.
                    // 2. If arr[ind] is subtracted
                    // to obtain given val then 
                    // val+arr[ind] should be 
                    // obtainable from index ind-1.
                    // Check for both the conditions.
                    if(val - arr[ind] >= 0 && 
                         val + arr[ind] <= maxLimit)
                    {
                          
                        // If either of one condition
                        // is true, then val is 
                        // obtainable at index ind.
                        if(dp[ind-1,val-arr[ind]] == 1 
                        || dp[ind-1,val+arr[ind]] == 1)
                            dp[ind,val] = 1;
                          

1522
Chapter 205. Maximize array elements upto given number

                    }
                    else if(val - arr[ind] >= 0)
                    {
                        dp[ind,val] = dp[ind-1,val-arr[ind]];
                    }
                    else if(val + arr[ind] <= maxLimit)
                    {
                        dp[ind,val] = dp[ind-1,val+arr[ind]];
                    }
                    else
                    {
                        dp[ind,val] = 0;
                    }
                }
            }
        }
          
        // Find maximum value that is obtained
        // at index n-1.
        for(val = maxLimit; val >= 0; val--)
        {
            if(dp[n-1,val] == 1)
            {
                return val;
            }
        }
          
        // If no solution exists return -1.
        return -1;
    }
      
    // Driver Code 
    static void Main()
    {
        int num = 1;
        int []arr = new int[]{3, 10, 6, 4, 5};
        int n = arr.Length;
        int maxLimit = 15;
              
        Console.Write(
             findMaxVal(arr, n, num, maxLimit));
    }
}
  
// This code is contributed by Manish Shaw
// (manishshaw1)

Output:

1523
Chapter 205. Maximize array elements upto given number

Time Complexity : O(n*maxLimit), where n is the size of array and maxLimit is the
given max value.
Auxiliary Space : O(n*maxLimit), n is the size of array and maxLimit is the given max
value.
Optimization : The space required can be reduced to O(2*maxLimit). Note that at every
index position, we are only using values from previous row. So we can create a table with
two rows, in which one of the rows store result for previous iteration and other for the
current iteration.
Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/maximize-array-elements-upto-given-number/

1524
Chapter 206

Maximize the binary matrix by


filpping submatrix once

Maximize the binary matrix by filpping submatrix once - GeeksforGeeks


Given a binary matrix of R rows and C columns. We are allowed flip to any size of sub
matrix. Flipping means changing 1 to 0 and 0 to 1. The task is maximize the number of 1s
in the matrix. Output the maximum number of 1s.
Examples:

Input : R = 3, C =3
mat[][] = { 0, 0, 1,
0, 0, 1,
1, 0, 1 }

Output : 8
Flip
0 0 1
0 0 1
1 0 1

to get

1 1 1
1 1 1
0 1 1

Input : R = 2, C = 3
mat[][] = { 0, 0, 0,
0, 0, 0 }
Output : 6

1525
Chapter 206. Maximize the binary matrix by filpping submatrix once

Create a matrix ones[][] of R rows and C columns, which precomputes the number of ones
in the submatrix from (0, 0) to (i, j) by

// Common elements in ones[i-1][j] and


// ones[i][j-1] are ones[i-1][j-1]
ones[i][j] = ones[i-1][j] + ones[i][j-1] -
ones[i-1][j-1] + (mat[i][j] == 1)

Since, we are allowed to flip sub matrix only once. We iterate over all possible submatrices
of all possible sizes for each cell (i, j) to (i + k – 1, i + k – 1). We calculate the total number
of ones after the digits are filliped in the chosen submatrix.
Total number of ones in the final matrix after flipping submatrix (i, j) to (i + k – 1) will
be Ones in the whole matrix – Ones in the chosen submatrix + Zeroes in the chosen sub
matrix. That comes out to be :-
ones[R][C] – cal(i, j, i + k, j + k – 1) + k*k – cal(i, j, i + k – 1, j + k – 1)
where cal(a, b, c, d) denotes the number of ones in square submatrix of length c – a.
Now cal(x1, y1, x2, y2) can be define by:
ones[x2][y2] – ones[x2][y1 – 1] – ones[x1 – 1][y2] + ones[x1 – 1][y1 – 1].
Below is the C++ implementation of this approach:

// C++ program to find maximum number of ones after


// one flipping in Binary Matrix
#include <bits/stdc++.h>
#define R 3
#define C 3
using namespace std;
  
// Return number of ones in square submatrix of size
// k x k starting from (x, y)
int cal(int ones[R + 1][C + 1], int x, int y, int k)
{
    return ones[x + k - 1][y + k - 1] - ones[x - 1][y + k - 1]
           - ones[x + k - 1][y - 1] + ones[x - 1][y - 1];
}
  
// Return maximum number of 1s after flipping a submatrix
int sol(int mat[R][C])
{
    int ans = 0;
  
    // Precomputing the number of 1s
    int ones[R + 1][C + 1] = {0};
    for (int i = 1; i <= R; i++)
        for (int j = 1; j <= C; j++)
            ones[i][j] = ones[i - 1][j] + ones[i][j - 1] -

1526
Chapter 206. Maximize the binary matrix by filpping submatrix once

                         ones[i - 1][j - 1] +
                         (mat[i - 1][j - 1] == 1);
  
    // Finding the maximum number of 1s after flipping
    for (int k = 1; k <= min(R, C); k++)
        for (int i = 1; i + k - 1 <= R; i++)
            for (int j = 1; j + k - 1 <= C; j++)
                ans = max(ans, (ones[R][C] + k * k -
                                2 * cal(ones, i, j, k)));
    return ans;
}
  
// Driver code
int main()
{
    int mat[R][C] = {{0, 0, 1},
        { 0, 0, 1},
        { 1, 0, 1 }
    };
  
    cout << sol(mat) << endl;
  
    return 0;
}

Output:

Time Complexity: O(R*C*min(R, C))

Source

https://www.geeksforgeeks.org/maximize-binary-matrix-filpping-submatrix/

1527
Chapter 207

Maximize the sum of selected


numbers from an array to make
it empty

Maximize the sum of selected numbers from an array to make it empty - GeeksforGeeks
Given an array of N numbers, we need to maximize the sum of selected numbers. At each
step you need to select a number Ai , delete one occurrence of Ai -1 (if exists), Ai +1 (if
exists) and Ai each from the array. Repeat these steps until the array gets empty. The
problem is to maximize the sum of selected numbers.
Note: We have to delete Ai +1 and Ai -1 elements if they are present in the array and not
Ai+1 and Ai-1 .
Examples:

Input : a[] = {1, 2, 3}


Output : 4
Explanation: At first step we select 1, so 1 and
2 are deleted from the sequence leaving us with 3.
Then we select 3 from the sequence and delete it.
So the sum of selected numbers is 1+3 = 4.

Input : a[] = {1, 2, 2, 2, 3, 4}


Output : 10
Explanation : Select one of the 2's from the array, so
2, 2-1, 2+1 will be deleted and we are left with {2, 2, 4},
since 1 and 3 are deleted. Select 2 in next two steps,
and then select 4 in the last step.
We get a sum of 2+2+2+4=10 which is the maximum possible.

1528
Chapter 207. Maximize the sum of selected numbers from an array to make it empty

Our aim is to maximize the sum of selected numbers. The idea is to pre-calculate the
occurrence of all numbers x in the array a[] in a hash ans. Now our recurrence relation will
decide either to select a number or not. If we select the number then we take the occurrences
of that number and the value stored at ans[i-2] as ans[i-1] will be deleted and not be taken to
count. If we do not select the number then we take ans[i-1] which have been pre-calculated
while moving forward.

ans[i] = max(ans[i-1], ans[i-2] + ans[i]*i )

At the end, ans[maximum] will have the maximum sum of selected numbers.
Below is the implementation of above idea:

// CPP program to Maximize the sum of selected


// numbers by deleting three consecutive numbers.
#include <bits/stdc++.h>
using namespace std;
  
// function to maximize the sum of selected numbers
int maximizeSum(int a[], int n) {
  
  // stores the occurrences of the numbers
  unordered_map<int, int> ans;
  
  // marks the occurrence of every number in the sequence
  for (int i = 0; i < n; i++)
    ans[a[i]]++;
  
  // maximum in the sequence
  int maximum = *max_element(a, a + n);
  
  // traverse till maximum and apply the recurrence relation
  for (int i = 2; i <= maximum; i++) 
    ans[i] = max(ans[i - 1], ans[i - 2] + ans[i] * i);  
  
  // return the ans stored in the index of maximum
  return ans[maximum];
}
  
// Driver code
int main() 
{
  int a[] = {1, 2, 3};
  int n = sizeof(a) / sizeof(a[0]);
  cout << maximizeSum(a, n);
  return 0;
}

1529
Chapter 207. Maximize the sum of selected numbers from an array to make it empty

Output:

Time Complexity: O(Amax ), where Amax is the maximum element present in the array
A[].

Source

https://www.geeksforgeeks.org/maximize-sum-selected-numbers-performing-following-operation/

1530
Chapter 208

Maximum Product Subarray |


Added negative product case

Maximum Product Subarray | Added negative product case - GeeksforGeeks


Given an array that contains both positive and negative integers, find the product of the
maximum product subarray. Expected Time complexity is O(n) and only O(1) extra space
can be used. The maximum product can be positive, negative or zero.
Examples:

Input : arr[] = {-2, -3, 0, -2, -40}


Output : 80
Subarray : arr[3..4] i.e.{-2, -40}

Input : arr[] = {0, -4, 0, -2}


Output : 0

We have discussed this problem in Maximum Product Subarray, but there is a restriction
that result can only be positive. For maximum product to be negative or zero, the values of
variable maxval (maximum product upto current element) and minval (minimum product
upto current element), has to be updated as follows:

1. When arr[i] is positive: As maxval is maximum possible value, simply multiply arr[i]
with maxval to obtain new maxval. minval is minimum possible negative product. If
its previous value is negative then simply multiply it with arr[i]. If its value is 1 keep
it as 1.
2. When arr[i] is 0: Update maxval with zero in case all other elements are negative
then this is the maximum possible product so far. Update minval with 1 as subarray
product with zero as element in it will be zero, which is not minimum. So to include
next element exclude this zero from minval by setting it to 1, i.e., restarting product
calculation.

1531
Chapter 208. Maximum Product Subarray | Added negative product case

3. When arr[i] is negative: new value of maxval is previous minval*arr[i] and new value
of minval is previous maxval*arr[i]. Before updating maxval, store its previous value
in prevMax to be used to update minval.

Implementation:

// C++ program to find maximum subarray product.


#include <bits/stdc++.h>
  
using namespace std;
  
// Function to find maximum subarray product.
int findMaxProduct(int arr[], int n)
{
    int i;
  
    // As maximum product can be negative, so
    // initialize ans with minimum integer value.
    int ans = INT_MIN;
  
    // Variable to store maximum product until
    // current value.
    int maxval = 1;
  
    // Variable to store minimum product until
    // current value.
    int minval = 1;
  
    // Variable used during updation of maximum
    // product and minimum product.
    int prevMax;
  
    for (i = 0; i < n; i++) {
  
        // If current element is positive, update
        // maxval. Update minval if it is
        // negative.
        if (arr[i] > 0) {
            maxval = maxval * arr[i];
            minval = min(1, minval * arr[i]);
        }
  
        // If current element is zero, maximum
        // product cannot end at current element.
        // Update minval with 1 and maxval with 0.
        // maxval is updated to 0 as in case all
        // other elements are negative, then maxval
        // is 0.

1532
Chapter 208. Maximum Product Subarray | Added negative product case

        else if (arr[i] == 0) {
            minval = 1;
            maxval = 0;
        }
  
        // If current element is negative, then new
        // value of maxval is previous minval*arr[i]
        // and new value of minval is previous
        // maxval*arr[i]. Before updating maxval,
        // store its previous value in prevMax to
        // be used to update minval.
        else if (arr[i] < 0) {
            prevMax = maxval;
            maxval = minval * arr[i];
            minval = prevMax * arr[i];
        }
  
        // Update ans if necessary.
        ans = max(ans, maxval);
  
        // If maxval is zero, then to calculate
        // product for next iteration, it should
        // be set to 1 as maximum product
        // subarray does not include 0.
        // The minimum possible value
        // to be considered in maximum product
        // subarray is already stored in minval,
        // so when maxval is negative it is set to 1.
        if (maxval <= 0) {
            maxval = 1;
        }
    }
  
    return ans;
}
  
int main()
{
    int arr[] = { 0, -4, 0, -2 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << findMaxProduct(arr, n);
    return 0;
}

Output: 0

Time Complexity: O(n)

1533
Chapter 208. Maximum Product Subarray | Added negative product case

Auxiliary Space: O(1)

Source

https://www.geeksforgeeks.org/maximum-product-subarray-added-negative-product-case/

1534
Chapter 209

Maximum Subarray Sum


Excluding Certain Elements

Maximum Subarray Sum Excluding Certain Elements - GeeksforGeeks


Given an array of A of n integers and an array B of m integers find the Maximum Contiguous
Subarray Sum of array A such that any element of array B is not present in that subarray
Examples :

Input : A = {1, 7, -10, 6, 2}, B = {5, 6, 7, 1}


Output : 2
Explanation Since the Maximum Sum Subarray of A is not allowed to have
any element that is present in array B.
The Maximum Sum Subarray satisfying this is {2} as the only allowed subarrays
are:{-10} and {2}. The Maximum Sum Subarray being {2} which sums to 2
Input : A = {3, 4, 5, -4, 6}, B = {1, 8, 5}
Output : 7
Explanation
The Maximum Sum Subarray satisfying this is {3, 4} as the only allowed subar-
rays are {3}, {4}, {3, 4}, {-4}, {6}, {-4, 6}. The Maximum Sum subarray being
{3, 4} which sums to 7

Method 1 (O(n*m) approach):


We can solve this problem using the Kadane’s Algorithm. Since we don’t want any of the
elements of array B to be part of any subarray of A, we need to modify the classical Kadane’s
Algorithm a little.
Whenever we consider an element in the Kadane’s algorithm we either extend current sub-
array or we start a new subarray.

1535
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

curr_max = max(a[i], curr_max+a[i]);


if (curr_max < 0)
curr_max = 0

Now, in this problem when we consider any element, we check by linearly searchingin the
array B, if that element is present in B then we set curr_max to zero which means that
at that index all subarrays we considered upto that point would end and not be extended
further as no further contiguous arrays can be formed, i.e

If Ai is present in B, all subarrays in A from 0 to (i – 1) cannot be extended


further as, the ith element can never be included in any subarray

If the current element of array A is not part of array B, we proceed with the Kadane’s
Algorithm and keep track of the max_so_far.
C++

// C++ Program to find max subarray


// sum excluding some elements
#include <bits/stdc++.h>
using namespace std;
  
// Function to check the element 
// present in array B
bool isPresent(int B[], int m, int x)
{
    for (int i = 0; i < m; i++)
        if (B[i] == x)
            return true;
    return false;
}
  
// Utility function for findMaxSubarraySum()
// with the following parameters 
// A => Array A,
// B => Array B,
// n => Number of elements in Array A,
// m => Number of elements in Array B 
int findMaxSubarraySumUtil(int A[], int B[],
                        int n, int m)
{
  
    // set max_so_far to INT_MIN
    int max_so_far = INT_MIN, curr_max = 0;
  
    for (int i = 0; i < n; i++) {
  
        // if the element is present in B, 

1536
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

        // set current max to 0 and move to 


        // the next element */
        if (isPresent(B, m, A[i])) {
            curr_max = 0;
            continue;
        }
  
        // Proceed as in Kadane's Algorithm 
        curr_max = max(A[i], curr_max + A[i]);
        max_so_far = max(max_so_far, curr_max);
    }
    return max_so_far;
}
  
// Wrapper for findMaxSubarraySumUtil() 
void findMaxSubarraySum(int A[], int B[],
                        int n, int m)
{
    int maxSubarraySum = findMaxSubarraySumUtil(A, B,
                                                n, m);
  
    // This case will occour when all elements
    // of A are are present in B, thus
    // no subarray can be formed 
    if (maxSubarraySum == INT_MIN) {
        cout << "Maximum Subarray Sum cant be found"
             << endl;
    }
    else {
        cout << "The Maximum Subarray Sum = "
            << maxSubarraySum << endl;
    }
}
  
// Driver Code
int main()
{
    int A[] = { 3, 4, 5, -4, 6 };
    int B[] = { 1, 8, 5 };
  
    int n = sizeof(A) / sizeof(A[0]);
    int m = sizeof(B) / sizeof(B[0]);
  
    // Calling function
    findMaxSubarraySum(A, B, n, m);
  
    return 0;
}

1537
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

Java

// Java Program to find max subarray


// sum excluding some elements
import java.io.*;
  
class GFG {
  
    // Function to check the element 
    // present in array B
    static boolean isPresent(int B[],
                            int m,
                            int x)
    {
        for (int i = 0; i < m; i++)
            if (B[i] == x)
                return true;
  
        return false;
    }
  
    // Utility function for findMaxSubarraySum()
    // with the following parameters
    // A => Array A,
    // B => Array B,
    // n => Number of elements in Array A,
    // m => Number of elements in Array B
    static int findMaxSubarraySumUtil(int A[], int B[],
                                      int n, int m)
    {
  
        // set max_so_far to INT_MIN
        int max_so_far = -2147483648, curr_max = 0;
  
        for (int i = 0; i < n; i++) {
  
            // if the element is present in B,
            // set current max to 0 and move to
            // the next element
            if (isPresent(B, m, A[i])) {
                curr_max = 0;
                continue;
            }
  
            // Proceed as in Kadane's Algorithm
            curr_max = Math.max(A[i], curr_max + A[i]);
            max_so_far = Math.max(max_so_far, curr_max);
        }

1538
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

        return max_so_far;
    }
  
    // Wrapper for findMaxSubarraySumUtil()
    static void findMaxSubarraySum(int A[], int B[],
                                   int n, int m)
    {
        int maxSubarraySum = findMaxSubarraySumUtil(A, B,
                                                    n, m);
  
        // This case will occour when all
        // elements of A are are present
        // in B, thus no subarray can be formed
        if (maxSubarraySum == -2147483648) {
                        System.out.println("Maximum Subarray Sum"
                                        + " " + "can't be found");
                                              
        }
        else {
            System.out.println("The Maximum Subarray Sum = "
                                + maxSubarraySum);
        }
    }
  
    // Driver code
    public static void main(String[] args)
    {
  
        int A[] = { 3, 4, 5, -4, 6 };
        int B[] = { 1, 8, 5 };
  
        int n = A.length;
        int m = B.length;
  
        // Calling Function
        findMaxSubarraySum(A, B, n, m);
    }
}
  
// This code is contributed by Ajit.

C#

// C# Program to find max subarray


// sum excluding some elements
using System;
  
class GFG {

1539
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

      
    // Function to check the element 
    // present in array B
    static bool isPresent(int[] B, int m, 
                                   int x)
    {
        for (int i = 0; i < m; i++)
            if (B[i] == x)
                return true;
  
        return false;
    }
  
    // Utility function for findMaxSubarraySum()
    // with the following parameters
    // A => Array A,
    // B => Array B,
    // n => Number of elements in Array A,
    // m => Number of elements in Array B
    static int findMaxSubarraySumUtil(int[] A, int[] B,
                                      int n, int m)
    {
  
        // set max_so_far to INT_MIN
        int max_so_far = -2147483648, curr_max = 0;
  
        for (int i = 0; i < n; i++) {
  
            // if the element is present in B,
            // set current max to 0 and move to
            // the next element
            if (isPresent(B, m, A[i])) {
                curr_max = 0;
                continue;
            }
  
            // Proceed as in Kadane's Algorithm
            curr_max = Math.Max(A[i], curr_max + A[i]);
            max_so_far = Math.Max(max_so_far, curr_max);
        }
        return max_so_far;
    }
  
    // Wrapper for findMaxSubarraySumUtil()
    static void findMaxSubarraySum(int[] A, int[] B,
                                    int n, int m)
    {
        int maxSubarraySum = findMaxSubarraySumUtil(A, B,

1540
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

                                                    n, m);
  
        // This case will occour when all
        // elements of A are are present
        // in B, thus no subarray can be formed
        if (maxSubarraySum == -2147483648)
        {
            Console.Write("Maximum Subarray Sum"
                           + " " + "can't be found");
                                              
        }
        else 
        {
            Console.Write("The Maximum Subarray Sum = "
                           + maxSubarraySum);
        }
    }
      
    // Driver Code
    static public void Main ()
    {
          
        int[] A = {3, 4, 5, -4, 6};
        int[] B = {1, 8, 5};
  
        int n = A.Length;
        int m = B.Length;
  
        // Calling Function
        findMaxSubarraySum(A, B, n, m);
      
    }
}
  
// This code is contributed by Shrikant13.

PHP

<?php
// PHP Program to find max subarray
// sum excluding some elements
  
// Function to check the element 
// present in array B
function isPresent($B, $m, $x)
{
    for ($i = 0; $i < $m; $i++)
        if ($B[$i] == $x)

1541
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

            return true;
    return false;
}
  
// Utility function for 
// findMaxSubarraySum() 
// with the following 
// parameters 
// A => Array A,
// B => Array B,
// n => Number of elements
//      in Array A,
// m => Number of elements 
//      in Array B 
function findMaxSubarraySumUtil($A, $B,
                                $n, $m)
{
  
    // set max_so_far
    // to INT_MIN
    $max_so_far = PHP_INT_MIN;
    $curr_max = 0;
  
    for ($i = 0; $i < $n; $i++) 
    {
  
        // if the element is present 
        // in B, set current max to 
        // 0 and move to the next 
        // element 
        if (isPresent($B, $m, $A[$i]))
        {
            $curr_max = 0;
            continue;
        }
  
        // Proceed as in
        // Kadane's Algorithm 
        $curr_max = max($A[$i], 
        $curr_max + $A[$i]);
        $max_so_far = max($max_so_far, 
                          $curr_max);
    }
    return $max_so_far;
}
  
// Wrapper for 
// findMaxSubarraySumUtil() 

1542
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

function findMaxSubarraySum($A, $B,


                            $n, $m)
{
    $maxSubarraySum = findMaxSubarraySumUtil($A, $B,
                                             $n, $m);
  
    // This case will occour 
    // when all elements of 
    // A are are present in
    // B, thus no subarray 
    // can be formed 
    if ($maxSubarraySum == PHP_INT_MIN) 
    {
        echo ("Maximum Subarray " . 
            "Sum cant be found\n");
    }
    else 
    {
        echo ("The Maximum Subarray Sum = ". 
                     $maxSubarraySum. "\n");
    }
}
  
// Driver Code
$A = array(3, 4, 5, -4, 6);
$B = array(1, 8, 5);
  
$n = count($A);
$m = count($B);
  
// Calling function
findMaxSubarraySum($A, $B, $n, $m);
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

Output :

The Maximum Subarray Sum = 7

Time Complexity of this approach is O(n*m)


Method 2 (O((n+m)*log(m)) approach)
The main idea behind this approach is exactly the same as that of method 1. This approach
just makes the searching of an element of array A, in array B, faster by using Binary

1543
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

Search
Note: We need to sort the Array B to apply Binary Search on it.
C++

// C++ Program to find max subarray 


// sum excluding some elements
#include <bits/stdc++.h>
using namespace std;
  
// Utility function for findMaxSubarraySum()
// with the following parameters 
// A => Array A,
// B => Array B,
// n => Number of elements in Array A,
// m => Number of elements in Array B 
int findMaxSubarraySumUtil(int A[], int B[],
                           int n, int m)
{
  
    // set max_so_far to INT_MIN
    int max_so_far = INT_MIN, curr_max = 0;
  
    for (int i = 0; i < n; i++) {
  
        // if the element is present in B, 
        // set current max to 0 and move to
        // the next element 
        if (binary_search(B, B + m, A[i])) {
            curr_max = 0;
            continue;
        }
  
        // Proceed as in Kadane's Algorithm 
        curr_max = max(A[i], curr_max + A[i]);
        max_so_far = max(max_so_far, curr_max);
    }
    return max_so_far;
}
  
// Wrapper for findMaxSubarraySumUtil()
void findMaxSubarraySum(int A[], int B[], 
                        int n, int m)
{
    // sort array B to apply Binary Search
    sort(B, B + m);
  
    int maxSubarraySum = findMaxSubarraySumUtil(A, B, 
                                                n, m);

1544
Chapter 209. Maximum Subarray Sum Excluding Certain Elements

  
    // This case will occour when all elements
    // of A are present in B, thus no subarray 
    // can be formed 
    if (maxSubarraySum == INT_MIN) {
        cout << "Maximum subarray sum cant be found"
            << endl;
    }
    else {
        cout << "The Maximum subarray sum = "
             << maxSubarraySum << endl;
    }
}
  
// Driver Code
int main()
{
    int A[] = { 3, 4, 5, -4, 6 };
    int B[] = { 1, 8, 5 };
  
    int n = sizeof(A) / sizeof(A[0]);
    int m = sizeof(B) / sizeof(B[0]);
  
    // Calling fucntion
    findMaxSubarraySum(A, B, n, m);
    return 0;
}

Output :

The Maximum subarray sum = 7

Time Complexity of this approach is O(nlog(m) + mlog(m)) or O((n + m)log(m)).


Note: The mlog(m) factor is due to sorting the array B.
Improved By : jit_t, shrikanth13, manishshaw1

Source

https://www.geeksforgeeks.org/maximum-subarray-sum-excluding-certain-elements/

1545
Chapter 210

Maximum Subarray Sum using


Divide and Conquer algorithm

Maximum Subarray Sum using Divide and Conquer algorithm - GeeksforGeeks


You are given a one dimensional array that may contain both positive and negative integers,
find the sum of contiguous subarray of numbers which has the largest sum.
For example, if the given array is {-2, -5, 6, -2, -3, 1, 5, -6}, then the maximum subarray
sum is 7 (see highlighted elements).
The naive method is to run two loops. The outer loop picks the beginning element, the
inner loop finds the maximum possible sum with first element picked by outer loop and
compares this maximum with the overall maximum. Finally return the overall maximum.
The time complexity of the Naive method is O(n^2).
Using Divide and Conquer approach, we can find the maximum subarray sum in O(nLogn)
time. Following is the Divide and Conquer algorithm.
1) Divide the given array in two halves
2) Return the maximum of following three
….a) Maximum subarray sum in left half (Make a recursive call)
….b) Maximum subarray sum in right half (Make a recursive call)
….c) Maximum subarray sum such that the subarray crosses the midpoint
The lines 2.a and 2.b are simple recursive calls. How to find maximum subarray sum such
that the subarray crosses the midpoint? We can easily find the crossing sum in linear time.
The idea is simple, find the maximum sum starting from mid point and ending at some
point on left of mid, then find the maximum sum starting from mid + 1 and ending with
sum point on right of mid + 1. Finally, combine the two and return.

C++

// A Divide and Conquer based program for maximum subarray sum problem
#include <stdio.h>

1546
Chapter 210. Maximum Subarray Sum using Divide and Conquer algorithm

#include <limits.h>
  
// A utility funtion to find maximum of two integers
int max(int a, int b) { return (a > b)? a : b; }
  
// A utility funtion to find maximum of three integers
int max(int a, int b, int c) { return max(max(a, b), c); }
  
// Find the maximum possible sum in arr[] auch that arr[m] is part of it
int maxCrossingSum(int arr[], int l, int m, int h)
{
    // Include elements on left of mid.
    int sum = 0;
    int left_sum = INT_MIN;
    for (int i = m; i >= l; i--)
    {
        sum = sum + arr[i];
        if (sum > left_sum)
          left_sum = sum;
    }
  
    // Include elements on right of mid
    sum = 0;
    int right_sum = INT_MIN;
    for (int i = m+1; i <= h; i++)
    {
        sum = sum + arr[i];
        if (sum > right_sum)
          right_sum = sum;
    }
  
    // Return sum of elements on left and right of mid
    return left_sum + right_sum;
}
  
// Returns sum of maxium sum subarray in aa[l..h]
int maxSubArraySum(int arr[], int l, int h)
{
   // Base Case: Only one element
   if (l == h)
     return arr[l];
  
   // Find middle point
   int m = (l + h)/2;
  
   /* Return maximum of following three possible cases
      a) Maximum subarray sum in left half
      b) Maximum subarray sum in right half

1547
Chapter 210. Maximum Subarray Sum using Divide and Conquer algorithm

      c) Maximum subarray sum such that the subarray crosses the midpoint */
   return max(maxSubArraySum(arr, l, m),
              maxSubArraySum(arr, m+1, h),
              maxCrossingSum(arr, l, m, h));
}
  
/*Driver program to test maxSubArraySum*/
int main()
{
   int arr[] = {2, 3, 4, 5, 7};
   int n = sizeof(arr)/sizeof(arr[0]);
   int max_sum = maxSubArraySum(arr, 0, n-1);
   printf("Maximum contiguous sum is %dn", max_sum);
   getchar();
   return 0;
}

Java

// A Divide and Conquer based Java 


// program for maximum subarray sum
// problem
import java.util.*;
  
class GFG {
  
    // Find the maximum possible sum in arr[] 
    // such that arr[m] is part of it
    static int maxCrossingSum(int arr[], int l,
                                int m, int h)
    {
        // Include elements on left of mid.
        int sum = 0;
        int left_sum = Integer.MIN_VALUE;
        for (int i = m; i >= l; i--)
        {
            sum = sum + arr[i];
            if (sum > left_sum)
            left_sum = sum;
        }
  
        // Include elements on right of mid
        sum = 0;
        int right_sum = Integer.MIN_VALUE;
        for (int i = m + 1; i <= h; i++)
        {
            sum = sum + arr[i];
            if (sum > right_sum)

1548
Chapter 210. Maximum Subarray Sum using Divide and Conquer algorithm

            right_sum = sum;
        }
  
        // Return sum of elements on left
        // and right of mid
        return left_sum + right_sum;
    }
  
    // Returns sum of maxium sum subarray 
    // in aa[l..h]
    static int maxSubArraySum(int arr[], int l, 
                                      int h)
    {
    // Base Case: Only one element
    if (l == h)
        return arr[l];
  
    // Find middle point
    int m = (l + h)/2;
  
    /* Return maximum of following three 
    possible cases:
    a) Maximum subarray sum in left half
    b) Maximum subarray sum in right half
    c) Maximum subarray sum such that the 
    subarray crosses the midpoint */
    return Math.max(Math.max(maxSubArraySum(arr, l, m),
                    maxSubArraySum(arr, m+1, h)),
                    maxCrossingSum(arr, l, m, h));
    }
  
    /* Driver program to test maxSubArraySum */
    public static void main(String[] args)
    {
    int arr[] = {2, 3, 4, 5, 7};
    int n = arr.length;
    int max_sum = maxSubArraySum(arr, 0, n-1);
      
    System.out.println("Maximum contiguous sum is "+
                                         max_sum);
    }
}
// This code is contributed by Prerna Saini

Python3

# A Divide and Conquer based program


# for maximum subarray sum problem

1549
Chapter 210. Maximum Subarray Sum using Divide and Conquer algorithm

  
# Find the maximum possible sum in
# arr[] auch that arr[m] is part of it
def maxCrossingSum(arr, l, m, h) :
      
    # Include elements on left of mid.
    sm = 0; left_sum = -10000
      
    for i in range(m, l-1, -1) :
        sm = sm + arr[i]
          
        if (sm > left_sum) :
            left_sum = sm
      
      
    # Include elements on right of mid
    sm = 0; right_sum = -1000
    for i in range(m + 1, h + 1) :
        sm = sm + arr[i]
          
        if (sm > right_sum) :
            right_sum = sm
      
  
    # Return sum of elements on left and right of mid
    return left_sum + right_sum;
  
  
# Returns sum of maxium sum subarray in aa[l..h]
def maxSubArraySum(arr, l, h) :
      
    # Base Case: Only one element
    if (l == h) :
        return arr[l]
  
    # Find middle point
    m = (l + h) // 2
  
    # Return maximum of following three possible cases
    # a) Maximum subarray sum in left half
    # b) Maximum subarray sum in right half
    # c) Maximum subarray sum such that the 
    #     subarray crosses the midpoint 
    return max(maxSubArraySum(arr, l, m),
               maxSubArraySum(arr, m+1, h),
               maxCrossingSum(arr, l, m, h))
              
  

1550
Chapter 210. Maximum Subarray Sum using Divide and Conquer algorithm

# Driver Code
arr = [2, 3, 4, 5, 7]
n = len(arr)
  
max_sum = maxSubArraySum(arr, 0, n-1)
print("Maximum contiguous sum is ", max_sum)
  
# This code is contributed by Nikita Tiwari.

C#

// A Divide and Conquer based C# 


// program for maximum subarray sum
// problem
using System;
  
class GFG {
  
    // Find the maximum possible sum in arr[] 
    // such that arr[m] is part of it
    static int maxCrossingSum(int []arr, int l,
                                int m, int h)
    {
        // Include elements on left of mid.
        int sum = 0;
        int left_sum = int.MinValue;
        for (int i = m; i >= l; i--)
        {
            sum = sum + arr[i];
            if (sum > left_sum)
                left_sum = sum;
        }
  
        // Include elements on right of mid
        sum = 0;
        int right_sum = int.MinValue;;
        for (int i = m + 1; i <= h; i++)
        {
            sum = sum + arr[i];
            if (sum > right_sum)
                right_sum = sum;
        }
  
        // Return sum of elements on left
        // and right of mid
        return left_sum + right_sum;
    }
  

1551
Chapter 210. Maximum Subarray Sum using Divide and Conquer algorithm

    // Returns sum of maxium sum subarray 


    // in aa[l..h]
    static int maxSubArraySum(int []arr, int l, 
                                        int h)
    {
          
    // Base Case: Only one element
    if (l == h)
        return arr[l];
  
    // Find middle point
    int m = (l + h)/2;
  
    /* Return maximum of following three 
    possible cases:
    a) Maximum subarray sum in left half
    b) Maximum subarray sum in right half
    c) Maximum subarray sum such that the 
    subarray crosses the midpoint */
    return Math.Max(Math.Max(maxSubArraySum(arr, l, m),
                          maxSubArraySum(arr, m+1, h)),
                         maxCrossingSum(arr, l, m, h));
    }
  
    /* Driver program to test maxSubArraySum */
    public static void Main()
    {
        int []arr = {2, 3, 4, 5, 7};
        int n = arr.Length;
        int max_sum = maxSubArraySum(arr, 0, n-1);
          
        Console.Write("Maximum contiguous sum is "+
                                            max_sum);
    }
}
  
// This code is contributed by vt_m.

Output :

Maximum contiguous sum is 21

Time Complexity: maxSubArraySum() is a recursive method and time complexity can


be expressed as following recurrence relation.
T(n) = 2T(n/2) + Θ(n)
The above recurrence is similar to Merge Sort and can be solved either using Recurrence

1552
Chapter 210. Maximum Subarray Sum using Divide and Conquer algorithm

Tree method or Master method. It falls in case II of Master Method and solution of the
recurrence is Θ(nLogn).
The Kadane’s Algorithm for this problem takes O(n) time. Therefore the Kadane’s algo-
rithm is better than the Divide and Conquer approach, but this problem can be considered
as a good example to show power of Divide and Conquer. The above simple approach where
we divide the array in two halves, reduces the time complexity from O(n^2) to O(nLogn).
References:
Introduction to Algorithms by Clifford Stein, Thomas H. Cormen, Charles E. Leiserson,
Ronald L.

Source

https://www.geeksforgeeks.org/maximum-subarray-sum-using-divide-and-conquer-algorithm/

1553
Chapter 211

Maximum Sum Decreasing


Subsequence

Maximum Sum Decreasing Subsequence - GeeksforGeeks


Given an array of N positive integers. The task is to find the sum of maximum sum
decreasing subsequence(MSDS) of the given array such that the integers in the subsequence
are sorted in decreasing order.
Examples:

Input: arr[] = {5, 4, 100, 3, 2, 101, 1}


Output: 106
100 + 3 + 2 + 1 = 106
Input: arr[] = {10, 5, 4, 3}
Output: 22
10 + 5 + 4 + 3 = 22

This problem is a variation of Longest Decreasing Subsequence problem. The Optimal


Substructure for the above problem will be:
Let arr[0..n-1] be the input array and MSDS[i] be the maximum sum of the MSDS ending
at index i such that arr[i] is the last element of the MSDS.
Then, MSDS[i] can be written as:

MSDS[i] = a[i] + max( MSDS[j] ) where i > j > 0 and arr[j] > arr[i] or,
MSDS[i] = a[i], if no such j exists.

To find the MSDS for a given array, we need to return max(MSDS[i]) where n > i > 0.
Below is the implementation of the above approach:
C++

1554
Chapter 211. Maximum Sum Decreasing Subsequence

// CPP code to return the maximum sum


// of decreasing subsequence in arr[]
#include <bits/stdc++.h>
using namespace std;
  
// function to return the maximum
// sum of decreasing subsequence
// in arr[]
int maxSumDS(int arr[], int n)
{
    int i, j, max = 0;
    int MSDS[n];
  
    // Initialize msds values
    // for all indexes
    for (i = 0; i < n; i++)
        MSDS[i] = arr[i];
  
    // Compute maximum sum values
    // in bottom up manner
    for (i = 1; i < n; i++)
        for (j = 0; j < i; j++)
            if (arr[i] < arr[j] && MSDS[i] < MSDS[j] + arr[i])
                MSDS[i] = MSDS[j] + arr[i];
  
    // Pick maximum of all msds values
    for (i = 0; i < n; i++)
        if (max < MSDS[i])
            max = MSDS[i];
  
    return max;
}
  
// Drive Code
int main()
{
    int arr[] = { 5, 4, 100, 3, 2, 101, 1 };
      
    int n = sizeof(arr) / sizeof(arr[0]);
  
    cout << "Sum of maximum sum decreasing subsequence is: "
         << maxSumDS(arr, n);
    return 0;
}

Java

// Java code to return the maximum sum

1555
Chapter 211. Maximum Sum Decreasing Subsequence

// of decreasing subsequence in arr[]


import java.io.*;
import java.lang.*;
  
class GfG {
      
    // function to return the maximum
    // sum of decreasing subsequence
    // in arr[]
    public static int maxSumDS(int arr[], int n)
    {
        int i, j, max = 0;
        int[] MSDS = new int[n];
      
        // Initialize msds values
        // for all indexes
        for (i = 0; i < n; i++)
            MSDS[i] = arr[i];
      
        // Compute maximum sum values
        // in bottom up manner
        for (i = 1; i < n; i++)
            for (j = 0; j < i; j++)
                if (arr[i] < arr[j] && 
                    MSDS[i] < MSDS[j] + arr[i])
                    MSDS[i] = MSDS[j] + arr[i];
      
        // Pick maximum of all msds values
        for (i = 0; i < n; i++)
            if (max < MSDS[i])
                max = MSDS[i];
      
        return max;
    }
      
    // Drive Code
    public static void main(String argc[])
    {
        int arr[] = { 5, 4, 100, 3, 2, 101, 1 };
          
        int n = 7;
      
        System.out.println("Sum of maximum sum"
               + " decreasing subsequence is: "
                           + maxSumDS(arr, n));
    }
}
  

1556
Chapter 211. Maximum Sum Decreasing Subsequence

// This code os contributed by Sagar Shukla.

C#

// C# code to return the


// maximum sum of decreasing
// subsequence in arr[]
using System;
  
class GFG
{
      
    // function to return the 
    // maximum sum of decreasing
    // subsequence in arr[]
    public static int maxSumDS(int []arr, 
                               int n)
    {
        int i, j, max = 0;
        int[] MSDS = new int[n];
      
        // Initialize msds values
        // for all indexes
        for (i = 0; i < n; i++)
            MSDS[i] = arr[i];
      
        // Compute maximum sum values
        // in bottom up manner
        for (i = 1; i < n; i++)
            for (j = 0; j < i; j++)
                if (arr[i] < arr[j] && 
                    MSDS[i] < MSDS[j] + arr[i])
                    MSDS[i] = MSDS[j] + arr[i];
      
        // Pick maximum of 
        // all msds values
        for (i = 0; i < n; i++)
            if (max < MSDS[i])
                max = MSDS[i];
      
        return max;
    }
      
    // Drive Code
    static public void Main ()
    {
        int []arr = {5, 4, 100, 
                     3, 2, 101, 1};

1557
Chapter 211. Maximum Sum Decreasing Subsequence

        int n = 7;
        Console.WriteLine("Sum of maximum sum" + 
                " decreasing subsequence is: " + 
                              maxSumDS(arr, n));
    }
}
  
// This code is contributed by m_kit

PHP

<?php
// PHP code to return the maximum sum
// of decreasing subsequence in arr[]
  
// function to return the maximum
// sum of decreasing subsequence
// in arr[]
function maxSumDS($arr, $n)
{
    $i; $j; $max = 0;
    $MSDS = array();
  
    // Initialize msds values
    // for all indexes
    for ($i = 0; $i < $n; $i++)
        $MSDS[$i] = $arr[$i];
  
    // Compute maximum sum values
    // in bottom up manner
    for ($i = 1; $i < $n; $i++)
        for ($j = 0; $j < $i; $j++)
            if ($arr[$i] < $arr[$j] && 
                   $MSDS[$i] < $MSDS[$j] + $arr[$i])
                $MSDS[$i] = $MSDS[$j] + $arr[$i];
  
    // Pick maximum of 
    // all msds values
    for ($i = 0; $i < $n; $i++)
        if ($max < $MSDS[$i])
            $max = $MSDS[$i];
  
    return $max;
}
  
// Driver Code
$arr = array (5, 4, 100, 
              3, 2, 101, 1 );

1558
Chapter 211. Maximum Sum Decreasing Subsequence

  
$n = sizeof($arr);
  
echo "Sum of maximum sum decreasing " . 
                    "subsequence is: ", 
                    maxSumDS($arr, $n);
  
// This code is contributed by ajit
?>

Output:

Sum of maximum sum decreasing subsequence is: 106

Time complexity: O(N2 )


Auxiliary Space: O(N)
Improved By : jit_t

Source

https://www.geeksforgeeks.org/maximum-sum-decreasing-subsequence/

1559
Chapter 212

Maximum absolute difference


between sum of two contiguous
sub-arrays

Maximum absolute difference between sum of two contiguous sub-arrays - GeeksforGeeks


Given an array of integers, find two non-overlapping contiguous sub-arrays such that the
absolute difference between the sum of two sub-arrays is maximum.
For example,

Input: [-2, -3, 4, -1, -2, 1, 5, -3]


Output: 12
Two subarrays are [-2, -3] and [4, -1, -2, 1, 5]

Input: [2, -1, -2, 1, -4, 2, 8]


Output: 16
Two subarrays are [-1, -2, 1, -4] and [2, 8]

Expected time complexity is O(n).


The idea is for each index i in given array arr[0…n-1], compute maximum and minimum
sum subarrays that lie in subarrays arr[0…i] and arr[i+1 …n-1]. We maintain four arrays
that store the maximum and minimum sums in the subarrays arr[0…i] and arr[i+1 … n-1]
for every index i in the array.

leftMax[] : An element leftMax[i] of this


array stores the maximum value
in subarray arr[0..i]

1560
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

leftMin[] : An element leftMin[i] of this


array stores the minimum value
in subarray arr[0..i]

rightMax[] : An element rightMax[i] of this


array stores the maximum value
in subarray arr[i+1..n-1]

rightMin[] : An element rightMin[i] of this


array stores the minimum value
in subarray arr[i+1..n-1]

We can build above four arrays in O(n) time by using Kadane Algorithm.
In order to calculate maximum sum subarray that lies in arr[0…i], we run Kadane Algorithm
from 0 to n-1 and to find maximum sum subarray that lies in arr[i+1 … n-1], we run Kadane
Algorithm from n-1 to 0.
Kadane’s algorithm can be modified to find minimum absolute sum of a subarray as well.
The idea is to change the sign of each element in the array and run Kadane Algorithm to
find maximum sum subarray that lies in arr[0…i] and arr[i+1 … n-1]. Now invert the sign
of maximum subarray sum found. That will be our minimum subarray sum. This idea is
taken from here.
Now from above four arrays, we can easily find maximum absolute difference between the
sum of two contiguous sub-arrays. For each index i, take maximum of

1. abs(max sum subarray that lies in arr[0…i] – min sum subarray that lies in arr[i+1…n-
1])
2. abs(min sum subarray that lies in arr[0…i] – max sum subarray that lies in arr[i+1…n-
1])

Below is the implementation of above idea.

C++

// C++ program to find two non-overlapping contiguous


// sub-arrays such that the absolute difference
// between the sum of two sub-array is maximum.
#include <bits/stdc++.h>
using namespace std;
  
// Find maximum subarray sum for subarray [0..i]
// using standard Kadane's algorithm. This version of
// Kadane's Algorithm will work if all numbers are
// negative.
int maxLeftSubArraySum(int a[], int size, int sum[])
{

1561
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

    int max_so_far = a[0];


    int curr_max = a[0];
    sum[0] = max_so_far;
  
    for (int i = 1; i < size; i++)
    {
        curr_max = max(a[i], curr_max + a[i]);
        max_so_far = max(max_so_far, curr_max);
        sum[i] = max_so_far;
    }
  
    return max_so_far;
}
  
// Find maximum subarray sum for subarray [i..n]
// using Kadane's algorithm. This version of Kadane's
// Algorithm will work if all numbers are negative
int maxRightSubArraySum(int a[], int n, int sum[])
{
    int max_so_far = a[n];
    int curr_max = a[n];
    sum[n] = max_so_far;
  
    for (int i = n-1; i >= 0; i--)
    {
        curr_max = max(a[i], curr_max + a[i]);
        max_so_far = max(max_so_far, curr_max);
        sum[i] = max_so_far;
    }
  
    return max_so_far;
}
  
// The function finds two non-overlapping contiguous
// sub-arrays such that the absolute difference
// between the sum of two sub-array is maximum.
int findMaxAbsDiff(int arr[], int n)
{
    // create and build an array that stores
    // maximum sums of subarrays that lie in
    // arr[0...i]
    int leftMax[n];
    maxLeftSubArraySum(arr, n, leftMax);
  
    // create and build an array that stores
    // maximum sums of subarrays that lie in
    // arr[i+1...n-1]
    int rightMax[n];

1562
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

    maxRightSubArraySum(arr, n-1, rightMax);


  
    // Invert array (change sign) to find minumum
    // sum subarrays.
    int invertArr[n];
    for (int i = 0; i < n; i++)
        invertArr[i] = -arr[i];
  
    // create and build an array that stores
    // minimum sums of subarrays that lie in
    // arr[0...i]
    int leftMin[n];
    maxLeftSubArraySum(invertArr, n, leftMin);
    for (int i = 0; i < n; i++)
        leftMin[i] = -leftMin[i];
  
    // create and build an array that stores
    // minimum sums of subarrays that lie in
    // arr[i+1...n-1]
    int rightMin[n];
    maxRightSubArraySum(invertArr, n - 1, rightMin);
    for (int i = 0; i < n; i++)
        rightMin[i] = -rightMin[i];
  
    int result = INT_MIN;
    for (int i = 0; i < n - 1; i++)
    {
        /* For each index i, take maximum of
        1. abs(max sum subarray that lies in arr[0...i] -
            min sum subarray that lies in arr[i+1...n-1])
        2. abs(min sum subarray that lies in arr[0...i] -
            max sum subarray that lies in arr[i+1...n-1]) */
        int absValue = max(abs(leftMax[i] - rightMin[i + 1]),
                        abs(leftMin[i] - rightMax[i + 1]));
        if (absValue > result)
            result = absValue;
    }
  
    return result;
}
  
// Driver program
int main()
{
    int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
  
    int n = sizeof(a) / sizeof(a[0]);
  

1563
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

    cout << findMaxAbsDiff(a, n);


  
    return 0;
}

Java

// Java program to find two non-overlapping


// contiguous sub-arrays such that the 
// absolute difference
import java.util.*;
  
class GFG {
      
    // Find maximum subarray sum for subarray
    // [0..i] using standard Kadane's algorithm.
    // This version of Kadane's Algorithm will 
    // work if all numbers are negative.
    static int maxLeftSubArraySum(int a[], int size, 
                                          int sum[])
    {
        int max_so_far = a[0];
        int curr_max = a[0];
        sum[0] = max_so_far;
  
        for (int i = 1; i < size; i++) {
            curr_max = Math.max(a[i], curr_max + a[i]);
            max_so_far = Math.max(max_so_far, curr_max);
            sum[i] = max_so_far;
        }
  
        return max_so_far;
    }
  
    // Find maximum subarray sum for subarray [i..n]
    // using Kadane's algorithm. This version of Kadane's
    // Algorithm will work if all numbers are negative
    static int maxRightSubArraySum(int a[], int n, int sum[])
    {
        int max_so_far = a[n];
        int curr_max = a[n];
        sum[n] = max_so_far;
  
        for (int i = n - 1; i >= 0; i--) {
            curr_max = Math.max(a[i], curr_max + a[i]);
            max_so_far = Math.max(max_so_far, curr_max);
            sum[i] = max_so_far;
        }

1564
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

  
        return max_so_far;
    }
  
    // The function finds two non-overlapping contiguous
    // sub-arrays such that the absolute difference
    // between the sum of two sub-array is maximum.
    static int findMaxAbsDiff(int arr[], int n)
    {
        // create and build an array that stores
        // maximum sums of subarrays that lie in
        // arr[0...i]
        int leftMax[] = new int[n];
        maxLeftSubArraySum(arr, n, leftMax);
  
        // create and build an array that stores
        // maximum sums of subarrays that lie in
        // arr[i+1...n-1]
        int rightMax[] = new int[n];
        maxRightSubArraySum(arr, n - 1, rightMax);
  
        // Invert array (change sign) to find minumum
        // sum subarrays.
        int invertArr[] = new int[n];
        for (int i = 0; i < n; i++)
            invertArr[i] = -arr[i];
  
        // create and build an array that stores
        // minimum sums of subarrays that lie in
        // arr[0...i]
        int leftMin[] = new int[n];
        maxLeftSubArraySum(invertArr, n, leftMin);
        for (int i = 0; i < n; i++)
            leftMin[i] = -leftMin[i];
  
        // create and build an array that stores
        // minimum sums of subarrays that lie in
        // arr[i+1...n-1]
        int rightMin[] = new int[n];
        maxRightSubArraySum(invertArr, n - 1, rightMin);
        for (int i = 0; i < n; i++)
            rightMin[i] = -rightMin[i];
  
        int result = -2147483648;
        for (int i = 0; i < n - 1; i++) {
              
        /* For each index i, take maximum of
        1. abs(max sum subarray that lies in arr[0...i] -

1565
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

            min sum subarray that lies in arr[i+1...n-1])


        2. abs(min sum subarray that lies in arr[0...i] -
            max sum subarray that lies in arr[i+1...n-1]) */
            int absValue = Math.max(Math.abs(leftMax[i] - rightMin[i + 1]),
                                    Math.abs(leftMin[i] - rightMax[i + 1]));
            if (absValue > result)
                result = absValue;
        }
  
        return result;
    }
      
    // driver code
    public static void main(String[] args)
    {
        int a[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = a.length;
        System.out.print(findMaxAbsDiff(a, n));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

   
# Python3 program to find two non-
# overlapping contiguous sub-arrays
# such that the absolute difference
# between the sum of two sub-array is maximum.
  
# Find maximum subarray sum for
# subarray [0..i] using standard
# Kadane's algorithm. This version 
# of Kadane's Algorithm will work if 
# all numbers are negative.
def maxLeftSubArraySum(a, size, sum):
  
    max_so_far = a[0]
    curr_max = a[0]
    sum[0] = max_so_far
  
    for i in range(1, size):
      
        curr_max = max(a[i], curr_max + a[i])
        max_so_far = max(max_so_far, curr_max)
        sum[i] = max_so_far
      

1566
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

    return max_so_far
  
# Find maximum subarray sum for
# subarray [i..n] using Kadane's
# algorithm. This version of Kadane's
# Algorithm will work if all numbers are negative
def maxRightSubArraySum(a, n, sum):
  
    max_so_far = a[n]
    curr_max = a[n]
    sum[n] = max_so_far
  
    for i in range(n - 1, -1, -1):
      
        curr_max = max(a[i], curr_max + a[i])
        max_so_far = max(max_so_far, curr_max)
        sum[i] = max_so_far
  
    return max_so_far
  
# The function finds two non-overlapping
# contiguous sub-arrays such that the
# absolute difference between the sum
# of two sub-array is maximum.
def findMaxAbsDiff(arr, n):
  
    # create and build an array that 
    # stores maximum sums of subarrays 
    # that lie in arr[0...i]
    leftMax = [0 for i in range(n)]
    maxLeftSubArraySum(arr, n, leftMax)
  
    # create and build an array that stores
    # maximum sums of subarrays that lie in
    # arr[i+1...n-1]
    rightMax = [0 for i in range(n)]
    maxRightSubArraySum(arr, n-1, rightMax)
  
    # Invert array (change sign) to 
    # find minumum sum subarrays.
    invertArr = [0 for i in range(n)]
    for i in range(n):
        invertArr[i] = -arr[i]
  
    # create and build an array that stores
    # minimum sums of subarrays that lie in
    # arr[0...i]
    leftMin = [0 for i in range(n)]

1567
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

    maxLeftSubArraySum(invertArr, n, leftMin)
    for i in range(n):
        leftMin[i] = -leftMin[i]
  
    # create and build an array that stores
    # minimum sums of subarrays that lie in
    # arr[i+1...n-1]
    rightMin = [0 for i in range(n)]
    maxRightSubArraySum(invertArr, n - 1, rightMin)
    for i in range(n):
        rightMin[i] = -rightMin[i]
  
    result = -2147483648
    for i in range(n - 1):
      
        ''' For each index i, take maximum of
        1. abs(max sum subarray that lies in arr[0...i] -
            min sum subarray that lies in arr[i+1...n-1])
        2. abs(min sum subarray that lies in arr[0...i] -
            max sum subarray that lies in arr[i+1...n-1]) '''
        absValue = max(abs(leftMax[i] - rightMin[i + 1]),
                       abs(leftMin[i] - rightMax[i + 1]))
        if (absValue > result):
            result = absValue
      
    return result
      
# Driver Code
a = [-2, -3, 4, -1, -2, 1, 5, -3]
n = len(a)
print(findMaxAbsDiff(a, n))
  
# This code is contributed by Anant Agarwal.

C#

// C# program to find two non-overlapping 


// contiguous sub-arrays such that the
// absolute difference
using System;
class GFG {
      
// Find maximum subarray sum for subarray
// [0..i] using standard Kadane's algorithm.
// This version of Kadane's Algorithm will
// work if all numbers are negative.
static int maxLeftSubArraySum(int []a, int size, 
                                      int []sum)

1568
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

{
    int max_so_far = a[0];
    int curr_max = a[0];
    sum[0] = max_so_far;
   
    for (int i = 1; i < size; i++)
    {
        curr_max = Math.Max(a[i], curr_max + a[i]);
        max_so_far = Math.Max(max_so_far, curr_max);
        sum[i] = max_so_far;
    }
   
    return max_so_far;
}
   
// Find maximum subarray sum for subarray
// [i..n] using Kadane's algorithm. 
// This version of Kadane's Algorithm will
// work if all numbers are negative
static int maxRightSubArraySum(int []a, int n,
                                    int []sum)
{
    int max_so_far = a[n];
    int curr_max = a[n];
    sum[n] = max_so_far;
   
    for (int i = n-1; i >= 0; i--)
    {
        curr_max = Math.Max(a[i], curr_max + a[i]);
        max_so_far = Math.Max(max_so_far, curr_max);
        sum[i] = max_so_far;
    }
   
    return max_so_far;
}
   
// The function finds two non-overlapping
// contiguous sub-arrays such that the 
// absolute difference between the sum 
// of two sub-array is maximum.
static int findMaxAbsDiff(int []arr, int n)
{
    // create and build an array that stores
    // maximum sums of subarrays that lie in
    // arr[0...i]
    int []leftMax=new int[n];
    maxLeftSubArraySum(arr, n, leftMax);
   

1569
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

    // create and build an array that stores


    // maximum sums of subarrays that lie in
    // arr[i+1...n-1]
    int []rightMax=new int[n];
    maxRightSubArraySum(arr, n-1, rightMax);
   
    // Invert array (change sign) to find minumum
    // sum subarrays.
    int []invertArr=new int[n];
    for (int i = 0; i < n; i++)
        invertArr[i] = -arr[i];
   
    // create and build an array that stores
    // minimum sums of subarrays that lie in
    // arr[0...i]
    int []leftMin=new int[n];
    maxLeftSubArraySum(invertArr, n, leftMin);
    for (int i = 0; i < n; i++)
        leftMin[i] = -leftMin[i];
   
    // create and build an array that stores
    // minimum sums of subarrays that lie in
    // arr[i+1...n-1]
    int []rightMin=new int[n];
    maxRightSubArraySum(invertArr, n - 1, rightMin);
    for (int i = 0; i < n; i++)
        rightMin[i] = -rightMin[i];
   
    int result = -2147483648;
    for (int i = 0; i < n - 1; i++)
    {
        /* For each index i, take maximum of
        1. abs(max sum subarray that lies in arr[0...i] -
            min sum subarray that lies in arr[i+1...n-1])
        2. abs(min sum subarray that lies in arr[0...i] -
            max sum subarray that lies in arr[i+1...n-1]) */
        int absValue = Math.Max(Math.Abs(leftMax[i] - rightMin[i + 1]),
                               Math.Abs(leftMin[i] - rightMax[i + 1]));
        if (absValue > result)
            result = absValue;
    }
   
    return result;
}
  
//driver code
public static void Main()
{

1570
Chapter 212. Maximum absolute difference between sum of two contiguous sub-arrays

    int []a= {-2, -3, 4, -1, -2, 1, 5, -3};


    int n = a.Length;
    Console.Write(findMaxAbsDiff(a, n));
}
}
  
//This code is contributed by Anant Agarwal.

Output :

12

Time Complexity is O(n) where n is the number of elements in input array. Auxiliary Space
required is O(n).

Source

https://www.geeksforgeeks.org/maximum-absolute-difference-between-sum-of-two-contiguous-sub-arrays/

1571
Chapter 213

Maximum and Minimum Values


of an Algebraic Expression

Maximum and Minimum Values of an Algebraic Expression - GeeksforGeeks


Given an algebraic expression of the form (x1 + x2 + x3 + . . . + xn ) * (y1 + y2 + . . . +
ym ) and
(n + m) integers. Find the maximum and minimum value of the expression using the given
integers.

Consstraint :
n <= 50
m <= 50
-50 <= x1, x2, .. xn <= 50

Examples :

Input : n = 2, m = 2
arr[] = {1, 2, 3, 4}
Output : Maximum : 25
Minimum : 21
The expression is (x1 + x2) * (y1 + y2) and
the given integers are 1, 2, 3 and 4. Then
maximum value is (1 + 4) * (2 + 3) = 25
whereas minimum value is (4 + 3) * (2 + 1)
= 21.

Input : n = 3, m = 1
arr[] = {1, 2, 3, 4}
Output : Maximum : 24
Minimum : 9

1572
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

A simple solution is to consider all possible combinations of n numbers and remaining m


numbers and calculating their values, from which maximum value and minimum value can
be derived.
Below is an efficient solution.
The idea is based on limited values of n, m, x1, x2, .. y1, y2, .. Let suppose S be the sum
of all the (n + m) numbers in the expression and X be the sum of the n numbers on the
left of expression. Obviously, the sum of the m numbers on the right of expression will be
represented as (S – X). There can be many possible values of X from the given (n + m)
numbers and hence the problem gets reduced to simply iterate through all values of X and
keeping track of the minimum and maximum value of X * (S – X).
Now, the problem is equivalent to finding all possible values of X. Since the given numbers
are in the range of -50 to 50 and the maximum value of (n + m) is 100, X will lie in
between -2500 and 2500 which results into overall 5000 values of X. We will use dynamic
programming approach to solve this problem. Consider a dp[i][j] array which can value
either 1 or 0, where 1 means X can be equal to j by choosing i numbers from the (n + m)
numbers and 0 otherwise. Then for each number k, if dp[i][j] is 1 then dp[i + 1][j + k] is
also 1 where k belongs to given (n + m) numbers. Thus, by iterating through all k, we can
determine whether a value of X is reachable by choosing a total of n numbers
Below is the implementation of the above approach.

C++

// CPP program to find the maximum


// and minimum values of an Algebraic
// expression of given form
#include <bits/stdc++.h>
using namespace std;
  
#define INF 1e9
#define MAX 50
  
int minMaxValues(int arr[], int n, int m)
{
    // Finding sum of array elements
    int sum = 0;
    for (int i = 0; i < (n + m); i++) {
        sum += arr[i];
  
        // shifting the integers by 50
        // so that they become positive
        arr[i] += 50;
    }
  
// dp[i][j] represents true if sum
// j can be reachable by choosing
// i numbers
bool dp[MAX+1][MAX * MAX + 1];

1573
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

  
    // initialize the dp array to 01
    memset(dp, 0, sizeof(dp));
  
    dp[0][0] = 1;
  
    // if dp[i][j] is true, that means
    // it is possible to select i numbers
    // from (n + m) numbers to sum upto j
    for (int i = 0; i < (n + m); i++) {
  
        // k can be at max n because the
        // left expression has n numbers
        for (int k = min(n, i + 1); k >= 1; k--) {
            for (int j = 0; j < MAX * MAX + 1; j++) {
                if (dp[k - 1][j])
                    dp[k][j + arr[i]] = 1;
            }
        }
    }
  
    int max_value = -INF, min_value = INF;
  
    for (int i = 0; i < MAX * MAX + 1; i++) {
  
        // checking if a particular sum
        // can be reachable by choosing
        // n numbers
        if (dp[n][i]) {
  
            // getting the actual sum as
            // we shifted the numbers by
            /// 50 to avoid negative indexing
            // in array
            int temp = i - 50 * n;
            max_value = max(max_value, temp * (sum - temp));
            min_value = min(min_value, temp * (sum - temp));
        }
    }
    cout << "Maximum Value: " << max_value
         << "\n"
         << "Minimum Value: "
         << min_value << endl;
}
  
// Driver Code
int main()
{

1574
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

    int n = 2, m = 2;
    int arr[] = { 1, 2, 3, 4 };
    minMaxValues(arr, n, m);
    return 0;
}

Java

// Java program to find the maximum


// and minimum values of an Algebraic
// expression of given form
import java.io.*;
import java.lang.*;
  
public class GFG {
      
    static double INF = 1e9;
    static int MAX = 50;
  
    static void minMaxValues(int []arr, 
                              int n, int m)
    {
          
        // Finding sum of array elements
        int sum = 0;
        for (int i = 0; i < (n + m); i++)
        {
            sum += arr[i];
      
            // shifting the integers by 50
            // so that they become positive
            arr[i] += 50;
        }
      
        // dp[i][j] represents true if sum
        // j can be reachable by choosing
        // i numbers
        boolean dp[][] = 
             new boolean[MAX+1][MAX * MAX + 1];
      
        dp[0][0] = true;
      
        // if dp[i][j] is true, that means
        // it is possible to select i numbers
        // from (n + m) numbers to sum upto j
        for (int i = 0; i < (n + m); i++) {
      
            // k can be at max n because the

1575
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

            // left expression has n numbers


            for (int k = Math.min(n, i + 1); k >= 1; k--) 
            {
                for (int j = 0; j < MAX * MAX + 1; j++)
                {
                    if (dp[k - 1][j])
                        dp[k][j + arr[i]] = true;
                }
            }
        }
      
        double max_value = -1 * INF, min_value = INF;
      
        for (int i = 0; i < MAX * MAX + 1; i++)
        {
      
            // checking if a particular sum
            // can be reachable by choosing
            // n numbers
            if (dp[n][i]) {
      
                // getting the actual sum as
                // we shifted the numbers by
                /// 50 to avoid negative indexing
                // in array
                int temp = i - 50 * n;
                max_value = Math.max(max_value, temp *
                                        (sum - temp));
                                              
                min_value = Math.min(min_value, temp * 
                                        (sum - temp));
            }
        }
          
        System.out.print("Maximum Value: " + 
                     (int)max_value + "\n" + 
          "Minimum Value: " + (int)min_value + "\n");
    }
  
    // Driver Code
    public static void main(String args[])
    {
        int n = 2, m = 2;
        int []arr = { 1, 2, 3, 4 };
        minMaxValues(arr, n, m);
    }
}
  

1576
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

// This code is contributed by Manish Shaw


// (manishshaw1)

Python3

# Python3 program to find the 


# maximum and minimum values 
# of an Algebraic expression 
# of given form
def minMaxValues(arr, n, m) :     
    # Finding sum of
    # array elements
    sum = 0
    INF = 1000000000
    MAX = 50
    for i in range(0, (n + m)) :
        sum += arr[i]
  
        # shifting the integers by 50
        # so that they become positive
        arr[i] += 50
  
    # dp[i][j] represents true 
    # if sum j can be reachable
    # by choosing i numbers
    dp = [[0 for x in range(MAX * MAX + 1)]
                  for y in range( MAX + 1)]
      
    dp[0][0] = 1
  
    # if dp[i][j] is true, that 
    # means it is possible to 
    # select i numbers from (n + m)
    # numbers to sum upto j
    for i in range(0, (n + m)) : 
          
        # k can be at max n because the
        # left expression has n numbers
        for k in range(min(n, i + 1), 0, -1) :
            for j in range(0, MAX * MAX + 1) :
                if (dp[k - 1][j]) :
                    dp[k][j + arr[i]] = 1
  
    max_value = -1 * INF 
    min_value = INF
  
    for i in range(0, MAX * MAX + 1) :
  

1577
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

        # checking if a particular 


        # sum can be reachable by 
        # choosing n numbers
        if (dp[n][i]) :
  
            # getting the actual sum 
            # as we shifted the numbers 
            # by 50 to avoid negative 
            # indexing in array
            temp = i - 50 * n
            max_value = max(max_value, 
                         temp * (sum - temp))
                                          
            min_value = min(min_value,
                         temp * (sum - temp))
      
    print ("Maximum Value: {}\nMinimum Value: {}"
                 .format(max_value, min_value))
  
# Driver Code
n = 2
m = 2
arr = [ 1, 2, 3, 4 ]
  
minMaxValues(arr, n, m) 
  
# This code is contributed by 
# Manish Shaw(manishshaw1)

C#

// C# program to find the maximum


// and minimum values of an Algebraic
// expression of given form
using System;
using System.Collections.Generic;
  
class GFG {
      
    static double INF = 1e9;
    static int MAX = 50;
  
    static void minMaxValues(int []arr, int n, int m)
    {
          
        // Finding sum of array elements
        int sum = 0;
        for (int i = 0; i < (n + m); i++)

1578
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

        {
            sum += arr[i];
      
            // shifting the integers by 50
            // so that they become positive
            arr[i] += 50;
        }
      
    // dp[i][j] represents true if sum
    // j can be reachable by choosing
    // i numbers
        bool[,] dp = new bool[MAX+1, MAX * MAX + 1];
      
        dp[0,0] = true;
      
        // if dp[i][j] is true, that means
        // it is possible to select i numbers
        // from (n + m) numbers to sum upto j
        for (int i = 0; i < (n + m); i++) {
      
            // k can be at max n because the
            // left expression has n numbers
            for (int k = Math.Min(n, i + 1); k >= 1; k--) 
            {
                for (int j = 0; j < MAX * MAX + 1; j++)
                {
                    if (dp[k - 1,j])
                        dp[k,j + arr[i]] = true;
                }
            }
        }
      
        double max_value = -1 * INF, min_value = INF;
      
        for (int i = 0; i < MAX * MAX + 1; i++)
        {
      
            // checking if a particular sum
            // can be reachable by choosing
            // n numbers
            if (dp[n,i]) {
      
                // getting the actual sum as
                // we shifted the numbers by
                /// 50 to avoid negative indexing
                // in array
                int temp = i - 50 * n;
                max_value = Math.Max(max_value, temp *

1579
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

                                          (sum - temp));
                                            
                min_value = Math.Min(min_value, temp * 
                                          (sum - temp));
            }
        }
          
        Console.WriteLine("Maximum Value: " + max_value
         + "\n" + "Minimum Value: " + min_value + "\n");
    }
  
    // Driver Code
    public static void Main()
    {
        int n = 2, m = 2;
        int []arr = { 1, 2, 3, 4 };
        minMaxValues(arr, n, m);
    }
}
  
// This code is contributed by Manish Shaw
// (manishshaw1)

PHP

<?php
// PHP program to find the 
// maximum and minimum values 
// of an Algebraic expression 
// of given form
function minMaxValues($arr, $n, $m)
{         
    // Finding sum of
    // array elements
    $sum = 0;
    $INF = 1000000000;
    $MAX = 50;
    for ($i = 0; $i < ($n + $m); $i++)
    {
        $sum += $arr[$i];
  
        // shifting the integers by 50
        // so that they become positive
        $arr[$i] += 50;
    }
  
    // dp[i][j] represents true 
    // if sum j can be reachable

1580
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

    // by choosing i numbers


    $dp = array();
      
    // new bool[MAX+1, MAX * MAX + 1];
    for($i = 0; $i < $MAX + 1; $i++)
    {
        for($j = 0; $j < $MAX * $MAX + 1; $j++)
            $dp[$i][$j] = 0; 
    }
      
    $dp[0][0] = 1;
  
    // if dp[i][j] is true, that 
    // means it is possible to 
    // select i numbers from (n + m)
    // numbers to sum upto j
    for ($i = 0; $i < ($n + $m); $i++) 
    {
  
        // k can be at max n because the
        // left expression has n numbers
        for ($k = min($n, $i + 1); 
                      $k >= 1; $k--) 
        {
            for ($j = 0; $j < $MAX * 
                              $MAX + 1; $j++)
            {
                if ($dp[$k - 1][$j])
                    $dp[$k][$j + $arr[$i]] = 1;
            }
        }
    }
  
    $max_value = -1 * $INF; 
    $min_value = $INF;
  
    for ($i = 0; $i < $MAX * $MAX + 1; $i++)
    {
  
        // checking if a particular 
        // sum can be reachable by 
        // choosing n numbers
        if ($dp[$n][$i]) 
        {
  
            // getting the actual sum 
            // as we shifted the numbers 
            // by 50 to avoid negative 

1581
Chapter 213. Maximum and Minimum Values of an Algebraic Expression

            // indexing in array


            $temp = $i - 50 * $n;
            $max_value = max($max_value, $temp *
                                ($sum - $temp));
                                          
            $min_value = min($min_value, $temp * 
                                ($sum - $temp));
        }
    }
      
    echo ("Maximum Value: ". $max_value. "\n". 
          "Minimum Value: ". $min_value. "\n");
}
  
// Driver Code
$n = 2;
$m = 2;
$arr = [ 1, 2, 3, 4 ];
  
minMaxValues($arr, $n, $m); 
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

Output :

Maximum Value: 25
Minimum Value: 21

This approach will have a runtime complexity of O(MAX * MAX * (n+m)2 ).


Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/maximum-minimum-values-algebraic-expression/

1582
Chapter 214

Maximum average sum


partition of an array

Maximum average sum partition of an array - GeeksforGeeks


Given an array, we partition a row of numbers A into at most K adjacent (non-empty)
groups, then the score is the sum of the average of each group. What is the maximum score
than can be scored ?
Examples:

Input : A = { 9, 1, 2, 3, 9 }
K=3
Output : 20
Explanation : We can partition A into [9], [1, 2, 3], [9]. The answer is 9 + (1 +
2 + 3) / 3 + 9 = 20.
We could have also partitioned A into [9, 1], [2], [3, 9]. That partition would
lead to a score of 5 + 2 + 6 = 13, which is worse.
Input : A[] = { 1, 2, 3, 4, 5, 6, 7 }
K=4
Output : 20.5
Explanation : We can partition A into [1, 2, 3, 4], [5], [6], [7]. The answer is 2.5
+ 5 + 6 + 7 = 20.5.

A simple solution is to use recursion. An efficient solution is memorization where we keep


the largest score upto k i.e. for 1, 2, 3… upto k;
Let memo[i][k] be the best score portioning A[i..n-1] into at most K parts. In the first
group, we partition A[i..n-1] into A[i..j-1] and A[j..n-1], then our candidate partition has
score average(i, j) + score(j, k-1)), where average(i, j) = (A[i] + A[i+1] + … + A[j-1]) / (j
– i). We take the highest score of these.
In total, our recursion in the general case is :
memo[n][k] = max(memo[n][k], score(memo, i, A, k-1) + average(i, j))
for all i from n-1 to 1 .

1583
Chapter 214. Maximum average sum partition of an array

// CPP program for maximum average sum partition


#include <bits/stdc++.h>
using namespace std;
  
#define MAX 1000
  
double memo[MAX][MAX];
  
// bottom up approach to calculate score
double score(int n, vector<int>& A, int k)
{
    if (memo[n][k] > 0)
        return memo[n][k];
    double sum = 0;
    for (int i = n - 1; i > 0; i--) {
        sum += A[i];
        memo[n][k] = max(memo[n][k], score(i, A, k - 1) +
                                          sum / (n - i));
    }
    return memo[n][k];
}
  
double largestSumOfAverages(vector<int>& A, int K)
{
    int n = A.size();
    double sum = 0;
    memset(memo, 0.0, sizeof(memo));
    for (int i = 0; i < n; i++) {
        sum += A[i];
  
        // storing averages from starting to each i ; 
        memo[i + 1][1] = sum / (i + 1);
    }
    return score(n, A, K);
}
  
int main()
{
    vector<int> A = { 9, 1, 2, 3, 9 };
    int K = 3; // atmost partioning size
    cout << largestSumOfAverages(A, K) << endl;
    return 0;
}

Output:

20

1584
Chapter 214. Maximum average sum partition of an array

Above problem can now be easily understood as dynamic programming.


Let dp(i, k) be the best score partioning A[i:j] into at most K parts. If the first group we
partition A[i:j] into ends before j, then our candidate partition has score average(i, j) + dp(j,
k-1)). Recursion in the general case is dp(i, k) = max(average(i, N), (average(i, j) + dp(j,
k-1))). We can precompute the prefix sums for fast execution of out code.

// CPP program for maximum average sum partition


#include <bits/stdc++.h>
using namespace std;
  
double largestSumOfAverages(vector<int>& A, int K)
{
    int n = A.size();
  
    // storing prefix sums
    double pre_sum[n+1]; 
    pre_sum[0] = 0;
    for (int i = 0; i < n; i++)
        pre_sum[i + 1] = pre_sum[i] + A[i];
  
    // for each i to n storing averages 
    double dp[n] = {0};
    double sum = 0;
    for (int i = 0; i < n; i++) 
        dp[i] = (pre_sum[n] - pre_sum[i]) / (n - i);
      
    for (int k = 0; k < K - 1; k++) 
        for (int i = 0; i < n; i++) 
            for (int j = i + 1; j < n; j++) 
                dp[i] = max(dp[i], (pre_sum[j] -
                         pre_sum[i]) / (j - i) + dp[j]);
      
    return dp[0];
}
  
// Driver code
int main()
{
    vector<int> A = { 9, 1, 2, 3, 9 };
    int K = 3; // atmost partioning size
    cout << largestSumOfAverages(A, K) << endl;
    return 0;
}

Output:

20

1585
Chapter 214. Maximum average sum partition of an array

Source

https://www.geeksforgeeks.org/maximum-average-sum-partition-array/

1586
Chapter 215

Maximum decimal value path in


a binary matrix

Maximum decimal value path in a binary matrix - GeeksforGeeks


Given binary square matrix [n*n]. Find maximum integer value in a path from top left to
bottom right. We compute integer value using bits of traversed path. We start at index
[0,0] and end at index [n-1][n-1]. from index [i, j], we can move [i, j+1] or [i+1, j].
Examples:

Input : mat[][] = {{1, 1, 0, 1},


{0, 1, 1, 0},
{1, 0, 0, 1},
{1, 0, 1, 1}}
Output : 111
Explanation :
Path : (0,0) -> (0,1) -> (1,1) -> (1,2) ->
(2,2) -> (3,2) ->(4,4)
Decimal value : 1*(2^0) + 1*(2^1) + 1*(2^2) + 1*(2^3) +
0*(2^4) + 1*(2^5) + 1*(2^6) = 111

The above problem can be recursively defined as below:

// p indicates power of 2, initially p = i = j = 0


MaxDecimalValue(mat, i, j, p)

// If i or j is our of boundary
If i >= n || j >= n
return 0

1587
Chapter 215. Maximum decimal value path in a binary matrix

// Compute rest of matrix find maximum decimal value


result max(MaxDecimalValue(mat, i, j+1, p+1),
MaxDecimalValue(mat, i+1, j, p+1))

If mat[i][j] == 1
return power(2, p) + result
Else
return result

Below is the implementation of above recursive algorithm.


C++

    
// C++ program to find maximum decimal value path in
// binary matrix
#include<bits/stdc++.h>
using namespace std;
  
#define N 4
  
// Returns maximum decimal value in binary matrix.
// Here p indicate power of 2
long long int maxDecimalValue(int mat[][N], int i, int j,
                                                   int p)
{
    // Out of matrix boundary
    if (i >= N || j >= N )
        return 0;
  
    int result = max(maxDecimalValue(mat, i, j+1, p+1),
                     maxDecimalValue(mat, i+1, j, p+1));
  
    // If current matrix value is 1 then return result +
    // power(2, p) else result
    if (mat[i][j] == 1)
        return pow(2, p) + result;
    else
        return result;
}
  
//Driver program
int main()
{
    int mat[][4] = {{ 1 ,1 ,0 ,1 },
        { 0 ,1 ,1 ,0 },
        { 1 ,0 ,0 ,1 },

1588
Chapter 215. Maximum decimal value path in a binary matrix

        { 1 ,0 ,1 ,1 },
    };
  
    cout << maxDecimalValue(mat, 0, 0, 0) << endl;
    return 0;
}

Python3

# Python program to find maximum decimal


# value path in binary matrix
N =4
  
# Returns maximum decimal value in binary
# matrix. Here p indicate power of 2
def maxDecimalValue(mat, i, j, p):
  
    # Out of matrix boundary
    if i >= N or j >= N:
        return 0
          
    result = max(
        maxDecimalValue(mat, i, j+1, p+1),
        maxDecimalValue(mat, i+1, j, p+1))
  
    # If current matrix value is 1 then
    # return result + power(2, p) else
    # result
    if mat[i][j] == 1:
        return pow(2, p) + result
    else:
        return result
  
  
# Driver Program
mat = [ [1, 1, 0, 1],
        [0, 1, 1, 0],
        [1, 0, 0, 1],
        [1, 0, 1, 1] ]
  
print(maxDecimalValue(mat, 0, 0, 0))
  
# This code is contributed by Shrikant13.

PHP

<?php

1589
Chapter 215. Maximum decimal value path in a binary matrix

// PHP program to find maximum 


// decimal value path in binary
// matrix
  
// Returns maximum decimal value
// in binary matrix. Here p 
// indicate power of 2
function maxDecimalValue($mat, $i, 
                          $j, $p)
{
    $N=4;
      
    // Out of matrix boundary
    if ($i >= $N || $j >= $N )
        return 0;
  
    $result = max(maxDecimalValue($mat, $i, 
                            $j + 1, $p + 1),
                  maxDecimalValue($mat, $i + 1,
                                $j, $p + 1));
  
    // If current matrix value 
    // is 1 then return result +
    // power(2, p) else result
    if ($mat[$i][$j] == 1)
        return pow(2, $p) + $result;
    else
        return $result;
}
  
    // Driver Code
    $mat = array(array(1 ,1 ,0 ,1),
                 array(0 ,1 ,1 ,0),
                 array(1 ,0 ,0 ,1),
                 array(1 ,0 ,1 ,1));
  
    echo maxDecimalValue($mat, 0, 0, 0) ;
      
// This code is contributed by nitin mittal. 
?>

Output:

111

The time complexity of above recursive solution is exponential.

1590
Chapter 215. Maximum decimal value path in a binary matrix

Here matrix [3][3]


(2 2)
/ \
(1 2) (2 1)
/ \ / \
(0 2) (1 1) (1 1) (2 1)
/ \ / \ / \ / \
. . . . . . . .
. . . . . . . . and so no

If we see recursion tree of above recursive solution, we can observe overlapping sub-problems.
Since the problem has overlapping subproblems, we can solve it efficiently using Dynamic
Programming. Below is Dynamic Programming based solution.
Below is c++ implementation of above problem using Dynamic Programming

// C++ program to find Maximum decimal value Path in


// Binary matrix
#include<bits/stdc++.h>
using namespace std;
#define N 4
  
// Returns maximum decimal value in binary matrix.
// Here p indicate power of 2
long long int MaximumDecimalValue(int mat[][N], int n)
{
    int dp[n][n];
    memset(dp, 0, sizeof(dp));
    if (mat[0][0] == 1)
        dp[0][0] = 1 ; // 1*(2^0)
  
    // Compute binary stream of first row of matrix
    // and store result in dp[0][i]
    for (int i=1; i<n; i++)
    {
        // indicate 1*(2^i) + result of previous
        if (mat[0][i] == 1)
            dp[0][i] = dp[0][i-1] + pow(2, i);
  
        // indicate 0*(2^i) + result of previous
        else
            dp[0][i] = dp[0][i-1];
    }
  
    // Compute binary stream of first column of matrix
    // and store result in dp[i][0]
    for (int i = 1 ; i <n ; i++ )

1591
Chapter 215. Maximum decimal value path in a binary matrix

    {
        // indicate 1*(2^i) + result of previous
        if (mat[i][0] == 1)
            dp[i][0] = dp[i-1][0] + pow(2, i);
  
        // indicate 0*(2^i) + result of previous
        else
            dp[i][0] = dp[i-1][0];
    }
  
    // Traversal rest Binary matrix and Compute maximum
    // decimal value
    for (int i=1 ; i < n ; i++ )
    {
        for (int j=1 ; j < n ; j++ )
        {
            // Here (i+j) indicate the current power of
            // 2 in path that is 2^(i+j)
            if (mat[i][j] == 1)
                dp[i][j] = max(dp[i][j-1], dp[i-1][j]) + 
                                             pow(2, i+j);
            else
                dp[i][j] = max(dp[i][j-1], dp[i-1][j]);
        }
     }
  
    // Return maximum decimal value in binary matrix
    return dp[n-1][n-1];
}
  
// Driver program
int main()
{
    int mat[][4] = {{ 1 ,1 ,0 ,1 },
        { 0 ,1 ,1 ,0 },
        { 1 ,0 ,0 ,1 },
        { 1 ,0 ,1 ,1 },
    };
    cout << MaximumDecimalValue(mat, 4) << endl;
    return 0;
}

Output:

111

Time Complexity : O(n2 )

1592
Chapter 215. Maximum decimal value path in a binary matrix

Auxiliary space : O(n2 )


Improved By : shrikanth13, nitin mittal

Source

https://www.geeksforgeeks.org/maximum-decimal-value-path-in-a-binary-matrix/

1593
Chapter 216

Maximum difference of zeros


and ones in binary string

Maximum difference of zeros and ones in binary string - GeeksforGeeks


Given a binary string of 0s and 1s. The task is to find the length of substring which is
having maximum difference of number of 0s and number of 1s (number of 0s – number of
1s). In case of all 1s print -1.
Examples:

Input : S = "11000010001"
Output : 6
From index 2 to index 9, there are 7
0s and 1 1s, so number of 0s - number
of 1s is 6.

Input : S = "1111"
Output : -1

The idea is to use Dynamic Programming to solve the problem.


Before that we will convert given binary string into integer array of value 1s and -1s, say
arr[]. That can be easily done by traversing the given binary string and if ith index contain
‘0’ make -1 in corresponding position in array. Similarly, if ith index contain ‘1’, make 1 in
the array.
Now, at each index i we need to make decision whether to take it or skip it. So, declare a
2D array of size n x 2, where n is the length of the given binary string, say dp[n][2].

dp[i][0] define the maximum value upto


index i, when we skip the i-th
index element.

1594
Chapter 216. Maximum difference of zeros and ones in binary string

dp[i][1] define the maximum value upto


index i after taking the i-th
index element.

Therefore, we can derive dp[i][] as:


dp[i][0] = max(dp[i+1][0], dp[i+1][1] + arr[i])
dp[i][1] = max(dp[i+1][1] + arr[i], 0)

For all ones we check this case explicitly.


C++

// CPP Program to find the length of


// substring with maximum difference of
// zeroes and ones in binary string.
#include <bits/stdc++.h>
#define MAX 100
using namespace std;
  
// Return true if there all 1s
bool allones(string s, int n)
{
    // Checking each index is 0 or not.
    int co = 0;
    for (int i = 0; i < s.size(); i++)
        co += (s[i] == '1');
  
    return (co == n);
}
  
// Find the length of substring with maximum
// difference of zeroes and ones in binary 
// string
int findlength(int arr[], string s, int n, 
              int ind, int st, int dp[][3])
{
    // If string is over.
    if (ind >= n)
        return 0;
  
    // If the state is already calculated.
    if (dp[ind][st] != -1)
        return dp[ind][st];
  
    if (st == 0)
        return dp[ind][st] = max(arr[ind] + 
          findlength(arr, s, n, ind + 1, 1, dp),
          findlength(arr, s, n, ind + 1, 0, dp));

1595
Chapter 216. Maximum difference of zeros and ones in binary string

  
    else
        return dp[ind][st] = max(arr[ind] +
       findlength(arr, s, n, ind + 1, 1, dp), 0);
}
  
// Returns length of substring which is 
// having maximum difference of number
// of 0s and number of 1s 
int maxLen(string s, int n)
{
    // If all 1s return -1.
    if (allones(s, n)) 
        return -1;    
  
    // Else find the length.
    int arr[MAX] = { 0 };
    for (int i = 0; i < n; i++) 
        arr[i] = (s[i] == '0' ? 1 : -1);    
  
    int dp[MAX][3];
    memset(dp, -1, sizeof dp);
    return findlength(arr, s, n, 0, 0, dp);
}
  
// Driven Program
int main()
{
    string s = "11000010001";
    int n = 11;
    cout << maxLen(s, n) << endl;
    return 0;
}

Java

// Java Program to find the length of


// substring with maximum difference of
// zeroes and ones in binary string.
import java.util.Arrays;
  
class GFG
{
static final int MAX=100;
  
// Return true if there all 1s
static boolean allones(String s, int n)
{

1596
Chapter 216. Maximum difference of zeros and ones in binary string

    // Checking each index is 0 or not.


    int co = 0;
    for (int i = 0; i < s.length(); i++)
        if(s.charAt(i) == '1')
            co +=1;     
  
    return (co == n);
}
  
// Find the length of substring with maximum
// difference of zeroes and ones in binary 
// string
static int findlength(int arr[], String s, int n, 
                     int ind, int st, int dp[][])
{
    // If string is over.
    if (ind >= n)
        return 0;
  
    // If the state is already calculated.
    if (dp[ind][st] != -1)
        return dp[ind][st];
  
    if (st == 0)
        return dp[ind][st] = Math.max(arr[ind] + 
                             findlength(arr, s, n, 
                                   ind + 1, 1, dp),
                             findlength(arr, s, n, 
                                   ind + 1, 0, dp));
  
    else
        return dp[ind][st] = Math.max(arr[ind] +
                             findlength(arr, s, n, 
                               ind + 1, 1, dp), 0);
}
  
// Returns length of substring which is 
// having maximum difference of number
// of 0s and number of 1s 
static int maxLen(String s, int n)
{
    // If all 1s return -1.
    if (allones(s, n)) 
        return -1; 
  
    // Else find the length.
    int arr[] = new int[MAX];
    for (int i = 0; i < n; i++) 

1597
Chapter 216. Maximum difference of zeros and ones in binary string

        arr[i] = (s.charAt(i) == '0' ? 1 : -1); 


  
    int dp[][] = new int[MAX][3];
    for (int[] row : dp)
            Arrays.fill(row, -1);
    return findlength(arr, s, n, 0, 0, dp);
}
  
// Driver code 
public static void main (String[] args)
{
    String s = "11000010001";
    int n = 11;
    System.out.println(maxLen(s, n));
}
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python Program to find the length of


# substring with maximum difference of
# zeroes and ones in binary string.
MAX = 100
  
# Return true if there all 1s
def allones(s, n):
      
    # Checking each index
    # is 0 or not.
    co = 0
      
    for i in s:
        co += 1 if i == '1' else 0
  
    return co == n
  
# Find the length of substring with 
# maximum difference of zeroes and 
# ones in binary string
def findlength(arr, s, n, ind, st, dp):
      
    # If string is over
    if ind >= n:
        return 0
  
    # If the state is already calculated.

1598
Chapter 216. Maximum difference of zeros and ones in binary string

    if dp[ind][st] != -1:


        return dp[ind][st]
  
    if not st:
        dp[ind][st] = max(arr[ind] + 
           findlength(arr, s, n, ind + 1, 1, dp), 
            (findlength(arr, s, n, ind + 1, 0, dp)))
    else:
        dp[ind][st] = max(arr[ind] +
         findlength(arr, s, n, ind + 1, 1, dp), 0)
           
    return dp[ind][st]
  
# Returns length of substring which is 
# having maximum difference of number
# of 0s and number of 1s 
def maxLen(s, n):
      
    # If all 1s return -1.
    if allones(s, n):
        return -1 
  
    # Else find the length.
    arr = [0] * MAX
    for i in range(n):
        arr[i] = 1 if s[i] == '0' else -1
  
    dp = [[-1] * 3 for _ in range(MAX)]
    return findlength(arr, s, n, 0, 0, dp)
  
# Driven Program
s = "11000010001"
n = 11
print(maxLen(s, n))
  
# This code is contributed by Ansu Kumari.

Output :

Maximum difference of zeros and ones in binary string | Set 2 (O(n) time)

Source

https://www.geeksforgeeks.org/maximum-difference-zeros-ones-binary-string/

1599
Chapter 217

Maximum difference of zeros


and ones in binary string | Set 2
(O(n) time)

Maximum difference of zeros and ones in binary string | Set 2 (O(n) time) - GeeksforGeeks
Given a binary string of 0s and 1s. The task is to find the length of substring which is
having a maximum difference of number of 0s and number of 1s (number of 0s – number of
1s). In case of all 1s print -1.
Examples:

Input : S = "11000010001"
Output : 6
From index 2 to index 9, there are 7
0s and 1 1s, so number of 0s - number
of 1s is 6.

Input : S = "1111"
Output : -1

We have discussed Dynamic Programing approach in below post :


Maximum difference of zeros and ones in binary string | Set 1.
In the post we seen an efficient method that work in O(n) time and in O(1) extra space.
Idea behind that if we convert all zeros into 1 and all ones into -1.now our problem reduces
to find out the maximum sum sub_array Using Kadane’s Algorithm.

Input : S = "11000010001"

1600
Chapter 217. Maximum difference of zeros and ones in binary string | Set 2 (O(n) time)

After converting '0' into 1 and


'1' into -1 our S Look Like
S = -1 -1 1 1 1 1 -1 1 1 1 -1
Now we have to find out Maximum Sum sub_array
that is : 6 is that case

Output : 6

Below is the implementation of above idea.

C++

// CPP Program to find the length of


// substring with maximum difference of
// zeros and ones in binary string.
#include <iostream>
using namespace std;
  
// Returns the length of substring with
// maximum difference of zeroes and ones 
// in binary string
int findLength(string str, int n)
{
    int current_sum = 0;
    int max_sum = 0;
  
    // traverse a binary string from left 
    // to right
    for (int i = 0; i < n; i++) {
  
        // add current value to the current_sum
        // according to the Character
        // if it's '0' add 1 else -1
        current_sum += (str[i] == '0' ? 1 : -1);
  
        if (current_sum < 0)
            current_sum = 0;
  
        // update maximum sum
        max_sum = max(current_sum, max_sum);
    }
  
    // return -1 if string does not contain
    // any zero that means all ones 
    // otherwise max_sum
    return max_sum == 0 ? -1 : max_sum;
}

1601
Chapter 217. Maximum difference of zeros and ones in binary string | Set 2 (O(n) time)

  
// Driven Program
int main()
{
    string s = "11000010001";
    int n = 11;
    cout << findLength(s, n) << endl;
    return 0;
}

Java

// Java Program to find the length of


// substring with maximum difference of
// zeroes and ones in binary string.
import java.util.*;
import java.lang.*;
import java.io.*;
  
class GFG {
  
    // Find the length of substring with maximum
    // difference of zeros and ones in binary
    // string
    public static int findLength(String str, int n)
    {
  
        int current_sum = 0;
        int max_sum = 0;
  
        // traverse a binary string from left to right
        for (int i = 0; i < n; i++) {
  
            // add current value to the current_sum
            // according to the Character
            // if it's '0' add 1 else -1
            current_sum += (str.charAt(i) == '0' ? 1 : -1);
  
            if (current_sum < 0)
                current_sum = 0;
  
            // update maxium sum
            max_sum = Math.max(current_sum, max_sum);
        }
        // return -1 if string does not contain any zero
        // that means string contains all ones otherwise max_sum
        return max_sum == 0 ? -1 : max_sum;
    }

1602
Chapter 217. Maximum difference of zeros and ones in binary string | Set 2 (O(n) time)

  
    public static void main(String[] args)
    {
        String str = "11000010001";
        int n = str.length();
  
        System.out.println(findLength(str, n));
    }
}

Python3

# Python Program to find the length of


# substring with maximum difference of
# zeros and ones in binary string.
  
# Returns the length of substring with
# maximum difference of zeroes and ones 
# in binary string
def findLength(string, n):
    current_sum = 0
    max_sum = 0
  
    # traverse a binary string from left 
    # to right
    for i in range(n):
  
        # add current value to the current_sum
        # according to the Character
        # if it's '0' add 1 else -1
        current_sum += (1 if string[i] == '0' else -1)
  
        if current_sum < 0:
            current_sum = 0
  
        # update maximum sum
        max_sum = max(current_sum, max_sum)
  
    # return -1 if string does not contain
    # any zero that means all ones 
    # otherwise max_sum
    return max_sum if max_sum else 0
  
# Driven Program
s = "11000010001"
n = 11
print(findLength(s, n))
  

1603
Chapter 217. Maximum difference of zeros and ones in binary string | Set 2 (O(n) time)

# This code is contributed by Ansu Kumari.

PHP

<?php
// PHP Program to find the length of
// substring with maximum difference of
// zeros and ones in binary string.
  
// Returns the length of substring with
// maximum difference of zeroes and ones 
// in binary string
function findLength($str, $n)
{
    $current_sum = 0;
    $max_sum = 0;
  
    // traverse a binary string
    // from left to right
    for ($i = 0; $i < $n; $i++) 
    {
  
        // add current value to the current_sum
        // according to the Character
        // if it's '0' add 1 else -1
        $current_sum += ($str[$i] == '0' ? 1 : -1);
  
        if ($current_sum < 0)
            $current_sum = 0;
  
        // update maximum sum
        $max_sum = max($current_sum, $max_sum);
    }
  
    // return -1 if string does not contain
    // any zero that means all ones 
    // otherwise max_sum
    return $max_sum == 0 ? -1 : $max_sum;
}
  
    // Driver Code
    $s = "11000010001";
    $n = 11;
    echo findLength($s, $n),"\n";
      
// This code is contributed by aj_36
?>

1604
Chapter 217. Maximum difference of zeros and ones in binary string | Set 2 (O(n) time)

Output:

Time Complexity : O(n)


Space complexity : O(1)
Improved By : jit_t

Source

https://www.geeksforgeeks.org/maximum-difference-zeros-ones-binary-string-set-2-time/

1605
Chapter 218

Maximum games played by


winner

Maximum games played by winner - GeeksforGeeks


There are N players which are playing a tournament. We need to find the maximum number
of games the winner can play. In this tournament, two players are allowed to play against
each other only if the difference between games played by them is not more than one.
Examples:

Input : N = 3
Output : 2
Maximum games winner can play = 2
Assume that player are P1, P2 and P3
First, two players will play let (P1, P2)
Now winner will play against P3,
making total games played by winner = 2

Input : N = 4
Output : 2
Maximum games winner can play = 2
Assume that player are P1, P2, P3 and P4
First two pairs will play lets (P1, P2) and
(P3, P4). Now winner of these two games will
play against each other, making total games
played by winner = 2

We can solve this problem by first computing minimum number of players required such
that the winner will play x games. Once this is computed actual problem is just inverse of
this. Now assume that dp[i] denotes minimum number of players required so that winner
plays i games. We can write a recursive relation among dp values as,

1606
Chapter 218. Maximum games played by winner

dp[i + 1] = dp[i] + dp[i – 1] because if runner up has played (i – 1) games and winner has
played i games and all players against which they have played the match are disjoint, total
games played by winner will be addition of those two sets of players.
Above recursive relation can be written as dp[i] = dp[i – 1] + dp[i – 2]
Which is same as the Fibonacci series relation, so our final answer will be the index of the
maximal Fibonacci number which is less than or equal to given number of players in the
input.
C++

// C/C++ program to find maximum number of 


// games played by winner
#include <bits/stdc++.h>
using namespace std;
  
// method returns maximum games a winner needs
// to play in N-player tournament
int maxGameByWinner(int N)
{
    int dp[N];
  
    // for 0 games, 1 player is needed
    // for 1 game, 2 players are required
    dp[0] = 1;    
    dp[1] = 2;
      
    // loop until i-th Fibonacci number is  
    // less than or equal to N
    int i = 2;
    do {
        dp[i] = dp[i - 1] + dp[i - 2];
    } while (dp[i++] <= N);
  
    // result is (i - 2) because i will be 
    // incremented one extra in while loop
    // and we want the last value which is 
    // smaller than N, so one more decrement
    return (i - 2);
}
  
// Driver code to test above methods
int main()
{
    int N = 10;
    cout << maxGameByWinner(N) << endl;
    return 0;
}

Java

1607
Chapter 218. Maximum games played by winner

// Java program to find maximum number of 


// games played by winner
class Max_game_winner {
  
    // method returns maximum games a winner needs
    // to play in N-player tournament
    static int maxGameByWinner(int N)
    {
        int[] dp = new int[N];
       
        // for 0 games, 1 player is needed
        // for 1 game, 2 players are required
        dp[0] = 1;    
        dp[1] = 2;
           
        // loop until i-th Fibonacci number is  
        // less than or equal to N
        int i = 2;
        do {
            dp[i] = dp[i - 1] + dp[i - 2];
        } while (dp[i++] <= N);
       
        // result is (i - 2) because i will be 
        // incremented one extra in while loop
        // and we want the last value which is 
        // smaller than N, so one more decrement
        return (i - 2);
    }
       
    // Driver code to test above methods
    public static void main(String args[])
    {
        int N = 10;
        System.out.println(maxGameByWinner(N));
    }
}
//This code is contributed by Sumit Ghosh

Output:

C#

// C# program to find maximum number


// of games played by winner

1608
Chapter 218. Maximum games played by winner

using System;
  
class GFG {
      
    // method returns maximum games a 
    // winner needs to play in N-player
    // tournament
    static int maxGameByWinner(int N)
    {
        int[] dp = new int[N];
      
        // for 0 games, 1 player is needed
        // for 1 game, 2 players are required
        dp[0] = 1; 
        dp[1] = 2;
          
        // loop until i-th Fibonacci number 
        // is less than or equal to N
        int i = 2;
          
        do {
            dp[i] = dp[i - 1] + dp[i - 2];
        } while (dp[i++] <= N);
      
        // result is (i - 2) because i will be 
        // incremented one extra in while loop
        // and we want the last value which is 
        // smaller than N, so one more decrement
        return (i - 2);
    }
      
    // Driver code
    public static void Main()
    {
        int N = 10;
        Console.Write(maxGameByWinner(N));
    }
}
  
// This code is contributed by Nitin Mittal.

PHP

<?php
// PHP program to find maximum number
// of games played by winner
  
// Method returns maximum games

1609
Chapter 218. Maximum games played by winner

// a winner needs to play in 


// N-player tournament
function maxGameByWinner($N)
{
    $dp[$N]=0;
  
    // for 0 games, 1 player is needed
    // for 1 game, 2 players are required
    $dp[0] = 1; 
    $dp[1] = 2;
      
    // loop until i-th Fibonacci number is 
    // less than or equal to N
    $i = 2;
    do 
    {
        $dp[$i] = $dp[$i - 1] + $dp[$i - 2];
    } while ($dp[$i++] <= $N);
  
    // result is (i - 2) because i will be 
    // incremented one extra in while loop
    // and we want the last value which is 
    // smaller than N, so one more decrement
    return ($i - 2);
}
  
    // Driver Code
    $N = 10;
    echo maxGameByWinner($N);
  
// This code is contributed by nitin mittal
?>

Output :

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/maximum-games-played-winner/

1610
Chapter 219

Maximum length of segments of


0’s and 1’s

Maximum length of segments of 0’s and 1’s - GeeksforGeeks


Given a string comprising of ones and zeros. The task is to find the maximum length of the
segments of string such that a number of 1 in each segment is greater than 0.
Note: Each segment taken should be distinct. Index starts from 0.
Examples:

Input: str = “100110001010001”


Output: 9
First segment from index 0 to 4 (10011), total length = 5
Second segment from index 8 to 10 (101), total length = 3
Third segment from index 14 till 14 (1), total length = 1,
Hence asnwer is 5 + 3 + 1 = 9

Input: str = “0010111101100000”


Output: 13
The maximum length can be formed by taking segment
from index 0 till index 12 (0010111101100),
i.e. of total length = 13

Approach:

1. If start == n, limiting condition arises, return 0.


2. Run a loop from start till n, computing for each subarray till n.
3. If character is 1 then increment the count of 1 else increment the count of 0.
4. If count of 1 is greater than 0, recursively call the function for index (k+1) i.e. next
index and add the remaining length i.e. k-start+1.

1611
Chapter 219. Maximum length of segments of 0’s and 1’s

5. Else only recursively call the function for next index k+1.
6. Return dp[start].

Below is the implementation of above approach:

// C++ implementation of above approach


#include <bits/stdc++.h>
using namespace std;
  
// Recursive Function to find total length of the array
// Where 1 is greater than zero
int find(int start, string adj, int n, int dp[])
{
    // If reaches till end
    if (start == n)
        return 0;
  
    // If dp is saved
    if (dp[start] != -1)
        return dp[start];
  
    dp[start] = 0;
    int one = 0, zero = 0, k;
  
    // Finding for each length
    for (k = start; k < n; k++) {
  
        // If the character scanned is 1
        if (adj[k] == '1')
            one++;
        else
            zero++;
  
        // If one is greater than zero, add total
        // length scanned till now
        if (one > zero)
            dp[start] = max(dp[start], find(k + 1, adj, n, dp)
                                           + k - start + 1);
  
        // Continue with next length
        else
            dp[start] = max(dp[start], find(k + 1, adj, n, dp));
    }
  
    // Return the value for start index
    return dp[start];
}
  

1612
Chapter 219. Maximum length of segments of 0’s and 1’s

// Driver Code
int main()
{
    string adj = "100110001010001";
  
    // Size of string
    int n = adj.size();
    int dp[n + 1];
    memset(dp, -1, sizeof(dp));
    // Calling the function to find the value of function
  
    cout << find(0, adj, n, dp) << endl;
  
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/maximum-length-of-segments-of-0s-and-1s/

1613
Chapter 220

Maximum length subsequence


with difference between
adjacent elements as either 0 or
1

Maximum length subsequence with difference between adjacent elements as either 0 or 1 -


GeeksforGeeks
Given an array of n integers. The problem is to find maximum length of the subsequence
with difference between adjacent elements as either 0 or 1.
Examples:

Input : arr[] = {2, 5, 6, 3, 7, 6, 5, 8}


Output : 5
The subsequence is {5, 6, 7, 6, 5}.

Input : arr[] = {-2, -1, 5, -1, 4, 0, 3}


Output : 4
The subsequence is {-2, -1, -1, 0}.

Source: Expedia Interview Experience | Set 12


The solution to this problem closely resembles the Longest Increasing Subsequence problem.
The only difference is that here we have to check whether the absolute difference between
the adjacent elements of the subsequence is either 0 or 1.
C++

// C++ implementation to find maximum length

1614
Chapter 220. Maximum length subsequence with difference between adjacent elements as
either 0 or 1

// subsequence with difference between adjacent 


// elements as either 0 or 1
#include <bits/stdc++.h>
using namespace std;
  
// function to find maximum length subsequence 
// with difference between adjacent elements as
// either 0 or 1
int maxLenSub(int arr[], int n)
{
    int mls[n], max = 0;
      
    // Initialize mls[] values for all indexes
    for (int i=0; i<n; i++)
        mls[i] = 1;
      
    // Compute optimized maximum length subsequence 
    // values in bottom up manner
    for (int i=1; i<n; i++)
        for (int j=0; j<i; j++)
            if (abs(arr[i] - arr[j]) <= 1 &&
                    mls[i] < mls[j] + 1)
                mls[i] = mls[j] + 1;
      
    // Store maximum of all 'mls' values in 'max'    
    for (int i=0; i<n; i++)
        if (max < mls[i])
            max = mls[i];
      
    // required maximum length subsequence
    return max;        
}
  
// Driver program to test above
int main()
{
    int arr[] = {2, 5, 6, 3, 7, 6, 5, 8};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Maximum length subsequence = "
         << maxLenSub(arr, n);
    return 0;

Java

// JAVA Code for Maximum length subsequence 


// with difference between adjacent elements
// as either 0 or 1

1615
Chapter 220. Maximum length subsequence with difference between adjacent elements as
either 0 or 1

import java.util.*;
  
class GFG {
      
    // function to find maximum length subsequence 
    // with difference between adjacent elements as
    // either 0 or 1
     public static int maxLenSub(int arr[], int n)
    {
        int mls[] = new int[n], max = 0;
           
        // Initialize mls[] values for all indexes
        for (int i = 0; i < n; i++)
            mls[i] = 1;
           
        // Compute optimized maximum length 
        // subsequence values in bottom up manner
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (Math.abs(arr[i] - arr[j]) <= 1 
                      && mls[i] < mls[j] + 1)
                    mls[i] = mls[j] + 1;
           
        // Store maximum of all 'mls' values in 'max'    
        for (int i = 0; i < n; i++)
            if (max < mls[i])
                max = mls[i];
           
        // required maximum length subsequence
        return max;        
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int arr[] = {2, 5, 6, 3, 7, 6, 5, 8};
        int n = arr.length;
        System.out.println("Maximum length subsequence = "+
                               maxLenSub(arr, n));
            
    }
}
    
// This code is contributed by Arnav Kr. Mandal.

Python3

# Python implementation to find maximum length

1616
Chapter 220. Maximum length subsequence with difference between adjacent elements as
either 0 or 1

# subsequence with difference between adjacent 


# elements as either 0 or 1
  
# function to find maximum length subsequence 
# with difference between adjacent elements as
# either 0 or 1
def maxLenSub( arr, n):
    mls=[]
    max = 0
      
    #Initialize mls[] values for all indexes
    for i in range(n):
        mls.append(1)
      
    #Compute optimized maximum length subsequence
    # values in bottom up manner
    for i in range(n):
        for j in range(i):
            if (abs(arr[i] - arr[j]) <= 1 and mls[i] < mls[j] + 1):
                mls[i] = mls[j] + 1
                  
    # Store maximum of all 'mls' values in 'max'
    for i in range(n):
        if (max < mls[i]):
            max = mls[i]
      
    #required maximum length subsequence
    return max
      
#Driver program to test above
arr = [2, 5, 6, 3, 7, 6, 5, 8]
n = len(arr)
print("Maximum length subsequence = ",maxLenSub(arr, n))
  
#This code is contributed by "Abhishek Sharma 44"

C#

// C# Code for Maximum length subsequence


// with difference between adjacent elements
// as either 0 or 1
using System;
  
class GFG {
      
    // function to find maximum length subsequence
    // with difference between adjacent elements as
    // either 0 or 1

1617
Chapter 220. Maximum length subsequence with difference between adjacent elements as
either 0 or 1

    public static int maxLenSub(int[] arr, int n)


    {
        int[] mls = new int[n];
        int max = 0;
  
        // Initialize mls[] values for all indexes
        for (int i = 0; i < n; i++)
            mls[i] = 1;
  
        // Compute optimized maximum length
        // subsequence values in bottom up manner
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (Math.Abs(arr[i] - arr[j]) <= 1
                    && mls[i] < mls[j] + 1)
                    mls[i] = mls[j] + 1;
  
        // Store maximum of all 'mls' values in 'max'
        for (int i = 0; i < n; i++)
            if (max < mls[i])
                max = mls[i];
  
        // required maximum length subsequence
        return max;
    }
  
    /* Driver program to test above function */
    public static void Main()
    {
        int[] arr = { 2, 5, 6, 3, 7, 6, 5, 8 };
        int n = arr.Length;
        Console.Write("Maximum length subsequence = " + 
                                    maxLenSub(arr, n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP implementation to find maximum length
// subsequence with difference between adjacent 
// elements as either 0 or 1
  
// function to find maximum length subsequence 
// with difference between adjacent elements as
// either 0 or 1

1618
Chapter 220. Maximum length subsequence with difference between adjacent elements as
either 0 or 1

function maxLenSub($arr, $n)


{
    $mls = array(); $max = 0;
      
    // Initialize mls[] values
    // for all indexes
    for($i = 0; $i < $n; $i++)
        $mls[$i] = 1;
      
    // Compute optimized maximum
    // length subsequence 
    // values in bottom up manner
    for ($i = 1; $i < $n; $i++)
        for ( $j = 0; $j < $i; $j++)
            if (abs($arr[$i] - $arr[$j]) <= 1 and
                         $mls[$i] < $mls[$j] + 1)
                $mls[$i] = $mls[$j] + 1;
      
    // Store maximum of all
    // 'mls' values in 'max' 
    for($i = 0; $i < $n; $i++)
        if ($max < $mls[$i])
            $max = $mls[$i];
      
    // required maximum 
    // length subsequence
    return $max;     
}
  
    // Driver Code
    $arr = array(2, 5, 6, 3, 7, 6, 5, 8);
    $n = count($arr);
    echo "Maximum length subsequence = "
        , maxLenSub($arr, $n);
          
// This code is contributed by anuj_67.
?>

Output:

Maximum length subsequence = 5

Time Complexity: O(n2 )


Auxiliary Space: O(n)
Maximum length subsequence with difference between adjacent elements as either 0 or 1 |
Set 2
Improved By : vt_m

1619
Chapter 220. Maximum length subsequence with difference between adjacent elements as
either 0 or 1

Source

https://www.geeksforgeeks.org/maximum-length-subsequence-difference-adjacent-elements-either-0-1/

1620
Chapter 221

Maximum number of segments


of lengths a, b and c

Maximum number of segments of lengths a, b and c - GeeksforGeeks


Given a positive integer N, find the maximum number of segments of lengths a, b and c
that can be formed from N .
Examples :

Input : N = 7, a = 5, b, = 2, c = 5
Output : 2
N can be divided into 2 segments of lengths
2 and 5. For the second example,

Input : N = 17, a = 2, b = 1, c = 3
Output : 17
N can be divided into 17 segments of 1 or 8
segments of 2 and 1 segment of 1. But 17 segments
of 1 is greater than 9 segments of 2 and 1.

Approach : The approach used is Dynamic Programming. The base dp0 will be 0 as
initially it has no segments. After that, iterate from 1 to n, and for each of the 3 states i.e,
dpi+a , dpi+b and dpi+c , store the maximum value obtained by either using or not using the
a, b or c segment.
The 3 states to deal with are :

dpi+a =max(dpi +1, dpi+a );


dpi+b =max(dpi +1, dpi+b );
dpi+c =max(dpi +1, dpi+c );

1621
Chapter 221. Maximum number of segments of lengths a, b and c

Below is the implementation of above idea :

C++

// C++ implementation to divide N into 


// maximum number of segments 
// of length a, b and c
#include <bits/stdc++.h>
using namespace std;
  
// function to find the maximum
// number of segments
int maximumSegments(int n, int a, 
                    int b, int c)
{
    // stores the maximum number of 
    // segments each index can have
    int dp[n + 1];
      
    // initialize with -1
    memset(dp, -1, sizeof(dp));
  
    // 0th index will have 0 segments
    // base case
    dp[0] = 0; 
  
    // traverse for all possible 
    // segments till n
    for (int i = 0; i < n; i++) 
    {
        if (dp[i] != -1) {
              
            // conditions
            dp[i + a] = max(dp[i] + 1, 
                            dp[i + a]);
            dp[i + b] = max(dp[i] + 1, 
                            dp[i + b]);
            dp[i + c] = max(dp[i] + 1, 
                            dp[i + c]);
        }
    }
    return dp[n];
}
  
// Driver code
int main()
{
    int n = 7, a = 5, b = 2, c = 5;

1622
Chapter 221. Maximum number of segments of lengths a, b and c

    cout << maximumSegments(n, a, b, c); 


    return 0;
}

Java

// Java implementation to divide N into


// maximum number of segments
// of length a, b and c
import java.util.*;
  
class GFG 
{
      
    // function to find the maximum
    // number of segments
    static int maximumSegments(int n, int a, 
                               int b, int c)
    {
        // stores the maximum number of
        // segments each index can have
        int dp[] = new int[n + 10];
  
        // initialize with -1
        Arrays.fill(dp, -1);
  
        // 0th index will have 0 segments
        // base case
        dp[0] = 0; 
  
        // traverse for all possible 
        // segments till n
        for (int i = 0; i < n; i++) 
        {
            if (dp[i] != -1) 
            {
  
                // conditions
                dp[i + a] = Math.max(dp[i] + 1, 
                                     dp[i + a]);
                dp[i + b] = Math.max(dp[i] + 1,     
                                     dp[i + b]);
                dp[i + c] = Math.max(dp[i] + 1, 
                                     dp[i + c]);
            }
        }
        return dp[n];
    }

1623
Chapter 221. Maximum number of segments of lengths a, b and c

  
    // Driver code
    public static void main(String arg[])
    {
        int n = 7, a = 5, b = 2, c = 5;
        System.out.print(maximumSegments(n, a, b, c));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python implementation 
# to divide N into maximum 
# number of segments of 
# length a, b and c
  
# function to find 
# the maximum number 
# of segments
def maximumSegments(n, a, b, c) :
  
    # stores the maximum 
    # number of segments 
    # each index can have
    dp = [-1] * (n + 10)
  
    # 0th index will have 
    # 0 segments base case
    dp[0] = 0
  
    # traverse for all possible
    # segments till n
    for i in range(0, n) :
      
        if (dp[i] != -1) :
          
            # conditions
            dp[i + a] = max(dp[i] + 1, 
                            dp[i + a])
            dp[i + b] = max(dp[i] + 1, 
                            dp[i + b])
            dp[i + c] = max(dp[i] + 1, 
                            dp[i + c])
  
    return dp[n]
  

1624
Chapter 221. Maximum number of segments of lengths a, b and c

# Driver code
n = 7
a = 5
b = 2
c = 5
print (maximumSegments(n, a, 
                       b, c))
  
# This code is contributed by 
# Manish Shaw(manishshaw1)

C#

// C# implementation to divide N into


// maximum number of segments
// of length a, b and c
using System;
  
class GFG 
{
      
    // function to find the maximum
    // number of segments
    static int maximumSegments(int n, int a, 
                               int b, int c)
    {
        // stores the maximum number of
        // segments each index can have
        int []dp = new int[n + 10];
  
        // initialize with -1
        for(int i = 0; i < n + 10; i++)
        dp[i]= -1;
          
  
        // 0th index will have 0 segments
        // base case
        dp[0] = 0; 
  
        // traverse for all possible
        // segments till n
        for (int i = 0; i < n; i++) 
        {
            if (dp[i] != -1) 
            {
  
                // conditions
                dp[i + a] = Math.Max(dp[i] + 1, 

1625
Chapter 221. Maximum number of segments of lengths a, b and c

                                     dp[i + a]);
                dp[i + b] = Math.Max(dp[i] + 1, 
                                     dp[i + b]);
                dp[i + c] = Math.Max(dp[i] + 1, 
                                     dp[i + c]);
            }
        }
        return dp[n];
    }
  
    // Driver code
    public static void Main()
    {
        int n = 7, a = 5, b = 2, c = 5;
        Console.Write(maximumSegments(n, a, b, c));
    }
}
  
// This code is contributed by nitin mittal

PHP

<?php
// PHP implementation to divide 
// N into maximum number of 
// segments of length a, b and c
  
// function to find the maximum
// number of segments
function maximumSegments($n, $a, 
                         $b, $c)
{
    // stores the maximum  
    // number of segments 
    // each index can have
    $dp = array();
  
    // initialize with -1
    for($i = 0; $i < $n + 10; $i++)
        $dp[$i]= -1;
      
  
    // 0th index will have 
    // 0 segments base case
    $dp[0] = 0; 
  
    // traverse for all possible
    // segments till n

1626
Chapter 221. Maximum number of segments of lengths a, b and c

    for ($i = 0; $i < $n; $i++) 


    {
        if ($dp[$i] != -1) 
        {
            // conditions
            $dp[$i + $a] = max($dp[$i] + 1, 
                               $dp[$i + $a]);
            $dp[$i + $b] = max($dp[$i] + 1, 
                               $dp[$i + $b]);
            $dp[$i + $c] = max($dp[$i] + 1, 
                               $dp[$i + $c]);
        }
    }
    return $dp[$n];
}
  
// Driver code
$n = 7; $a = 5; 
$b = 2; $c = 5;
echo (maximumSegments($n, $a, 
                      $b, $c));
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

Output :

Time complexity : O(n)


Improved By : nitin mittal, manishshaw1

Source

https://www.geeksforgeeks.org/maximum-number-segments-lengths-b-c/

1627
Chapter 222

Maximum number of trailing


zeros in the product of the
subsets of size k

Maximum number of trailing zeros in the product of the subsets of size k - GeeksforGeeks
Given an array of size n and a positive integer k, find the maximum number of trailing zeros
in the product of the subsets of size k.
Examples:

Input : arr = {50, 4, 20}


k = 2
Output : 3
Here, we have 3 subsets of size 2. [50, 4]
has product 200, having 2 zeros at the end,
[4, 20] — product 80, having 1 zero at the
end, [50, 20] — product 1000, having 3 zeros
at the end. Therefore, the maximum zeros at
the end of the product is 3.

Input : arr = {15, 16, 3, 25, 9}


k = 3
Output : 3
Here, the subset [15, 16, 25] has product 6000.

Input : arr = {9, 77, 13}


k = 3
Output : 0
Here, the subset [9, 77, 13] has product 9009
having no zeros at the end.

1628
Chapter 222. Maximum number of trailing zeros in the product of the subsets of size k

Dynamic Programming approach :


Obviously, the number of zeros at the end of the number is determined by minimum of
powers of 2 and 5 in the number. Let pw5 be the maximal power of 5 in the number and
pw2 be the maximal power of 2.
Let, subset[i][j] be the maximum amount of 2s we can collect considering i numbers having
j number of 5s in each of them.
We traverse through all numbers of given, for every array element, we count number of 2s
and 5s in it. Let pw2 be the number of 2s in current number and pw5 be the number of 5s.
Now, there is one transition for subset[i][j]:
// For current number (pw2 two’s and pw5 five’s) we check
// if we can increase value of subset[i][j].
subset[i][j] = max(subset[i][j], subset[i-1][j-pw5] + pw2)
The above expression can also be written as below.
subset[i + 1][j + pw5] = max(subset[i + 1][j + pw5], subset[i][j] + pw2);
The answer will be max(ans, min(i, subset[k][i])
C++

// CPP program for finding the maximum number


// of trailing zeros in the product of the
// selected subset of size k.
#include <bits/stdc++.h>
using namespace std;
#define MAX5 100
  
// Function to calculate maximum zeros.
int maximumZeros(int* arr, int n, int k)
{
    // Initializing each value with -1;
    int subset[k+1][MAX5+5];    
    memset(subset, -1, sizeof(subset));
  
    subset[0][0] = 0;
  
    for (int p = 0; p < n; p++) {
        int pw2 = 0, pw5 = 0;
  
        // Calculating maximal power of 2 for
        // arr[p].
        while (arr[p] % 2 == 0) {
            pw2++;
            arr[p] /= 2;
        }
  
        // Calculating maximal power of 5 for

1629
Chapter 222. Maximum number of trailing zeros in the product of the subsets of size k

        // arr[p].
        while (arr[p] % 5 == 0) {
            pw5++;
            arr[p] /= 5;
        }
  
        // Calculating subset[i][j] for maximum
        // amount of twos we can collect by
        // checking first i numbers and taking
        // j of them with total power of five.
        for (int i = k - 1; i >= 0; i--)
            for (int j = 0; j < MAX5; j++)
  
                // If subset[i][j] is not calculated.
                if (subset[i][j] != -1)
                    subset[i + 1][j + pw5] = 
                    max(subset[i + 1][j + pw5],
                         subset[i][j] + pw2);
    } 
  
    // Calculating maximal number of zeros.
    // by taking minimum of 5 or 2 and then
    // taking maximum.
    int ans = 0;
    for (int i = 0; i < MAX5; i++)
        ans = max(ans, min(i, subset[k][i]));
  
    return ans;
}
  
// Driver function
int main()
{
    int arr[] = { 50, 4, 20 };
    int k = 2;
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maximumZeros(arr, n, k) << endl;
    return 0;
}

Python3

# Python3 program for finding the maximum number


# of trailing zeros in the product of the
# selected subset of size k.
MAX5 = 100
  
# Function to calculate maximum zeros.

1630
Chapter 222. Maximum number of trailing zeros in the product of the subsets of size k

def maximumZeros(arr, n, k):


    global MAX5
      
    # Initializing each value with -1
    subset = [[-1] * (MAX5 + 5) for _ in range(k + 1)]
  
    subset[0][0] = 0
  
    for p in arr:
          
        pw2, pw5 = 0, 0
  
        # Calculating maximal power 
        # of 2 for arr[p].
        while not p % 2 :
            pw2 += 1
            p //= 2
  
        # Calculating maximal power 
        # of 5 for arr[p].
        while not p % 5 :
            pw5 += 1
            p //= 5
  
        # Calculating subset[i][j] for maximum
        # amount of twos we can collect by
        # checking first i numbers and taking
        # j of them with total power of five.
        for i in range(k-1, -1, -1):
              
            for j in range(MAX5):
  
                # If subset[i][j] is not calculated.
                if subset[i][j] != -1:
                    subset[i + 1][j + pw5] = (
                        max(subset[i + 1][j + pw5], 
                        (subset[i][j] + pw2)))
  
    # Calculating maximal number of zeros.
    # by taking minimum of 5 or 2 and then
    # taking maximum.
    ans = 0
    for i in range(MAX5):
        ans = max(ans, min(i, subset[k][i]))
  
    return ans
  
  

1631
Chapter 222. Maximum number of trailing zeros in the product of the subsets of size k

# Driver function
arr = [ 50, 4, 20 ]
k = 2
n = len(arr)
  
print(maximumZeros(arr, n, k))
  
# This code is contributed by Ansu Kumari.

Output :

Source

https://www.geeksforgeeks.org/maximum-number-of-trailing-zeros-in-the-product-of-the-subsets-of-size-k/

1632
Chapter 223

Maximum path sum for each


position with jumps under
divisibility condition

Maximum path sum for each position with jumps under divisibility condition - Geeks-
forGeeks
Given an array of n positive integers. Initially we are at first position. We can jump to
position y (1 <= x <= n) from position x (1 <= x <= n) if x divides y and x < y. The task
is to print maximum sum path ending at every position x. Note : Since first element is at
position 1, we can jump to any position from here as 1 divides all other position numbers.
Examples :

Input : arr[] = {2, 3, 1, 4, 6, 5}


Output : 2 5 3 9 8 10
Maximum sum path ending with position 1 is 2.
For position 1, last position to visit is 1 only.
So maximum sum for position 1 = 2.

Maximum sum path ending with position 2 is 5.


For position 2, path can be jump from position 1
to 2 as 1 divides 2.
So maximum sum for position 2 = 2 + 3 = 5.

For position 3, path can be jump from position 1


to 3 as 1 divides 3.
So maximum sum for position 3 = 2 + 3 = 5.

For position 4, path can be jump from position 1


to 2 and 2 to 4.

1633
Chapter 223. Maximum path sum for each position with jumps under divisibility condition

So maximum sum for position 4 = 2 + 3 + 4 = 9.

For position 5, path can be jump from position 1


to 5.
So maximum sum for position 5 = 2 + 6 = 8.

For position 6, path can be jump from position


1 to 2 and 2 to 6 or 1 to 3 and 3 to 6.
But path 1 -> 2 -> 6 gives maximum sum for
position 6 = 2 + 3 + 5 = 10.

The idea is to use Dynamic Programming to solve this problem.

Create an 1-D array dp[] where each element dp[i]


stores maximum sum path ending at index i (or
position x where x = i+1) with divisible jumps.

The recurrence relation for dp[i] can be defined as:

dp[i] = max(dp[i], dp[divisor of i+1] + arr[i])

To find all the divisor of i+1, move from 1


divisor to sqrt(i+1).

Below is the implementation of this approach:

C++

// C++ program to print maximum path sum ending with


// each position x such that all path step positions
// divide x.
#include <bits/stdc++.h>
using namespace std;
  
void printMaxSum(int arr[], int n)
{
    // Create an array such that dp[i] stores maximum
    // path sum ending with i.
    int dp[n];
    memset(dp, 0, sizeof dp);
  
    // Calculating maximum sum path for each element.
    for (int i = 0; i < n; i++) {
        dp[i] = arr[i];
  
        // Finding previous step for arr[i]

1634
Chapter 223. Maximum path sum for each position with jumps under divisibility condition

        // Moving from 1 to sqrt(i+1) since all the


        // divisors are present from sqrt(i+1).
        int maxi = 0;
        for (int j = 1; j <= sqrt(i + 1); j++) {
            // Checking if j is divisor of i+1.
            if (((i + 1) % j == 0) && (i + 1) != j) {
                // Checking which divisor will provide
                // greater value.
                if (dp[j - 1] > maxi)
                    maxi = dp[j - 1];
                if (dp[(i + 1) / j - 1] > maxi && j != 1)
                    maxi = dp[(i + 1) / j - 1];
            }
        }
  
        dp[i] += maxi;
    }
  
    // Printing the answer (Maximum path sum ending
    // with every position i+1.
    for (int i = 0; i < n; i++)
        cout << dp[i] << " ";
}
  
// Driven Program
int main()
{
    int arr[] = { 2, 3, 1, 4, 6, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    printMaxSum(arr, n);
  
    return 0;
}

Java

// Java program to print maximum path


// sum ending with each position x such
// that all path step positions divide x.
import java.util.*;
  
class GFG {
  
    static void printMaxSum(int arr[], int n)
    {
        // Create an array such that dp[i]
        // stores maximum path sum ending with i.

1635
Chapter 223. Maximum path sum for each position with jumps under divisibility condition

        int dp[] = new int[n];


        Arrays.fill(dp, 0);
  
        // Calculating maximum sum
        // path for each element.
        for (int i = 0; i < n; i++) {
            dp[i] = arr[i];
  
            // Finding previous step for arr[i]
            // Moving from 1 to sqrt(i+1) since all the
            // divisors are present from sqrt(i+1).
            int maxi = 0;
            for (int j = 1; j <= Math.sqrt(i + 1); j++) {
                  
                // Checking if j is divisor of i+1.
                if (((i + 1) % j == 0) && (i + 1) != j) {
                      
                    // Checking which divisor will
                    // provide greater value.
                    if (dp[j - 1] > maxi)
                        maxi = dp[j - 1];
                    if (dp[(i + 1) / j - 1] > maxi && j != 1)
                        maxi = dp[(i + 1) / j - 1];
                }
            }
  
            dp[i] += maxi;
        }
  
        // Printing the answer (Maximum path sum 
        // ending with every position i+1.)
        for (int i = 0; i < n; i++)
            System.out.print(dp[i] + " ");
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 2, 3, 1, 4, 6, 5 };
        int n = arr.length;
          
        // Function calling
        printMaxSum(arr, n);
    }
}
  
// This code is contributed by Anant Agarwal.

1636
Chapter 223. Maximum path sum for each position with jumps under divisibility condition

Python3

# Python program to print maximum 


# path sum ending with each position
# x such that all path step positions
# divide x.
  
def printMaxSum(arr, n):
      
    # Create an array such that dp[i] 
    # stores maximum path sum ending with i.
    dp = [0 for i in range(n)]
  
    # Calculating maximum sum path 
    # for each element.
    for i in range(n):
        dp[i] = arr[i]
  
        # Finding previous step for arr[i]
        # Moving from 1 to sqrt(i + 1) since all the
        # divisiors are present from sqrt(i + 1).
        maxi = 0
        for j in range(1, int((i + 1) ** 0.5) + 1):
  
            # Checking if j is divisior of i + 1.
            if ((i + 1) % j == 0 and (i + 1) != j):
  
                # Checking which divisor will provide
                # greater value.
                if (dp[j - 1] > maxi):
                    maxi = dp[j - 1]
                if (dp[(i + 1) // j - 1] > maxi and j != 1):
                    maxi = dp[(i + 1) // j - 1]
  
        dp[i] += maxi
  
    # Printing the answer 
    # (Maximum path sum ending
    # with every position i + 1).
    for i in range(n):
        print(dp[i], end = ' ')
  
# Driver Program
arr = [2, 3, 1, 4, 6, 5]
n = len(arr)
printMaxSum(arr, n)
  
# This code is contributed by Soumen Ghosh.

1637
Chapter 223. Maximum path sum for each position with jumps under divisibility condition

C#

// C# program to print maximum path


// sum ending with each position x such
// that all path step positions divide x.
using System;
  
class GFG {
  
    static void printMaxSum(int[] arr, int n)
    {
        // Create an array such that dp[i]
        // stores maximum path sum ending with i.
        int[] dp = new int[n];
  
        // Calculating maximum sum
        // path for each element.
        for (int i = 0; i < n; i++) {
            dp[i] = arr[i];
  
            // Finding previous step for arr[i]
            // Moving from 1 to sqrt(i+1) since all the
            // divisors are present from sqrt(i+1).
            int maxi = 0;
            for (int j = 1; j <= Math.Sqrt(i + 1); j++) 
            {
                // Checking if j is divisor of i+1.
                if (((i + 1) % j == 0) && (i + 1) != j)
                {
                    // Checking which divisor will
                    // provide greater value.
                    if (dp[j - 1] > maxi)
                        maxi = dp[j - 1];
                    if (dp[(i + 1) / j - 1] > maxi && j != 1)
                        maxi = dp[(i + 1) / j - 1];
                }
            }
  
            dp[i] += maxi;
        }
  
        // Printing the answer (Maximum path sum ending
        // with every position i+1.)
        for (int i = 0; i < n; i++)
            Console.Write(dp[i] + " ");
    }
  
    // Driver code

1638
Chapter 223. Maximum path sum for each position with jumps under divisibility condition

    public static void Main()


    {
        int[] arr = { 2, 3, 1, 4, 6, 5 };
        int n = arr.Length;
          
        // Function calling
        printMaxSum(arr, n);
    }
}
  
// This code is contributed by vt_m.

Output:

2 5 3 9 8 10

Time Complexity: O(n*sqrt(n)).


Improved By : vt_m

Source

https://www.geeksforgeeks.org/maximum-path-sum-position-jumps-divisibility-condition/

1639
Chapter 224

Maximum path sum in a


triangle.

Maximum path sum in a triangle. - GeeksforGeeks


We have given numbers in form of triangle, by starting at the top of the triangle and moving
to adjacent numbers on the row below, find the maximum total from top to bottom.
Examples :

Input :
3
7 4
2 4 6
8 5 9 3
Output : 23
Explanation : 3 + 7 + 4 + 9 = 23

Input :
8
-4 4
2 2 6
1 1 1 1
Output : 19
Explanation : 8 + 4 + 6 + 1 = 19

We can go through the brute force by checking every possible path but that is much time
taking so we should try to solve this problem with the help of dynamic programming which
reduces the time complexity.
If we should left shift every element and put 0 at each empty position to make it a regular
matrix, then our problem looks like minimum cost path.
So, after converting our input triangle elements into a regular matrix we should apply the

1640
Chapter 224. Maximum path sum in a triangle.

dynamic programmic concept to find the maximum path sum.


Applying, DP in bottom-up manner we should solve our problem as:
Example:

3
7 4
2 4 6
8 5 9 3

Step 1 :
3 0 0 0
7 4 0 0
2 4 6 0
8 5 9 3

Step 2 :
3 0 0 0
7 4 0 0
10 13 15 0

Step 3 :
3 0 0 0
20 19 0 0

Step 4:
23 0 0 0

output : 23

C++

// C++ program for Dynamic


// Programming implementation of
// Max sum problem in a triangle 
#include<bits/stdc++.h>
using namespace std;
#define N 3
  
//  Function for finding maximum sum
int maxPathSum(int tri[][N], int m, int n)
{
     // loop for bottom-up calculation
     for (int i=m-1; i>=0; i--)
     {
        for (int j=0; j<=i; j++)
        {

1641
Chapter 224. Maximum path sum in a triangle.

            // for each element, check both


            // elements just below the number
            // and below right to the number
            // add the maximum of them to it
            if (tri[i+1][j] > tri[i+1][j+1])
                tri[i][j] += tri[i+1][j];
            else
                tri[i][j] += tri[i+1][j+1];
        }
     }
  
     // return the top element
     // which stores the maximum sum
     return tri[0][0];
}
  
/* Driver program to test above functions */
int main()
{
   int tri[N][N] = {  {1, 0, 0},
                      {4, 8, 0},
                      {1, 5, 3} };
   cout << maxPathSum(tri, 2, 2);
   return 0;
}

Java

// Java Program for Dynamic 


// Programming implementation of
// Max sum problem in a triangle 
import java.io.*;
  
class GFG {
          
    static int N = 3;
      
    // Function for finding maximum sum
    static int maxPathSum(int tri[][], int m, int n)
    {
        // loop for bottom-up calculation
        for (int i = m - 1; i >= 0; i--)
        {
            for (int j = 0; j <= i; j++)
            {
                // for each element, check both
                // elements just below the number
                // and below right to the number

1642
Chapter 224. Maximum path sum in a triangle.

                // add the maximum of them to it


                if (tri[i + 1][j] > tri[i + 1][j + 1])
                    tri[i][j] += tri[i + 1][j];
                else
                    tri[i][j] += tri[i + 1][j + 1];
            }
        }
      
        // return the top element
        // which stores the maximum sum
        return tri[0][0];
    }
      
    /* Driver program to test above functions */
    public static void main (String[] args)
    {
        int tri[][] = { {1, 0, 0},
                        {4, 8, 0},
                        {1, 5, 3} };
        System.out.println ( maxPathSum(tri, 2, 2));
    }
}
  
// This code is contributed by vt_m

Python3

# Python program for


# Dynamic Programming
# implementation of Max
# sum problem in a
# triangle
  
N = 3
  
# Function for finding maximum sum
def maxPathSum(tri, m, n):
  
    # loop for bottom-up calculation
    for i in range(m-1, -1, -1):
        for j in range(i+1):
  
            # for each element, check both
            # elements just below the number
            # and below right to the number
            # add the maximum of them to it
            if (tri[i+1][j] > tri[i+1][j+1]):
                tri[i][j] += tri[i+1][j]

1643
Chapter 224. Maximum path sum in a triangle.

            else:
                tri[i][j] += tri[i+1][j+1]
  
    # return the top element
    # which stores the maximum sum
    return tri[0][0]
  
# Driver program to test above function
  
tri = [[1, 0, 0],
       [4, 8, 0],
       [1, 5, 3]]
print(maxPathSum(tri, 2, 2))
  
# This code is contributed
# by Soumen Ghosh.

C#

// C# Program for Dynamic Programming


// implementation of Max sum problem 
// in a triangle 
using System;
  
class GFG {
      
    // Function for finding maximum sum
    static int maxPathSum(int [,]tri, 
                          int m, int n)
    {
        // loop for bottom-up calculation
        for (int i = m - 1; i >= 0; i--)
        {
            for (int j = 0; j <= i; j++)
            {
                // for each element, 
                // check both elements
                // just below the number
                // and below right to
                // the number add the
                // maximum of them to it
                if (tri[i + 1,j] > 
                       tri[i + 1,j + 1])
                    tri[i,j] += 
                           tri[i + 1,j];
                else
                    tri[i,j] += 
                       tri[i + 1,j + 1];

1644
Chapter 224. Maximum path sum in a triangle.

            }
        }
      
        // return the top element
        // which stores the maximum sum
        return tri[0,0];
    }
      
    /* Driver program to test above
    functions */
    public static void Main ()
    {
        int [,]tri = { {1, 0, 0},
                        {4, 8, 0},
                        {1, 5, 3} };
                          
        Console.Write ( 
             maxPathSum(tri, 2, 2));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program for Dynamic
// Programming implementation of
// Max sum problem in a triangle 
  
// Function for finding
// maximum sum
function maxPathSum($tri, $m, $n)
{
    // loop for bottom-up
    // calculation
    for ( $i = $m - 1; $i >= 0; $i--)
    {
        for ($j = 0; $j <= $i; $j++)
        {
            // for each element, check 
            // both elements just below 
            // the number and below right 
            // to the number add the maximum
            // of them to it
            if ($tri[$i + 1][$j] > $tri[$i + 1]
                                       [$j + 1])
                $tri[$i][$j] += $tri[$i + 1][$j];

1645
Chapter 224. Maximum path sum in a triangle.

            else
                $tri[$i][$j] += $tri[$i + 1]
                                    [$j + 1];
        }
    }
  
    // return the top element
    // which stores the maximum sum
    return $tri[0][0];
}
  
// Driver Code
$tri= array(array(1, 0, 0),
            array(4, 8, 0),
            array(1, 5, 3));
echo maxPathSum($tri, 2, 2);
  
// This code is contributed by ajit
?>

Output :

14

Improved By : jit_t, nitin mittal

Source

https://www.geeksforgeeks.org/maximum-path-sum-triangle/

1646
Chapter 225

Maximum path sum that


starting with any cell of 0-th
row and ending with any cell of
(N-1)-th row

Maximum path sum that starting with any cell of 0-th row and ending with any cell of
(N-1)-th row - GeeksforGeeks
Given a N X N matrix Mat[N][N] of positive integers. There are only three possible moves
from a cell (i, j)

1. (i+1, j)
2. (i+1, j-1)
3. (i+1, j+1)

Starting from any column in row 0, return the largest sum of any of the paths up to row
N-1.
Examples:

Input : mat[4][4] = { {4, 2, 3, 4},


{2, 9, 1, 10},
{15, 1, 3, 0},
{16, 92, 41, 44} };
Output :120
path : 4 + 9 + 15 + 92 = 120

Asked in: Amazon interview

1647
Chapter 225. Maximum path sum that starting with any cell of 0-th row and ending with
any cell of (N-1)-th row

The above problem can be recursively defined.


Let initial position be MaximumPathSum(N-1, j), where j varies from 0 to N-1. We return
maximum value between all path that we start traversing (N-1, j) [ where j varies from 0 to
N-1]

i = N-1, j = 0 to N -1
int MaximumPath(Mat[][N], I, j)

// IF we reached to first row of


// matrix then return value of that
// element
IF ( i == 0 && j = 0 )
return Mat[i][j]

// out of matrix bound


IF( i = N || j < 0 )
return 0;

// call all rest position that we reached


// from current position and find maximum
// between them and add current value in
// that path
return max(MaximumPath(Mat, i-1, j),
MaximumPath(Mat, i-1, j-1),
MaximumPath(Mat, i-1, j+1)))
+ Mat[i][j];

If we draw recursion tree of above recursive solution, we can observe overlapping subprob-
lems. Since the problem has overlapping subproblems, we can solve it efficiently using
Dynamic Programming. Below is Dynamic Programming based solution.

CPP

// C++ program to find Maximum path sum


// start any column in row '0' and ends
// up to any column in row 'n-1'
#include<bits/stdc++.h>
using namespace std;
#define N 4
  
// function find maximum sum path
int MaximumPath(int Mat[][N])
{
    int result = 0 ;
  

1648
Chapter 225. Maximum path sum that starting with any cell of 0-th row and ending with
any cell of (N-1)-th row

    // creat 2D matrix to store the sum


    // of the path
    int dp[N][N+2];
  
    // initialize all dp matrix as '0'
    memset(dp, 0, sizeof(dp));
  
    // copy all element of first column into
    // 'dp' first column
    for (int i = 0 ; i < N ; i++)
        dp[0][i+1] = Mat[0][i];
  
    for (int i = 1 ; i < N ; i++)
        for (int j = 1 ; j <= N ; j++)
            dp[i][j] = max(dp[i-1][j-1],
                           max(dp[i-1][j],
                               dp[i-1][j+1])) +
                       Mat[i][j-1] ;
  
    // Find maximum path sum that end ups
    // at  any column of last row 'N-1'
    for (int i=0; i<=N; i++)
        result = max(result, dp[N-1][i]);
  
    // return maximum sum path
    return result ;
}
  
// driver program to test above function
int main()
{
    int Mat[4][4] = { { 4, 2 , 3 , 4 },
        { 2 , 9 , 1 , 10},
        { 15, 1 , 3 , 0 },
        { 16 ,92, 41, 44 }
    };
  
    cout << MaximumPath ( Mat ) <<endl ;
    return 0;
}

Java

// Java program to find Maximum path sum


// start any column in row '0' and ends
// up to any column in row 'n-1'
import java.util.*;
  

1649
Chapter 225. Maximum path sum that starting with any cell of 0-th row and ending with
any cell of (N-1)-th row

class GFG {
      
    static int N = 4;
  
    // function find maximum sum path
    static int MaximumPath(int Mat[][])
    {
        int result = 0;
  
        // creat 2D matrix to store the sum
        // of the path
        int dp[][] = new int[N][N + 2];
  
        // initialize all dp matrix as '0'
        for (int[] rows : dp)
            Arrays.fill(rows, 0);
  
        // copy all element of first column into
        // 'dp' first column
        for (int i = 0; i < N; i++)
            dp[0][i + 1] = Mat[0][i];
  
        for (int i = 1; i < N; i++)
            for (int j = 1; j <= N; j++)
                dp[i][j] = Math.max(dp[i - 1][j - 1],
                                    Math.max(dp[i - 1][j],
                                    dp[i - 1][j + 1])) +
                                    Mat[i][j - 1];
  
        // Find maximum path sum that end ups
        // at any column of last row 'N-1'
        for (int i = 0; i <= N; i++)
            result = Math.max(result, dp[N - 1][i]);
  
        // return maximum sum path
        return result;
    }
      
    // driver code
    public static void main(String arg[])
    {
        int Mat[][] = { { 4, 2, 3, 4 },
                        { 2, 9, 1, 10 },
                        { 15, 1, 3, 0 },
                        { 16, 92, 41, 44 } };
  
        System.out.println(MaximumPath(Mat));
    }

1650
Chapter 225. Maximum path sum that starting with any cell of 0-th row and ending with
any cell of (N-1)-th row

}
  
// This code is contributed by Anant Agarwal.

Python3

# Python program to find


# Maximum path sum
# start any column in
# row '0' and ends
# up to any column in row 'n-1'
  
N = 4
  
# function find maximum sum path
def MaximumPath(Mat):
  
    result = 0
  
    # create 2D matrix to store the sum
    # of the path
    # initialize all dp matrix as '0'
    dp = [[0 for i in range(N+2)] for j in range(N)]
  
    # copy all element of first column into
    # dp first column
    for i in range(N):
        for j in range(1, N+1):
            dp[i][j] = max(dp[i-1][j-1],
                           max(dp[i-1][j],
                               dp[i-1][j+1])) + \
                       Mat[i][j-1]
  
    # Find maximum path sum that end ups
    # at any column of last row 'N-1'
    for i in range(N+1):
        result = max(result, dp[N-1][i])
  
    # return maximum sum path
    return result
  
# driver program to test above function
Mat = [[4, 2, 3, 4],
       [2, 9, 1, 10],
       [15, 1, 3, 0],
       [16, 92, 41, 44]]
  
print(MaximumPath(Mat))

1651
Chapter 225. Maximum path sum that starting with any cell of 0-th row and ending with
any cell of (N-1)-th row

  
# This code is contributed by Soumen Ghosh.

Output:

120

Time complexity : O(N2 )

Source

https://www.geeksforgeeks.org/maximum-path-sum-starting-cell-0-th-row-ending-cell-n-1-th-row/

1652
Chapter 226

Maximum points collected by


two persons allowed to meet
once

Maximum points collected by two persons allowed to meet once - GeeksforGeeks


Given a 2-D matrix A[N][M] where A[i][j] denotes the points available on this cell. Two
persons, P1 and P2, start from two corners of this matrix. P1 starts from top left and needs
to reach bottom right. On the other hand, P2 starts bottom left and needs to reach top
right. P1 can move right and down. P2 can right and up. As they visit a cell, points A[i][j]
are added to their total. The task is to maximize the sum of total points collected by both
of them under the condition that they shall meet only once and the cost of this cell shall
not be included in either of their total.
Examples:

Input : A[][] = { {100, 100, 100},


{100, 1, 100},
{100, 100, 100}};
Output : 800
P1 needs to go from (0,0) to (2,2)
P2 needs to go from (2,0) to (0,2)
Explanation: P1 goes through A[0][0]->A[0][1]->A[1][1]->
A[2][1]->A[2][2].
P2 goes through A[2][0]->A[1][0]->A[1][1]->
A[1][2]->A[0][2].
They meet at A[2][2]. So total points collected:
A[0][0] + A[0][1] + A[2][1] + A[2][2] +
A[2][0] + A[1][0] + A[1][2] + A[0][2] = 800

1653
Chapter 226. Maximum points collected by two persons allowed to meet once

Input : A[][] = {{100, 100, 100, 100},


{100, 100, 100, 100},
{100, 0, 100, 100},
{100, 100, 100, 100}};
Output : 1200

P1 needs to move from top left (0, 0) to bottom right (n-1, m-1). P1 can move right and
down, i.e., from A[i][j] to A[i][j+1] or A[i+1][j]
P2 needs to move from bottom left (n-1, 0) to top right (0, m-1). P2 can move right and
up, i.e., from A[i][j] to A[i][j+1] or A[i-1][j].
The idea is to consider every point as a meeting point and find maximum of all meeting
points. When we consider a point A[i][j] as meeting point, we need to have following four
values to find maximum total points collected when A[i][j] is meeting point.
1) Points collected by P1 from (0, 0) to (i, j).
2) Points collected by P1 from (i, j) to (n-1, m-1).
3) Points collected by P2 from (n-1, 0) to (i, j).
4) Points collected by P2 from (i, j) to (0, m-1).
We can compute above four values using Dynamic Programming. Once we have above four
values for every point, we can find maximum points at every meeting point.
For every meeting points, there are two possible values to reach it and leave it as we are
allowed to have only one meeting point.
1) P1 reaches it through a right move and p2 through a up move and they leave same way
also.
2) P1 reaches it through a down move and p2 through a right move and they leave same
way also.
We take maximum of above two values to find optimal points at this meeting point.
Finally, we return maximum of all meeting points.

// C++ program to find maximum points that can


// be collected by two persons in a matrix.
#include<bits/stdc++.h>
#define M 3
#define N 3
using namespace std;
  
int findMaxPoints(int A[][M])
{
    // To store points collected by Person P1
    // when he/she begins journy from start and
    // from end.
    int P1S[M+1][N+1], P1E[M+1][N+1];
    memset(P1S, 0, sizeof(P1S));
    memset(P1E, 0, sizeof(P1E));
  
    // To store points collected by Person P2

1654
Chapter 226. Maximum points collected by two persons allowed to meet once

    // when he/she begins journey from start and


    // from end.
    int P2S[M+1][N+1], P2E[M+1][N+1];
    memset(P2S, 0, sizeof(P2S));
    memset(P2E, 0, sizeof(P2E));
  
    // Table for P1's journey from
    // start to meeting cell
    for (int i=1; i<=N; i++)
        for (int j=1; j<=M; j++)
            P1S[i][j] = max(P1S[i-1][j],
                  P1S[i][j-1]) + A[i-1][j-1];
  
    // Table for P1's journey from
    // end to meet cell
    for (int i=N; i>=1; i--)
        for (int j=M; j>=1; j--)
            P1E[i][j] = max(P1E[i+1][j],
                  P1E[i][j+1]) + A[i-1][j-1];
  
    // Table for P2's journey from start to meeting cell
    for (int i=N; i>=1; i--)
        for(int j=1; j<=M; j++)
            P2S[i][j] = max(P2S[i+1][j],
                  P2S[i][j-1]) + A[i-1][j-1];
  
    // Table for P2's journey from end to meeting cell
    for (int i=1; i<=N; i++)
        for (int j=M; j>=1; j--)
            P2E[i][j] = max(P2E[i-1][j],
                  P2E[i][j+1]) + A[i-1][j-1];
  
    // Now iterate over all meeting positions (i,j)
    int ans = 0;
    for (int i=2; i<N; i++)
    {
        for (int j=2; j<M; j++)
        {
            int op1 = P1S[i][j-1] + P1E[i][j+1] +
                      P2S[i+1][j] + P2E[i-1][j];
            int op2 = P1S[i-1][j] + P1E[i+1][j] +
                      P2S[i][j-1] + P2E[i][j+1];
            ans = max(ans, max(op1, op2));
        }
    }
    return ans;
}
  

1655
Chapter 226. Maximum points collected by two persons allowed to meet once

// Driver code
int main()
{
    //input the calories burnt matrix
    int A[][M] = {{100, 100, 100},
                  {100, 1, 100},
                  {100, 100, 100}};
    cout << "Max Points : " << findMaxPoints(A);
    return 0;
}

Output:

Max Points : 800

Time Complexity : O(N * M)


Auxiliary Space : O(N * M)

Source

https://www.geeksforgeeks.org/maximum-points-collected-by-two-persons-allowed-to-meet-once/

1656
Chapter 227

Maximum points from top left


of matrix to bottom right and
return back

Maximum points from top left of matrix to bottom right and return back - GeeksforGeeks
Given a matrix of size N X M consisting of ‘#’, ‘.’ and ‘*’. ‘#’ means blocked path, ‘.’
means walkable path and ‘*’ means point you have to collect. Now consider you are at top
left of the matrix. You have to reach bottom right of the matrix and come back to top left.
When you are moving top left to bottom right, you are allowed to walk right or down. And
when you are moving bottom right to top left, you are allowed to walk left or up. The task
is find the maximum points you can grab during your whole journey. Points once taken will
be converted into ‘.’ i.e walkable path.
Examples:

Input : N = 3, M = 4
****
.##.
.##.
****
Output : 8

Input : N = 9, M = 7
*........
.....**#.
..**...#*
..####*#.
.*.#*.*#.
...#**...
*........

1657
Chapter 227. Maximum points from top left of matrix to bottom right and return back

Output : 7

If you consider two paths – one from (0, 0) to (N – 1, M – 1) and another from (N – 1, M –
1) to (0, 0) and collect maximum * in each path. You might end up with wrong answer. If
you add the answer of both the paths independently, you will be calculating the intersecting
points once again while backtracking. Essentially, ending up with the same path. Even if
you keep a visited array, marking every * on the first path, you will still not end up with
the correct answer.
Consider the following example:

If we consider as two independent path, then

total * collected is 7.
Whereas the maximum points collected can be 8 by following paths.

1658
Chapter 227. Maximum points from top left of matrix to bottom right and return back

There are 4 * on each path. Hence, total = 8.


Thus we see that the optimal solution is not the sum of optimal solutions of both the path
independently. The optimal answer for one does not ensure an optimal answer.
So, we will have to calculate both the paths simultaneously. This is needed because the
answer for path 2 depends on the route chosen by path 1. Simultaneous calculation can be
done by considering two path from (0, 0) to (N-1, M-1) and making four decisions at each
position (two for each).
So instead of two traveling one path from top left to bottom right and other from bottom
right to top left, we will travel two path from (0, 0) to (N-1, M-1) simultaneously, so at each
step we take one step for both path. So our state will consist of (x1, y1, x2, y2) where (x1,
y1) is position of first path and (x2, y2) is position of second tourist in grid.
Points to notice:
1. At each step either step can move right or down, so we have 4 choices for movement(2
choice for each path).
2. If both path are on the same cell (x1 == x2 and y1 == y2) then we can add only 1 to
result if that cell have *.
3. We can reduce the complexity by reducing state dimesion from 4 to 3. If we know the
position of first path (x1, y1) the x coordinate of second path x2, then we must have x1 +
y1 = x2 + y2 since both path cover the same distance in same amount of time. So y2 = x1
+ y1 – x2 and our state depends only on (x1, y1, x2).
Below is C++ implementation of this approach:

// CPP program to find maximum points that can 


// be collected in a journey from top to bottom 
// and then back from bottom to top,
#include <bits/stdc++.h>
#define MAX 5
#define N 5

1659
Chapter 227. Maximum points from top left of matrix to bottom right and return back

#define M 5
#define inf 100000
using namespace std;
  
// Calculating the points at a (row1, col1) && 
// (row2, col2) from path1 && path2
int cost(char grid[][M], int row1, int col1, 
                           int row2, int col2)
{
    // If both path is at same cell
    if (row1 == row2 && col1 == col2) {
  
        // If the cell contain *, return 1
        if (grid[row1][col1] == '*')
            return 1;
  
        // else return 0.
        return 0;
    }
  
    int ans = 0;
  
    // If path 1 contain *, add to answer.
    if (grid[row1][col1] == '*')
        ans++;
  
    // If path  contain *, add to answer.
    if (grid[row2][col2] == '*')
        ans++;
  
    return ans;
}
  
// Calculate the maximum points that can be
// collected.
int solve(int n, int m, char grid[][M],
         int dp[MAX][MAX][MAX], int row1, 
                      int col1, int row2)
{
    int col2 = (row1 + col1) - (row2);
  
    // If both path reach the bottom right cell
    if (row1 == n - 1 && col1 == m - 1 &&
        row2 == n - 1 && col2 == m - 1)
        return 0;
  
    // If moving out of grid
    if (row1 >= n || col1 >= m || 

1660
Chapter 227. Maximum points from top left of matrix to bottom right and return back

        row2 >= n || col2 >= m)


        return -1 * inf;
  
    // If already calculated, return the value
    if (dp[row1][col1][row2] != -1)
        return dp[row1][col1][row2];
  
    // Vaiable for 4 options.
    int ch1 = -1 * inf, ch2 = -1 * inf;
    int ch3 = -1 * inf, ch4 = -1 * inf;
  
    // If path 1 is moving right and path 2 
    // is moving down.
    if (grid[row1][col1 + 1] != '#' && 
        grid[row2 + 1][col2] != '#')
      ch1 = cost(grid, row1, col1 + 1, row2 + 1, col2) + 
        solve(n, m, grid, dp, row1, col1 + 1, row2 + 1);
  
    // If path 1 is moving right and path 2 is moving
    // right.
    if (grid[row1][col1 + 1] != '#' && 
        grid[row2][col2 + 1] != '#')
      ch2 = cost(grid, row1, col1 + 1, row2, col2 + 1) + 
            solve(n, m, grid, dp, row1, col1 + 1, row2);
  
    // If path 1 is moving down and path 2 is moving right.
    if (grid[row1 + 1][col1] != '#' && 
        grid[row2][col2 + 1] != '#')
     ch3 = cost(grid, row1 + 1, col1, row2, col2 + 1) + 
           solve(n, m, grid, dp, row1 + 1, col1, row2);
  
    // If path 1 is moving down and path 2 is moving down.
    if (grid[row1 + 1][col1] != '#' && 
        grid[row2 + 1][col2] != '#')
      ch4 = cost(grid, row1 + 1, col1, row2 + 1, col2) +
         solve(n, m, grid, dp, row1 + 1, col1, row2 + 1);
  
    // Returning the maximum of 4 options.
    return dp[row1][col1][row2] = max({ch1, ch2, ch3, ch4});
}
  
// Wrapper Function
int wrapper(int n, int m, char grid[N][M])
{
    int ans = 0;
    int dp[MAX][MAX][MAX];
    memset(dp, -1, sizeof dp);
  

1661
Chapter 227. Maximum points from top left of matrix to bottom right and return back

    // If last bottom right cell is blcoked


    if (grid[n - 1][m - 1] == '#' || grid[0][0] == '#')
        ans = -1 * inf;
  
    // If top left cell contain *
    if (grid[0][0] == '*')
        ans++;
    grid[0][0] = '.';
  
    // If bottom right cell contain *
    if (grid[n - 1][m - 1] == '*')
        ans++;
    grid[n - 1][m - 1] = '.';
  
    ans += solve(n, m, grid, dp, 0, 0, 0);
    return max(ans, 0);
}
  
// Driven Program
int main()
{
    int n = 5, m = 5;
  
    char grid[N][M] = {
        { '.', '*', '.', '*', '.' },
        { '*', '#', '#', '#', '.' },
        { '*', '.', '*', '.', '*' },
        { '.', '#', '#', '#', '*' },
        { '.', '*', '.', '*', '.' }
    };
  
    cout << wrapper(n, m, grid) << endl;
    return 0;
}

Output:

Time Complexity: O(N^3)

Source

https://www.geeksforgeeks.org/maximum-points-top-left-matrix-bottom-right-return-back/

1662
Chapter 228

Maximum product of an
increasing subsequence

Maximum product of an increasing subsequence - GeeksforGeeks


Given an array of numbers, find the maximum product formed by multiplying numbers of
an increasing subsequence of that array.
Note: A single number is supposed to be an increasing subsequence of size 1.
Examples:

Input : arr[] = { 3, 100, 4, 5, 150, 6 }


Output : 45000
Maximum product is 45000 formed by the
increasing subsequence 3, 100, 150. Note
that the longest increasing subsequence
is different {3, 4, 5, 6}

Input : arr[] = { 10, 22, 9, 33, 21, 50, 41, 60 }


Output : 21780000
Maximum product is 21780000 formed by the
increasing subsequence 10, 22, 33, 50, 60.

Prerequisite : Longest Increasing Subsequence


Approach: Use a dynamic approach to maintain a table mpis[]. The value of mpis[i]
stores product maximum product increasing subsequence ending with arr[i]. Initially all the
values of increasing subsequence table are initialized to arr[i]. We use recursive approach
similar to LIS problem to find the result.

C++

1663
Chapter 228. Maximum product of an increasing subsequence

/* Dynamic programming C++ implementation of maximum 


   product of an increasing subsequence */
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
  
// Returns product of maximum product increasing
// subsequence.
ll lis(ll arr[], ll n)
{
    ll mpis[n];
  
    /* Initialize MPIS values */
    for (int i = 0; i < n; i++)
        mpis[i] = arr[i];
  
    /* Compute optimized MPIS values considering
       every element as ending element of sequence */
    for (int i = 1; i < n; i++)
        for (int j = 0; j < i; j++)
            if (arr[i] > arr[j] && mpis[i] < (mpis[j] * arr[i]))
                mpis[i] = mpis[j] * arr[i];
  
    /* Pick maximum of all product values */
    return *max_element(mpis, mpis + n);
}
  
/* Driver program to test above function */
int main()
{
    ll arr[] = { 3, 100, 4, 5, 150, 6 };
    ll n = sizeof(arr) / sizeof(arr[0]);
    printf("%lld", lis(arr, n));
    return 0;
}

Java

/* Dynamic programming Java implementation 


of maximum product of an increasing 
subsequence */
import java.util.Arrays;
import java.util.Collections;
  
class GFG {
  
    // Returns product of maximum product
    // increasing subsequence.

1664
Chapter 228. Maximum product of an increasing subsequence

    static int lis(int[] arr, int n)


    {
        int[] mpis = new int[n];
        int max = Integer.MIN_VALUE;
          
        /* Initialize MPIS values */
        for (int i = 0; i < n; i++)
            mpis[i] = arr[i];
  
        /* Compute optimized MPIS values 
        considering every element as ending
        element of sequence */
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] > arr[j] && mpis[i] 
                         < (mpis[j] * arr[i]))
                    mpis[i] = mpis[j] * arr[i];
  
        /* Pick maximum of all product values 
        using for loop*/
        for (int k = 0; k < mpis.length; k++)
        {
            if (mpis[k] > max) {
                max = mpis[k];
            }
        }
          
        return max;
    }
  
    // Driver program to test above function
    static public void main(String[] args)
    {
  
        int[] arr = { 3, 100, 4, 5, 150, 6 };
        int n = arr.length;
  
        System.out.println(lis(arr, n));
    }
}
  
// This code is contributed by parashar.

Python3

# Dynamic programming Python3 implementation


# of maximum product of an increasing
# subsequence 

1665
Chapter 228. Maximum product of an increasing subsequence

  
# Returns product of maximum product
# increasing subsequence.
def lis (arr, n ):
    mpis =[0] * (n)
      
    # Initialize MPIS values
    for i in range(n):
        mpis[i] = arr[i]
      
    # Compute optimized MPIS values
    # considering every element as 
    # ending element of sequence
    for i in range(1, n):
        for j in range(i):
            if (arr[i] > arr[j] and
                    mpis[i] < (mpis[j] * arr[i])):
                        mpis[i] = mpis[j] * arr[i]
      
    # Pick maximum of all product values 
    return max(mpis)
  
# Driver code to test above function
arr = [3, 100, 4, 5, 150, 6]
n = len(arr)
print( lis(arr, n))
  
# This code is contributed by "Sharad_Bhardwaj".

C#

/* Dynamic programming C# implementation 


of maximum product of an increasing 
subsequence */
using System;
using System.Linq;
  
public class GFG {
  
    // Returns product of maximum product
    // increasing subsequence.
    static long lis(long[] arr, long n)
    {
        long[] mpis = new long[n];
  
        /* Initialize MPIS values */
        for (int i = 0; i < n; i++)
            mpis[i] = arr[i];

1666
Chapter 228. Maximum product of an increasing subsequence

  
        /* Compute optimized MPIS values considering
        every element as ending element of sequence */
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] > arr[j] && mpis[i] < (mpis[j] * arr[i]))
                    mpis[i] = mpis[j] * arr[i];
  
        /* Pick maximum of all product values */
        return mpis.Max();
    }
  
    /* Driver program to test above function */
    static public void Main()
    {
  
        long[] arr = { 3, 100, 4, 5, 150, 6 };
        long n = arr.Length;
  
        Console.WriteLine(lis(arr, n));
    }
}
  
// This code is contributed by vt_m.

Output:

45000

Time Complexity: O(n^2)


Auxiliary Space : O(n)
Improved By : parashar

Source

https://www.geeksforgeeks.org/maximum-product-increasing-subsequence/

1667
Chapter 229

Maximum profit by buying and


selling a share at most k times

Maximum profit by buying and selling a share at most k times - GeeksforGeeks


In share trading, a buyer buys shares and sells on future date. Given stock price of n days,
the trader is allowed to make at most k transactions, where new transaction can only start
after previous transaction is complete, find out maximum profit that a share trader could
have made.

Input:
Price = [10, 22, 5, 75, 65, 80]
K = 2
Output: 87
Trader earns 87 as sum of 12 and 75
Buy at price 10, sell at 22, buy at
5 and sell at 80

Input:
Price = [12, 14, 17, 10, 14, 13, 12, 15]
K = 3
Output: 12
Trader earns 12 as sum of 5, 4 and 3
Buy at price 12, sell at 17, buy at 10
and sell at 14 and buy at 12 and sell
at 15

Input:
Price = [100, 30, 15, 10, 8, 25, 80]
K = 3
Output: 72
Only one transaction. Buy at price 8

1668
Chapter 229. Maximum profit by buying and selling a share at most k times

and sell at 80.

Input:
Price = [90, 80, 70, 60, 50]
K = 1
Output: 0
Not possible to earn.

There are various versions of the problem. If we are allowed to buy and sell only once, then
we can use Maximum difference between two elements algorithm. If we are allowed to make
at most 2 transactions, we can follow approach discussed here. If we are allowed to buy and
sell any number of times, we can follow approach discussed here.
In this post, we are only allowed to make at max k transactions. The problem can be solve
by using dynamic programming.
Let profit[t][i] represent maximum profit using at most t transactions up to day i (including
day i). Then the relation is:
profit[t][i] = max(profit[t][i-1], max(price[i] – price[j] + profit[t-1][j]))
for all j in range [0, i-1]
profit[t][i] will be maximum of –

1. profit[t][i-1] which represents not doing any transaction on the ith day.
2. Maximum profit gained by selling on ith day. In order to sell shares on ith day, we
need to purchase it on any one of [0, i – 1] days. If we buy shares on jth day and sell
it on ith day, max profit will be price[i] – price[j] + profit[t-1][j] where j varies from 0
to i-1. Here profit[t-1][j] is best we could have done with one less transaction till jth
day.

Below is Dynamic Programming based implementation.

C++

// C++ program to find out maximum profit by


// buying and selling a share atmost k times
// given stock price of n days
#include <climits>
#include <iostream>
using namespace std;
  
// Function to find out maximum profit by buying
// & selling a share atmost k times given stock
// price of n days
int maxProfit(int price[], int n, int k)
{
    // table to store results of subproblems
    // profit[t][i] stores maximum profit using

1669
Chapter 229. Maximum profit by buying and selling a share at most k times

    // atmost t transactions up to day i (including


    // day i)
    int profit[k + 1][n + 1];
  
    // For day 0, you can't earn money
    // irrespective of how many times you trade
    for (int i = 0; i <= k; i++)
        profit[i][0] = 0;
  
    // profit is 0 if we don't do any transation
    // (i.e. k =0)
    for (int j = 0; j <= n; j++)
        profit[0][j] = 0;
  
    // fill the table in bottom-up fashion
    for (int i = 1; i <= k; i++) {
        for (int j = 1; j < n; j++) {
            int max_so_far = INT_MIN;
  
            for (int m = 0; m < j; m++)
                max_so_far = max(max_so_far,
                                 price[j] - price[m] + profit[i - 1][m]);
  
            profit[i][j] = max(profit[i][j - 1], max_so_far);
        }
    }
  
    return profit[k][n - 1];
}
  
// Driver code
int main()
{
    int k = 2;
    int price[] = { 10, 22, 5, 75, 65, 80 };
    int n = sizeof(price) / sizeof(price[0]);
  
    cout << "Maximum profit is: "
         << maxProfit(price, n, k);
  
    return 0;
}

Java

// Java program to find out maximum 


// profit by buying and selling a
// share atmost k times given

1670
Chapter 229. Maximum profit by buying and selling a share at most k times

// stock price of n days


  
class GFG {
      
    // Function to find out 
    // maximum profit by 
    // buying & selling a 
    // share atmost k times
    // given stock price of n days
    static int maxProfit(int[] price, 
                         int n, 
                         int k)
    {
          
        // table to store results
        // of subproblems
        // profit[t][i] stores 
        // maximum profit using 
        // atmost t transactions up
        // to day i (including day i)
        int[][] profit = new int[k + 1][n + 1];
  
        // For day 0, you can't 
        // earn money irrespective
        // of how many times you trade
        for (int i = 0; i <= k; i++)
            profit[i][0] = 0;
  
        // profit is 0 if we don't
        // do any transation
        // (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0][j] = 0;
  
        // fill the table in 
        // bottom-up fashion
        for (int i = 1; i <= k; i++) 
        {
            for (int j = 1; j < n; j++)
            {
                int max_so_far = 0;
  
                for (int m = 0; m < j; m++)
                max_so_far = Math.max(max_so_far, price[j] -
                             price[m] + profit[i - 1][m]);
  
                profit[i][j] = Math.max(profit[i] [j - 1], 
                                              max_so_far);

1671
Chapter 229. Maximum profit by buying and selling a share at most k times

            }
        }
  
        return profit[k][n - 1];
    }
  
    // Driver code 
    public static void main(String []args)
    {
        int k = 2;
        int[] price = { 10, 22, 5, 75, 65, 80 };
        int n = price.length;
        System.out.println("Maximum profit is: " + 
                            maxProfit(price, n, k));
    }
}
  
// This code is contributed by Anshul Aggarwal.

Python3

# Python program to maximize the profit


# by doing at most k transactions
# given stock prices for n days
  
# Function to find out maximum profit by
# buying & selling a share atmost k times 
# given stock price of n days
def maxProfit(prices, n, k):
      
    # Bottom-up DP approach
    profit = [[0 for i in range(k + 1)]
                 for j in range(n)]
      
    # Profit is zero for the first
    # day and for zero transactions
    for i in range(1, n):
          
        for j in range(1, k + 1):
            max_so_far = 0
              
            for l in range(i):
                max_so_far = max(max_so_far, prices[i] -
                            prices[l] + profit[l][j - 1])
                              
            profit[i][j] = max(profit[i - 1][j], max_so_far)
      
    return profit[n - 1][k]

1672
Chapter 229. Maximum profit by buying and selling a share at most k times

  
# Driver code
k = 2
prices = [10, 22, 5, 75, 65, 80]
n = len(prices)
  
print("Maximum profit is:",
       maxProfit(prices, n, k))
  
# This code is contributed by vaibhav29498

C#

// C# program to find out maximum profit by


// buying and selling a share atmost k times
// given stock price of n days
using System;
  
class GFG {
      
    // Function to find out maximum profit by 
    // buying & selling/ a share atmost k times
    // given stock price of n days
    static int maxProfit(int[] price, int n, int k)
    {
        // table to store results of subproblems
        // profit[t][i] stores maximum profit using atmost
        // t transactions up to day i (including day i)
        int[, ] profit = new int[k + 1, n + 1];
  
        // For day 0, you can't earn money
        // irrespective of how many times you trade
        for (int i = 0; i <= k; i++)
            profit[i, 0] = 0;
  
        // profit is 0 if we don't do any transation
        // (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0, j] = 0;
  
        // fill the table in bottom-up fashion
        for (int i = 1; i <= k; i++) {
            for (int j = 1; j < n; j++) {
                int max_so_far = 0;
  
                for (int m = 0; m < j; m++)
                max_so_far = Math.Max(max_so_far, price[j] -
                               price[m] + profit[i - 1, m]);

1673
Chapter 229. Maximum profit by buying and selling a share at most k times

  
                profit[i, j] = Math.Max(profit[i, j - 1], max_so_far);
            }
        }
  
        return profit[k, n - 1];
    }
  
    // Driver code to test above
    public static void Main()
    {
        int k = 2;
        int[] price = { 10, 22, 5, 75, 65, 80 };
  
        int n = price.Length;
  
        Console.Write("Maximum profit is: " + 
                     maxProfit(price, n, k));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program to find out maximum profit by
// buying and selling a share atmost k times
// given stock price of n days
  
// Function to find out maximum profit by buying
// & selling a share atmost k times given stock
// price of n days
function maxProfit($price, $n, $k)
{
      
    // table to store results of subproblems
    // profit[t][i] stores maximum profit using
    // atmost t transactions up to day i (including
    // day i)
    $profit[$k + 1][$n + 1] = 0;
      
    // For day 0, you can't earn money
    // irrespective of how many times you trade
    for ($i = 0; $i <= $k; $i++)
        $profit[$i][0] = 0;
  
    // profit is 0 if we don't

1674
Chapter 229. Maximum profit by buying and selling a share at most k times

    // do any transation


    // (i.e. k =0)
    for ($j = 0; $j <= $n; $j++)
        $profit[0][$j] = 0;
  
    // fill the table in 
    // bottom-up fashion
    for ($i = 1; $i <= $k; $i++) {
        for ($j = 1; $j < $n; $j++) {
            $max_so_far = PHP_INT_MIN;
  
            for ($m = 0; $m < $j; $m++)
                $max_so_far = max($max_so_far, 
                              $price[$j] - $price[$m] +
                              $profit[$i - 1][$m]);
  
            $profit[$i][$j] = max($profit[$i][$j - 1],
                                         $max_so_far);
        }
    }
  
    return $profit[$k][$n - 1];
}
  
    // Driver code
    $k = 2;
    $price = array (10, 22, 5, 75, 65, 80 );
    $n = sizeof($price);
    echo "Maximum profit is: ". maxProfit($price, $n, $k);
  
// This is contributed by mits
?>

Output :

Maximum profit is: 87

Optimized Solution:
The above solution has time complexity of O(k.n2 ). It can be reduced if we are able to
calculate maximum profit gained by selling shares on ith day in constant time.
profit[t][i] = max(profit [t][i-1], max(price[i] – price[j] + profit[t-1][j]))
for all j in range [0, i-1]
If we carefully notice,
max(price[i] – price[j] + profit[t-1][j])
for all j in range [0, i-1]
can be rewritten as,
= price[i] + max(profit[t-1][j] – price[j])

1675
Chapter 229. Maximum profit by buying and selling a share at most k times

for all j in range [0, i-1]


= price[i] + max(prevDiff, profit[t-1][i-1] – price[i-1])
where prevDiff is max(profit[t-1][j] – price[j])
for all j in range [0, i-2]
So, if we have already calculated max(profit[t-1][j] – price[j]) for all j in range [0, i-2], we
can calculate it for j = i – 1 in constant time. In other words, we don’t have to look back in
range [0, i-1] anymore to find out best day to buy. We can determine that in constant time
using below revised relation.
profit[t][i] = max(profit[t][i-1], price[i] + max(prevDiff, profit [t-1][i-1] – price[i-1])
where prevDiff is max(profit[t-1][j] – price[j]) for all j in range [0, i-2]
Below is its optimized implementation –

C++

// C++ program to find out maximum profit by buying


// and/ selling a share atmost k times given stock
// price of n days
#include <climits>
#include <iostream>
using namespace std;
  
// Function to find out maximum profit by buying &
// selling/ a share atmost k times given stock price
// of n days
int maxProfit(int price[], int n, int k)
{
    // table to store results of subproblems
    // profit[t][i] stores maximum profit using atmost
    // t transactions up to day i (including day i)
    int profit[k + 1][n + 1];
  
    // For day 0, you can't earn money
    // irrespective of how many times you trade
    for (int i = 0; i <= k; i++)
        profit[i][0] = 0;
  
    // profit is 0 if we don't do any transation
    // (i.e. k =0)
    for (int j = 0; j <= n; j++)
        profit[0][j] = 0;
  
    // fill the table in bottom-up fashion
    for (int i = 1; i <= k; i++) {
        int prevDiff = INT_MIN;
        for (int j = 1; j < n; j++) {
            prevDiff = max(prevDiff,

1676
Chapter 229. Maximum profit by buying and selling a share at most k times

                           profit[i - 1][j - 1] - price[j - 1]);


            profit[i][j] = max(profit[i][j - 1],
                               price[j] + prevDiff);
        }
    }
  
    return profit[k][n - 1];
}
  
// Driver Code
int main()
{
    int k = 3;
    int price[] = { 12, 14, 17, 10, 14, 13, 12, 15 };
  
    int n = sizeof(price) / sizeof(price[0]);
  
    cout << "Maximum profit is: "
         << maxProfit(price, n, k);
  
    return 0;
}

Java

// Java program to find out maximum


// profit by buying and selling a
// share atmost k times given stock
// price of n days
import java.io.*;
  
class GFG {
      
    // Function to find out maximum profit by
    // buying & selling/ a share atmost k times 
    // given stock price of n days
    static int maxProfit(int price[], 
                         int n, int k)
    {
          
        // table to store results of subproblems
        // profit[t][i] stores maximum profit
        // using atmost t transactions up to day
        // i (including day i)
        int profit[][] = new int[k + 1][ n + 1];
  
        // For day 0, you can't earn money
        // irrespective of how many times you trade

1677
Chapter 229. Maximum profit by buying and selling a share at most k times

        for (int i = 0; i <= k; i++)


            profit[i][0] = 0;
  
        // profit is 0 if we don't do any 
        // transation (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0][j] = 0;
  
        // fill the table in bottom-up fashion
        for (int i = 1; i <= k; i++) 
        {
            int prevDiff = Integer.MIN_VALUE;
            for (int j = 1; j < n; j++) 
            {
                prevDiff = Math.max(prevDiff, 
                           profit[i - 1][j - 1] - 
                           price[j - 1]);
                profit[i][j] = Math.max(profit[i][j - 1], 
                               price[j] + prevDiff);
            }
        }
  
        return profit[k][n - 1];
    }
  
// Driver code
public static void main (String[] args) 
    {
        int k = 3;
        int price[] = {12, 14, 17, 10, 14, 13, 12, 15};
  
        int n = price.length;
  
        System.out.println("Maximum profit is: " + 
                            maxProfit(price, n, k));
    }

  
// This code is contributed by Sam007

C#

// C# program to find out maximum profit by buying


// and selling a share atmost k times given stock
// price of n days
using System;
  
class GFG {

1678
Chapter 229. Maximum profit by buying and selling a share at most k times

      
    // Function to find out maximum profit by
    // buying & selling/ a share atmost k times 
    // given stock price of n days
    static int maxProfit(int[] price, int n, int k)
    {
        // table to store results of subproblems
        // profit[t][i] stores maximum profit using atmost
        // t transactions up to day i (including day i)
        int[, ] profit = new int[k + 1, n + 1];
  
        // For day 0, you can't earn money
        // irrespective of how many times you trade
        for (int i = 0; i <= k; i++)
            profit[i, 0] = 0;
  
        // profit is 0 if we don't do any transation
        // (i.e. k =0)
        for (int j = 0; j <= n; j++)
            profit[0, j] = 0;
  
        // fill the table in bottom-up fashion
        for (int i = 1; i <= k; i++) {
            int prevDiff = int.MinValue;
            for (int j = 1; j < n; j++) {
            prevDiff = Math.Max(prevDiff,
                            profit[i - 1, j - 1] - price[j - 1]);
            profit[i, j] = Math.Max(profit[i, j - 1],
                                price[j] + prevDiff);
            }
        }
  
        return profit[k, n - 1];
    }
  
    // Driver code to test above
    public static void Main()
    {
        int k = 3;
        int[] price = {12, 14, 17, 10, 14, 13, 12, 15};
  
        int n = price.Length;
  
        Console.Write("Maximum profit is: " + 
                     maxProfit(price, n, k));
    }
}
  

1679
Chapter 229. Maximum profit by buying and selling a share at most k times

// This code is contributed by Sam007

PHP

<?php
// PHP program to find out maximum
// profit by buying and selling a 
// share atmost k times given stock
// price of n days
  
// Function to find out maximum
// profit by buying & selling a 
// share atmost k times given 
// stock price of n days
function maxProfit($price, $n, $k)
{
      
    // table to store results 
    // of subproblems profit[t][i]
    // stores maximum profit using
    // atmost t transactions up to
    // day i (including day i)
    $profit[$k + 1][$n + 1]=0;
  
    // For day 0, you can't 
    // earn money irrespective
    // of how many times you trade
    for ($i = 0; $i <= $k; $i++)
        $profit[$i][0] = 0;
  
    // profit is 0 if we don't
    // do any transation
    // (i.e. k =0)
    for ($j = 0; $j <= $n; $j++)
        $profit[0][$j] = 0;
  
    // fill the table in
    // bottom-up fashion
    $prevDiff = NULL;
    for ($i = 1; $i <= $k; $i++) {
        for ($j = 1; $j < $n; $j++) {
            $prevDiff = max($prevDiff, $profit[$i - 1][$j - 1] - 
                                               $price[$j - 1]);
            $profit[$i][$j] = max($profit[$i][$j - 1],
                              $price[$j] + $prevDiff);
        }
    }
    return $profit[$k][$n - 1];

1680
Chapter 229. Maximum profit by buying and selling a share at most k times

}
  
    // Driver Code
    $k = 3;
    $price = array(12, 14, 17, 10, 
                   14, 13, 12, 15);
    $n = sizeof($price);
    echo "Maximum profit is: "
         , maxProfit($price, $n, $k);
  
// This code is contributed by nitin mittal
?>

Output :

Maximum profit is: 12

Time complexity of above solution is O(kn) and space complexity is O(nk). Space complexity
can further be reduced to O(n) as we uses the result from last transaction. But to make the
article easily readable, we have used O(kn) space.
This article is contributed by Aditya Goel. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : Sam007, Anshul_Aggarwal, nitin mittal, Mithun Kumar, vaibhav29498

Source

https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-k-times/

1681
Chapter 230

Maximum profit by buying and


selling a share at most twice

Maximum profit by buying and selling a share at most twice - GeeksforGeeks


In a daily share trading, a buyer buys shares in the morning and sells it on same day. If the
trader is allowed to make at most 2 transactions in a day, where as second transaction can
only start after first one is complete (Sell->buy->sell->buy). Given stock prices throughout
day, find out maximum profit that a share trader could have made.
Examples:

Input: price[] = {10, 22, 5, 75, 65, 80}


Output: 87
Trader earns 87 as sum of 12 and 75
Buy at price 10, sell at 22, buy at 5 and sell at 80

Input: price[] = {2, 30, 15, 10, 8, 25, 80}


Output: 100
Trader earns 100 as sum of 28 and 72
Buy at price 2, sell at 30, buy at 8 and sell at 80

Input: price[] = {100, 30, 15, 10, 8, 25, 80};


Output: 72
Buy at price 8 and sell at 80.

Input: price[] = {90, 80, 70, 60, 50}


Output: 0
Not possible to earn.

A Simple Solution is to to consider every index ‘i’ and do following

1682
Chapter 230. Maximum profit by buying and selling a share at most twice

Max profit with at most two transactions =


MAX {max profit with one transaction and subarray price[0..i] +
max profit with one transaction and aubarray price[i+1..n-1] }
i varies from 0 to n-1.

Maximum possible using one transaction can be calculated using following O(n) algorithm

Maximum difference between two elements such that larger element appears after the smaller
number
Time complexity of above simple solution is O(n2 ).
We can do this O(n) using following Efficient Solution. The idea is to store maximum
possible profit of every subarray and solve the problem in following two phases.
1) Create a table profit[0..n-1] and initialize all values in it 0.
2) Traverse price[] from right to left and update profit[i] such that profit[i] stores maximum
profit achievable from one transaction in subarray price[i..n-1]
3) Traverse price[] from left to right and update profit[i] such that profit[i] stores maxi-
mum profit such that profit[i] contains maximum achievable profit from two transactions in
subarray price[0..i].
4) Return profit[n-1]
To do step 1, we need to keep track of maximum price from right to left side and to do step
2, we need to keep track of minimum price from left to right. Why we traverse in reverse
directions? The idea is to save space, in second step, we use same array for both purposes,
maximum with 1 transaction and maximum with 2 transactions. After an iteration i, the
array profit[0..i] contains maximum profit with 2 transactions and profit[i+1..n-1] contains
profit with two transactions.
Below are implementations of above idea.
C++

// C++ program to find maximum possible profit with at most


// two transactions
#include<iostream>
using namespace std;
  
// Returns maximum profit with two transactions on a given
// list of stock prices, price[0..n-1]
int maxProfit(int price[], int n)
{
    // Create profit array and initialize it as 0
    int *profit = new int[n];
    for (int i=0; i<n; i++)
        profit[i] = 0;
  

1683
Chapter 230. Maximum profit by buying and selling a share at most twice

    /* Get the maximum profit with only one transaction


       allowed. After this loop, profit[i] contains maximum
       profit from price[i..n-1] using at most one trans. */
    int max_price = price[n-1];
    for (int i=n-2;i>=0;i--)
    {
        // max_price has maximum of price[i..n-1]
        if (price[i] > max_price)
            max_price = price[i];
  
        // we can get profit[i] by taking maximum of:
        // a) previous maximum, i.e., profit[i+1]
        // b) profit by buying at price[i] and selling at
        //    max_price
        profit[i] = max(profit[i+1], max_price-price[i]);
    }
  
    /* Get the maximum profit with two transactions allowed
       After this loop, profit[n-1] contains the result */
    int min_price = price[0];
    for (int i=1; i<n; i++)
    {
        // min_price is minimum price in price[0..i]
        if (price[i] < min_price)
            min_price = price[i];
  
        // Maximum profit is maximum of:
        // a) previous maximum, i.e., profit[i-1]
        // b) (Buy, Sell) at (min_price, price[i]) and add
        //    profit of other trans. stored in profit[i]
        profit[i] = max(profit[i-1], profit[i] +
                                    (price[i]-min_price) );
    }
    int result = profit[n-1];
  
    delete [] profit; // To avoid memory leak
  
    return result;
}
  
// Drive program
int main()
{
    int price[] = {2, 30, 15, 10, 8, 25, 80};
    int n = sizeof(price)/sizeof(price[0]);
    cout << "Maximum Profit = " << maxProfit(price, n);
    return 0;
}

1684
Chapter 230. Maximum profit by buying and selling a share at most twice

Java

class Profit
{
    // Returns maximum profit with two transactions on a given
    // list of stock prices, price[0..n-1]
    static int maxProfit(int price[], int n)
    {
        // Create profit array and initialize it as 0
        int profit[] = new int[n];
        for (int i=0; i<n; i++)
            profit[i] = 0;
       
        /* Get the maximum profit with only one transaction
           allowed. After this loop, profit[i] contains maximum
           profit from price[i..n-1] using at most one trans. */
        int max_price = price[n-1];
        for (int i=n-2;i>=0;i--)
        {
            // max_price has maximum of price[i..n-1]
            if (price[i] > max_price)
                max_price = price[i];
       
            // we can get profit[i] by taking maximum of:
            // a) previous maximum, i.e., profit[i+1]
            // b) profit by buying at price[i] and selling at
            //    max_price
            profit[i] = Math.max(profit[i+1], max_price-price[i]);
        }
       
        /* Get the maximum profit with two transactions allowed
           After this loop, profit[n-1] contains the result */
        int min_price = price[0];
        for (int i=1; i<n; i++)
        {
            // min_price is minimum price in price[0..i]
            if (price[i] < min_price)
                min_price = price[i];
       
            // Maximum profit is maximum of:
            // a) previous maximum, i.e., profit[i-1]
            // b) (Buy, Sell) at (min_price, price[i]) and add
            //    profit of other trans. stored in profit[i]
            profit[i] = Math.max(profit[i-1], profit[i] +
                                        (price[i]-min_price) );
        }
        int result = profit[n-1];
        return result;

1685
Chapter 230. Maximum profit by buying and selling a share at most twice

    }
  
  
    public static void main(String args[])
    {
        int price[] = {2, 30, 15, 10, 8, 25, 80};
        int n = price.length;
        System.out.println("Maximum Profit = "+ maxProfit(price, n));
    }
  
}/* This code is contributed by Rajat Mishra */

Python

# Returns maximum profit with two transactions on a given 


# list of stock prices price[0..n-1]
def maxProfit(price,n):
      
    # Create profit array and initialize it as 0
    profit = [0]*n
      
    # Get the maximum profit with only one transaction
    # allowed. After this loop, profit[i] contains maximum
    # profit from price[i..n-1] using at most one trans.
    max_price=price[n-1]
      
    for i in range( n-2, 0 ,-1):
          
        if price[i]> max_price:
            max_price = price[i]
              
        # we can get profit[i] by taking maximum of:
        # a) previous maximum, i.e., profit[i+1]
        # b) profit by buying at price[i] and selling at
        #    max_price
        profit[i] = max(profit[i+1], max_price - price[i])
          
    # Get the maximum profit with two transactions allowed
    # After this loop, profit[n-1] contains the result    
    min_price=price[0]
      
    for i in range(1,n):
          
        if price[i] < min_price:
            min_price = price[i]
  
        # Maximum profit is maximum of:
        # a) previous maximum, i.e., profit[i-1]

1686
Chapter 230. Maximum profit by buying and selling a share at most twice

        # b) (Buy, Sell) at (min_price, A[i]) and add


        #    profit of other trans. stored in profit[i]    
        profit[i] = max(profit[i-1], profit[i]+(price[i]-min_price))
          
    result = profit[n-1]
      
    return result
  
# Driver function
price = [2, 30, 15, 10, 8, 25, 80]
print "Maximum profit is", maxProfit(price, len(price))
  
# This code is contributed by __Devesh Agrawal__

C#

// C# program to find maximum possible profit


// with at most two transactions
using System;
  
class GFG {
      
    // Returns maximum profit with two
    // transactions on a given list of 
    // stock prices, price[0..n-1]
    static int maxProfit(int []price, int n)
    {
          
        // Create profit array and initialize
        // it as 0
        int []profit = new int[n];
        for (int i = 0; i < n; i++)
            profit[i] = 0;
      
        /* Get the maximum profit with only
        one transaction allowed. After this 
        loop, profit[i] contains maximum
        profit from price[i..n-1] using at
        most one trans. */
        int max_price = price[n-1];
          
        for (int i = n-2; i >= 0; i--)
        {
              
            // max_price has maximum of
            // price[i..n-1]
            if (price[i] > max_price)
                max_price = price[i];

1687
Chapter 230. Maximum profit by buying and selling a share at most twice

      
            // we can get profit[i] by taking 
            // maximum of:
            // a) previous maximum, i.e., 
            // profit[i+1]
            // b) profit by buying at price[i]
            // and selling at max_price
            profit[i] = Math.Max(profit[i+1], 
                          max_price - price[i]);
        }
      
        /* Get the maximum profit with two
        transactions allowed After this loop,
        profit[n-1] contains the result */
        int min_price = price[0];
          
        for (int i = 1; i < n; i++)
        {
              
            // min_price is minimum price in
            // price[0..i]
            if (price[i] < min_price)
                min_price = price[i];
      
            // Maximum profit is maximum of:
            // a) previous maximum, i.e.,
            // profit[i-1]
            // b) (Buy, Sell) at (min_price,
            // price[i]) and add profit of 
            // other trans. stored in
            // profit[i]
            profit[i] = Math.Max(profit[i-1],
                       profit[i] + (price[i]
                              - min_price) );
        }
        int result = profit[n-1];
          
        return result;
    }
  
  
    public static void Main()
    {
        int []price = {2, 30, 15, 10,
                                  8, 25, 80};
        int n = price.Length;
          
        Console.Write("Maximum Profit = "

1688
Chapter 230. Maximum profit by buying and selling a share at most twice

                      + maxProfit(price, n));


    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to find maximum 
// possible profit with at most 
// two transactions
  
// Returns maximum profit with 
// two transactions on a given 
// list of stock prices, price[0..n-1] 
function maxProfit($price, $n) 
{
    // Create profit array and
    // initialize it as 0 
    $profit = array(); 
    for ($i = 0; $i < $n; $i++) 
        $profit[$i] = 0; 
  
    // Get the maximum profit with 
    // only one transaction allowed.
    // After this loop, profit[i]
    // contains maximum profit from 
    // price[i..n-1] using at most 
    // one trans. 
    $max_price = $price[$n - 1]; 
    for ($i = $n - 2; $i >= 0; $i--) 
    { 
        // max_price has maximum 
        // of price[i..n-1] 
        if ($price[$i] > $max_price) 
            $max_price = $price[$i]; 
  
        // we can get profit[i] by 
        // taking maximum of: 
        // a) previous maximum, 
        //    i.e., profit[i+1] 
        // b) profit by buying at 
        // price[i] and selling at 
        // max_price 
        if($profit[$i + 1] >
           $max_price-$price[$i])
        $profit[$i] = $profit[$i + 1]; 

1689
Chapter 230. Maximum profit by buying and selling a share at most twice

        else
        $profit[$i] = $max_price -
                      $price[$i];
    } 
  
    // Get the maximum profit with 
    // two transactions allowed. 
    // After this loop, profit[n-1] 
    // contains the result 
    $min_price = $price[0]; 
    for ($i = 1; $i < $n; $i++) 
    { 
        // min_price is minimum 
        // price in price[0..i] 
        if ($price[$i] < $min_price) 
            $min_price = $price[$i]; 
  
        // Maximum profit is maximum of: 
        // a) previous maximum, 
        //    i.e., profit[i-1] 
        // b) (Buy, Sell) at (min_price, 
        //     price[i]) and add 
        // profit of other trans. 
        // stored in profit[i] 
        $profit[$i] = max($profit[$i - 1], 
                          $profit[$i] + 
                         ($price[$i] - $min_price)); 
    } 
    $result = $profit[$n - 1]; 
    return $result; 
}
  
// Drive Code 
$price = array(2, 30, 15, 10,
               8, 25, 80); 
$n = sizeof($price); 
echo "Maximum Profit = ". 
      maxProfit($price, $n); 
      
// This code is contributed
// by Arnab Kundu
?>

Output:

Maximum Profit = 100

Time complexity of the above solution is O(n).

1690
Chapter 230. Maximum profit by buying and selling a share at most twice

Algorithmic Paradigm: Dynamic Programming


This article is contributed by Amit Jaiswal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : nitin mittal, andrew1234

Source

https://www.geeksforgeeks.org/maximum-profit-by-buying-and-selling-a-share-at-most-twice/

1691
Chapter 231

Maximum profit from sale of


wines

Maximum profit from sale of wines - GeeksforGeeks


Given n wines in a row, with integers denoting the cost of each wine respectively. Each year
you can sale the first or the last wine in the row. However, the price of wines increases over
time. Let the initial profits from the wines be P1, P2, P3…Pn. On the Yth year, the profit
from the ith wine will be Y*Pi. For each year, your task is to print “beg” or “end” denoting
whether first or last wine should be sold. Also, calculate the maximum profit from all the
wines.
Examples :

Input: Price of wines: 2 4 6 2 5


Output: beg end end beg beg
64
Explanation :

Approach : It is a standard Dynamic Programming problem. It initially looks like a greedy


problem in which we should sell the cheaper of the wines each year but the example case
(year 2) clearly proves the approach is wrong. Sometimes we need to sell an expensive wine
earlier to save relatively costly wines for later years (Here, if 4 was sold in the 2nd year, in
the 4th year we had to sell 2 which would be waste of a heavy coefficient).
The second problem is to “store the strategy” to obtain the calculated price which has a
fairly standard method that can be used in other problems as well. The idea is to store the
optimal action for each state and use that to navigate through the optimal states starting
from the initial state.

C++

1692
Chapter 231. Maximum profit from sale of wines

// Program to calculate maximum price of wines


#include <bits/stdc++.h>
using namespace std;
  
#define N 1000
  
int dp[N][N];
  
// This array stores the "optimal action"
// for each state i, j
int sell[N][N];
  
// Function to maximize profit
int maxProfitUtil(int price[], int begin,
                  int end, int n) {
    if (dp[begin][end] != -1)
        return dp[begin][end];
  
    int year = n - (end - begin);
  
    if (begin == end) 
        return year * price[begin];    
  
    // x = maximum profit on selling the
    // wine from the front this year
    int x = price[begin] * year + 
            maxProfitUtil(price, begin + 1, end, n);
  
    // y = maximum profit on selling the
    // wine from the end this year
    int y = price[end] * year + 
            maxProfitUtil(price, begin, end - 1, n);
  
    int ans = max(x, y);
    dp[begin][end] = ans;
  
    if (x >= y)
        sell[begin][end] = 0;
    else
        sell[begin][end] = 1;
  
    return ans;
}
  
// Util Function to calculate maxProfit
int maxProfit(int price[], int n) {
    // reseting the dp table
    for (int i = 0; i < N; i++)

1693
Chapter 231. Maximum profit from sale of wines

        for (int j = 0; j < N; j++)


            dp[i][j] = -1;
  
    int ans = maxProfitUtil(price, 0, n - 1, n);
  
    int i = 0, j = n - 1;
  
    while (i <= j) {
        // sell[i][j]=0 implies selling the
        // wine from beginning will be more
        // profitable in the long run
        if (sell[i][j] == 0) {
            cout << "beg ";
            i++;
        }  else {
            cout << "end ";
            j--;
        }
    }
  
    cout << endl;
  
    return ans;
}
  
// Driver code
int main() {
    // Price array
    int price[] = { 2, 4, 6, 2, 5 };
  
    int n = sizeof(price) / sizeof(price[0]);
  
    int ans = maxProfit(price, n);
  
    cout << ans << endl;
  
    return 0;
}

Java

// Program to calculate maximum price of wines


import java.io.*;
  
class GFG {
      
    static int N = 1000;
      

1694
Chapter 231. Maximum profit from sale of wines

    static int [][]dp = new int[N][N];


      
    // This array stores the "optimal action"
    // for each state i, j
    static int [][]sell = new int[N][N];
      
    // Function to maximize profit
    static int maxProfitUtil(int price[],
                   int begin, int end, int n)
    {
        if (dp[begin][end] != -1)
            return dp[begin][end];
      
        int year = n - (end - begin);
      
        if (begin == end) 
            return year * price[begin]; 
      
        // x = maximum profit on selling the
        // wine from the front this year
        int x = price[begin] * year + 
                maxProfitUtil(price, begin + 1,
                                       end, n);
      
        // y = maximum profit on selling the
        // wine from the end this year
        int y = price[end] * year + 
                maxProfitUtil(price, begin, 
                                  end - 1, n);
      
        int ans = Math.max(x, y);
        dp[begin][end] = ans;
      
        if (x >= y)
            sell[begin][end] = 0;
        else
            sell[begin][end] = 1;
      
        return ans;
    }
      
    // Util Function to calculate maxProfit
    static int maxProfit(int price[], int n)
    {
          
        // reseting the dp table
        for (int i = 0; i < N; i++)
            for (int j = 0; j < N; j++)

1695
Chapter 231. Maximum profit from sale of wines

                dp[i][j] = -1;
      
        int ans = maxProfitUtil(price, 0, 
                                  n - 1, n);
      
        int i = 0, j = n - 1;
      
        while (i <= j) {
      
            // sell[i][j]=0 implies selling
            // the wine from beginning will
            // be more profitable in the 
            // long run
            if(sell[i][j] == 0){
                System.out.print( "beg ");
                i++;
            }
            else
            {
                System.out.print( "end ");
                j--;
            }
        }
      
        System.out.println();
      
        return ans;
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        // Price array
        int price[] = { 2, 4, 6, 2, 5 };
      
        int n = price.length;
      
        int ans = maxProfit(price, n);
      
        System.out.println( ans );
    }
}
  
// This code is contributed by anuj_67.

C#

// C# Program to calculate maximum

1696
Chapter 231. Maximum profit from sale of wines

// price of wines
using System;
class GFG {
      
    static int N = 1000;
    static int [,]dp = new int[N, N];
      
    // This array stores the "optimal action"
    // for each state i, j
    static int [,]sell = new int[N,N];
      
    // Function to maximize profit
    static int maxProfitUtil(int []price,
               int begin, int end, int n) 
    {
        if (dp[begin,end] != -1)
            return dp[begin,end];
      
        int year = n - (end - begin);
      
        if (begin == end) 
            return year * price[begin]; 
      
        // x = maximum profit on selling the
        // wine from the front this year
        int x = price[begin] * year + 
                maxProfitUtil(price, begin + 1,
                                       end, n);
      
        // y = maximum profit on selling the
        // wine from the end this year
        int y = price[end] * year + 
                maxProfitUtil(price, begin, 
                                end - 1, n);
      
        int ans = Math.Max(x, y);
        dp[begin,end] = ans;
      
        if (x >= y)
            sell[begin,end] = 0;
        else
            sell[begin,end] = 1;
      
        return ans;
    }
      
    // Util Function to calculate maxProfit
    static int maxProfit(int []price, int n)

1697
Chapter 231. Maximum profit from sale of wines

    {
        int i, j;
           
        // reseting the dp table
        for(i = 0; i < N; i++)
            for(j = 0; j < N; j++)
                dp[i, j] = -1;
      
        int ans = maxProfitUtil(price, 0, 
                                n - 1, n);
      
        i = 0; j = n - 1;
      
        while (i <= j) {
      
            // sell[i][j]=0 implies selling
            // the wine from beginning will
            // be more profitable in the 
            // long run
            if(sell[i, j] == 0){
                Console.Write( "beg ");
                i++;
            }
            else
            {
                Console.Write( "end ");
                j--;
            }
        }
      
    Console.WriteLine();
      
        return ans;
    }
      
    // Driver Code
    public static void Main () 
    {
  
        // Price array
        int []price = {2, 4, 6, 2, 5};
        int n = price.Length;
        int ans = maxProfit(price, n);
        Console.WriteLine( ans );
    }
}
  
// This code is contributed by anuj_67.

1698
Chapter 231. Maximum profit from sale of wines

Output:

beg end end beg beg


64

Time Complexity: O(n2 )


Improved By : vt_m, ASHUTOSH_GUPTA

Source

https://www.geeksforgeeks.org/maximum-profit-sale-wines/

1699
Chapter 232

Maximum size square


sub-matrix with all 1s

Maximum size square sub-matrix with all 1s - GeeksforGeeks


Given a binary matrix, find out the maximum size square sub-matrix with all 1s.
For example, consider the below binary matrix.

Algorithm:
Let the given binary matrix be M[R][C]. The idea of the algorithm is to construct an auxiliary
size matrix S[][] in which each entry S[i][j] represents size of the square sub-matrix with all
1s including M[i][j] where M[i][j] is the rightmost and bottommost entry in sub-matrix.

1) Construct a sum matrix S[R][C] for the given M[R][C].


a) Copy first row and first columns as it is from M[][] to S[][]
b) For other entries, use following expressions to construct S[][]
If M[i][j] is 1 then
S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1
Else /*If M[i][j] is 0*/
S[i][j] = 0
2) Find the maximum entry in S[R][C]
3) Using the value and coordinates of maximum entry in S[i], print

1700
Chapter 232. Maximum size square sub-matrix with all 1s

sub-matrix of M[][]

For the given M[R][C] in above example, constructed S[R][C] would be:

0 1 1 0 1
1 1 0 1 0
0 1 1 1 0
1 1 2 2 0
1 2 2 3 1
0 0 0 0 0

The value of maximum entry in above matrix is 3 and coordinates of the entry are (4, 3).
Using the maximum value and its coordinates, we can find out the required sub-matrix.
C/C++

// C/C++ code for Maximum size square sub-matrix with all 1s


#include<stdio.h>
#define bool int
#define R 6
#define C 5
  
void printMaxSubSquare(bool M[R][C])
{
  int i,j;
  int S[R][C];
  int max_of_s, max_i, max_j; 
   
  /* Set first column of S[][]*/
  for(i = 0; i < R; i++)
     S[i][0] = M[i][0];
   
  /* Set first row of S[][]*/     
  for(j = 0; j < C; j++)
     S[0][j] = M[0][j];
       
  /* Construct other entries of S[][]*/
  for(i = 1; i < R; i++)
  {
    for(j = 1; j < C; j++)
    {
      if(M[i][j] == 1) 
        S[i][j] = min(S[i][j-1], S[i-1][j], S[i-1][j-1]) + 1;
      else
        S[i][j] = 0;
    }    
  } 

1701
Chapter 232. Maximum size square sub-matrix with all 1s

    
  /* Find the maximum entry, and indexes of maximum entry 
     in S[][] */
  max_of_s = S[0][0]; max_i = 0; max_j = 0;
  for(i = 0; i < R; i++)
  {
    for(j = 0; j < C; j++)
    {
      if(max_of_s < S[i][j])
      {
         max_of_s = S[i][j];
         max_i = i; 
         max_j = j;
      }        
    }                 
  }     
    
  printf("Maximum size sub-matrix is: \n");
  for(i = max_i; i > max_i - max_of_s; i--)
  {
    for(j = max_j; j > max_j - max_of_s; j--)
    {
      printf("%d ", M[i][j]);
    }  
    printf("\n");
  }  
}     
  
/* UTILITY FUNCTIONS */
/* Function to get minimum of three values */
int min(int a, int b, int c)
{
  int m = a;
  if (m > b) 
    m = b;
  if (m > c) 
    m = c;
  return m;
}
  
/* Driver function to test above functions */
int main()
{
  bool M[R][C] =  {{0, 1, 1, 0, 1}, 
                   {1, 1, 0, 1, 0}, 
                   {0, 1, 1, 1, 0},
                   {1, 1, 1, 1, 0},
                   {1, 1, 1, 1, 1},

1702
Chapter 232. Maximum size square sub-matrix with all 1s

                   {0, 0, 0, 0, 0}};
                 
  printMaxSubSquare(M);
  getchar();  
}  

Java

// JAVA Code for Maximum size square sub-matrix with all 1s


public class GFG
{
    // method for Maximum size square sub-matrix with all 1s
    static void printMaxSubSquare(int M[][])
    {
        int i,j;
        int R = M.length;         //no of rows in M[][]
        int C = M[0].length;     //no of columns in M[][]
        int S[][] = new int[R][C];     
          
        int max_of_s, max_i, max_j; 
        
        /* Set first column of S[][]*/
        for(i = 0; i < R; i++)
            S[i][0] = M[i][0];
        
        /* Set first row of S[][]*/    
        for(j = 0; j < C; j++)
            S[0][j] = M[0][j];
            
        /* Construct other entries of S[][]*/
        for(i = 1; i < R; i++)
        {
            for(j = 1; j < C; j++)
            {
                if(M[i][j] == 1) 
                    S[i][j] = Math.min(S[i][j-1],Math.min(S[i-1][j], S[i-1][j-1])) + 1;
                else
                    S[i][j] = 0;
            }    
        }     
         
        /* Find the maximum entry, and indexes of maximum entry 
             in S[][] */
        max_of_s = S[0][0]; max_i = 0; max_j = 0;
        for(i = 0; i < R; i++)
        {
            for(j = 0; j < C; j++)
            {

1703
Chapter 232. Maximum size square sub-matrix with all 1s

                if(max_of_s < S[i][j])


                {
                    max_of_s = S[i][j];
                    max_i = i; 
                    max_j = j;
                }        
            }                 
        }     
         
        System.out.println("Maximum size sub-matrix is: ");
        for(i = max_i; i > max_i - max_of_s; i--)
        {
            for(j = max_j; j > max_j - max_of_s; j--)
            {
                System.out.print(M[i][j] + " ");
            }  
            System.out.println();
        }  
    }    
      
    // Driver program 
    public static void main(String[] args) 
    {
        int M[][] =  {{0, 1, 1, 0, 1}, 
                      {1, 1, 0, 1, 0}, 
                      {0, 1, 1, 1, 0},
                      {1, 1, 1, 1, 0},
                      {1, 1, 1, 1, 1},
                      {0, 0, 0, 0, 0}};
               
        printMaxSubSquare(M);
    }
  
}

Python3

# Python3 code for Maximum size


# square sub-matrix with all 1s
  
def printMaxSubSquare(M):
    R = len(M) # no. of rows in M[][]
    C = len(M[0]) # no. of columns in M[][]
  
    S = [[0 for k in range(C)] for l in range(R)]
    # here we have set the first row and column of S[][]
  
    # Construct other entries

1704
Chapter 232. Maximum size square sub-matrix with all 1s

    for i in range(1, R):


        for j in range(1, C):
            if (M[i][j] == 1):
                S[i][j] = min(S[i][j-1], S[i-1][j],
                            S[i-1][j-1]) + 1
            else:
                S[i][j] = 0
      
    # Find the maximum entry and
    # indices of maximum entry in S[][]
    max_of_s = S[0][0]
    max_i = 0
    max_j = 0
    for i in range(R):
        for j in range(C):
            if (max_of_s < S[i][j]):
                max_of_s = S[i][j]
                max_i = i
                max_j = j
  
    print("Maximum size sub-matrix is: ")
    for i in range(max_i, max_i - max_of_s, -1):
        for j in range(max_j, max_j - max_of_s, -1):
            print (M[i][j], end = " ")
        print("")
  
# Driver Program
M = [[0, 1, 1, 0, 1],
    [1, 1, 0, 1, 0],
    [0, 1, 1, 1, 0],
    [1, 1, 1, 1, 0],
    [1, 1, 1, 1, 1],
    [0, 0, 0, 0, 0]]
  
printMaxSubSquare(M)
  
# This code is contributed by Soumen Ghosh

Output:

Maximum size sub-matrix is:


1 1 1
1 1 1
1 1 1

Time Complexity: O(m*n) where m is number of rows and n is number of columns in the
given matrix.

1705
Chapter 232. Maximum size square sub-matrix with all 1s

Auxiliary Space: O(m*n) where m is number of rows and n is number of columns in the
given matrix.
Algorithmic Paradigm: Dynamic Programming

Source

https://www.geeksforgeeks.org/maximum-size-sub-matrix-with-all-1s-in-a-binary-matrix/

1706
Chapter 233

Maximum size subset with


given sum

Maximum size subset with given sum - GeeksforGeeks


This is an extended version of subset sum problem. Here we need to find size of maximum
size subset whose sum is equal to given sum.
Examples:

Input : set[] = {2, 3, 5, 7, 10, 15},


sum = 10
Output : 3
The largest sized subset with sum 10
is {2, 3, 5}

Input : set[] = {1, 2, 3, 4, 5}


sum = 4
Output : 2

This is the further enhancement to subset sum problem which not only tells whether the
subset is possible but also the maximal subset using DP.
To solve the subset sum problem, use the same DP approach as given in subset sum problem.
To further count the maximal subset, we use another DP array (called as ‘count array’) where
count[i][j] is maximal of

• count[i][j-1]. Here current element is not considered.


• count[i- X][j-1] + 1. Here X is value of the current element selected for subset.

Java

1707
Chapter 233. Maximum size subset with given sum

// A Dynamic Programming solution for subset 


// sum problem+ maximal subset value.
class sumofSub {
  
    // Returns size of maximum sized subset if there
    // is a subset of set[] with sun equal to given sum.
    // It returns -1 if there is no subset with given sum.
    static int isSubsetSum(int set[], int n, int sum)
    {
        // The value of subset[i][j] will be true if there
        // is a subset of set[0..j-1] with sum equal to i
        boolean subset[][] = new boolean[sum + 1][n + 1];
        int count[][] = new int[sum + 1][n + 1];
  
        // If sum is 0, then answer is true
        for (int i = 0; i <= n; i++) {
            subset[0][i] = true;
            count[0][i] = 0;
        }
  
        // If sum is not 0 and set is empty,
        // then answer is false
        for (int i = 1; i <= sum; i++) {
            subset[i][0] = false;
            count[i][0] = -1;
        }
  
        // Fill the subset table in bottom up manner
        for (int i = 1; i <= sum; i++) {
            for (int j = 1; j <= n; j++) {
                subset[i][j] = subset[i][j - 1];
                count[i][j] = count[i][j - 1];
                if (i >= set[j - 1]) {
                    subset[i][j] = subset[i][j] || 
                       subset[i - set[j - 1]][j - 1];
  
                    if (subset[i][j])
                        count[i][j] = Math.max(count[i][j - 1],
                             count[i - set[j - 1]][j - 1] + 1);
                }
            }
        }
  
        return count[sum][n];
    }
  
    /* Driver program to test above function */
    public static void main(String args[])

1708
Chapter 233. Maximum size subset with given sum

    {
        int set[] = { 2, 3, 5, 10 };
        int sum = 20;
        int n = set.length;
        System.out.println(isSubsetSum(set, n, sum));
    }
}

C#

// A Dynamic Programming solution for subset


// sum problem+ maximal subset value.
using System;
  
class sumofSub {
  
    // Returns size of maximum sized subset 
    // if there is a subset of set[] with sun 
    // equal to given sum. It returns -1 if there
    // is no subset with given sum.
    static int isSubsetSum(int[] set, int n, int sum)
    {
        // The value of subset[i][j] will be true if there
        // is a subset of set[0..j-1] with sum equal to i
        bool[, ] subset = new bool[sum + 1, n + 1];
        int[, ] count = new int[sum + 1, n + 1];
  
        // If sum is 0, then answer is true
        for (int i = 0; i <= n; i++) {
            subset[0, i] = true;
            count[0, i] = 0;
        }
  
        // If sum is not 0 and set is empty,
        // then answer is false
        for (int i = 1; i <= sum; i++) {
            subset[i, 0] = false;
            count[i, 0] = -1;
        }
  
        // Fill the subset table in bottom up manner
        for (int i = 1; i <= sum; i++) {
            for (int j = 1; j <= n; j++) {
                subset[i, j] = subset[i, j - 1];
                count[i, j] = count[i, j - 1];
                if (i >= set[j - 1]) {
                    subset[i, j] = subset[i, j] || 
                                   subset[i - set[j - 1], j - 1];

1709
Chapter 233. Maximum size subset with given sum

  
                    if (subset[i, j])
                        count[i, j] = Math.Max(count[i, j - 1],
                                      count[i - set[j - 1], j - 1] + 1);
                }
            }
        }
  
        return count[sum, n];
    }
  
    /* Driver program to test above function */
    public static void Main()
    {
        int[] set = { 2, 3, 5, 10 };
        int sum = 20;
        int n = set.Length;
        Console.WriteLine(isSubsetSum(set, n, sum));
    }
}
  
// This code is contributed by vt_m.

Output:

Time complexity of the above solution is O(sum*n).

Source

https://www.geeksforgeeks.org/maximum-size-subset-given-sum/

1710
Chapter 234

Maximum sub-matrix area


having count of 1’s one more
than count of 0’s

Maximum sub-matrix area having count of 1’s one more than count of 0’s - GeeksforGeeks
Given a N x N binary matrix. The problem is finding the maximum area sub-matrix having
a count of 1’s one more than count of 0’s.
Examples:

Input : mat[][] = { {1, 0, 0, 1},


{0, 1, 1, 1},
{1, 0, 0, 0},
{0, 1, 0, 1} }
Output : 9
The sub-matrix defined by the boundary values (1, 1) and (3, 3).
{ {1, 0, 0, 1},
{0, 1, 1, 1},
{1, 0, 0, 0},
{0, 1, 0, 1} }

Naive Approach: Check every possible rectangle in given 2D matrix. This solution re-
quires 4 nested loops and the time complexity of this solution would be O(n^4).
Efficient Approach: An efficient approach will be to use Longest subarray having count
of 1s one more than count of 0s which reduces the time complexity to O(n^3). The idea is
to fix the left and right columns one by one and find the maximum length contiguous rows
having the count of 1’s one more than the count of 0’s for every left and right column pair.
Find top and bottom row numbers (which have a maximum length) for every fixed left and
right column pair. To find the top and bottom row numbers, calculate the sum of elements

1711
Chapter 234. Maximum sub-matrix area having count of 1’s one more than count of 0’s

in every row from left to right and store these sums in an array say temp[] (consider 0 as -1
while adding it). So temp[i] indicates the sum of elements from left to right in row i. Using
the approach in Longest subarray having count of 1s one more than count of 0s , temp[]
array is used to get the maximum length subarray of temp[] having count of 1’s one more
than a count of 0’s by obtaining the start and end row numbers, then these values can be
used to find maximum possible area with left and right as boundary columns. To get the
overall maximum area, compare this area with the maximum area so far.
Below is the implementation of the above approach:

// C++ implementation to find


// the maximum area sub-matrix
// having count of 1's
// one more than count of 0's
#include <bits/stdc++.h>
  
using namespace std;
  
#define SIZE 10
  
// function to find the length of longest
// subarray having count of 1's one more
// than count of 0's
int lenOfLongSubarr(int arr[], int n,
                    int& start, int& finish)
{
    // unordered_map 'um' implemented as
    // hash table
    unordered_map<int, int> um;
    int sum = 0, maxLen = 0;
  
    // traverse the given array
    for (int i = 0; i < n; i++) {
  
        // accumulating sum
        sum += arr[i];
  
        // when subarray starts form index '0'
        if (sum == 1) {
            start = 0;
            finish = i;
            maxLen = i + 1;
        }
  
        // make an entry for 'sum' if it is
        // not present in 'um'
        else if (um.find(sum) == um.end())
            um[sum] = i;
  

1712
Chapter 234. Maximum sub-matrix area having count of 1’s one more than count of 0’s

        // check if 'sum-1' is present in 'um'


        // or not
        if (um.find(sum - 1) != um.end()) {
  
            // update 'start', 'finish'
            // and maxLength
            if (maxLen < (i - um[sum - 1]))
                start = um[sum - 1] + 1;
            finish = i;
            maxLen = i - um[sum - 1];
        }
    }
  
    // required maximum length
    return maxLen;
}
  
// function to find the maximum
// area sub-matrix having
// count of 1's one more than count of 0's
void largestSubmatrix(int mat[SIZE][SIZE], int n)
{
    // variables to store final
    // and intermediate results
    int finalLeft, finalRight, finalTop, finalBottom;
    int temp[n], maxArea = 0, len, start, finish;
  
    // set the left column
    for (int left = 0; left < n; left++) {
  
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
  
        // Set the right column for the
        // left column set by outer loop
        for (int right = left; right < n; right++) {
  
            // Calculate sum between current left and right
            // for every row 'i', consider '0' as '-1'
            for (int i = 0; i < n; ++i)
                temp[i] += mat[i][right] == 0 ? -1 : 1;
  
            // function to set the 'start' and 'finish'
            // variables having index values of
            // temp[] which contains the longest
            // subarray of temp[] having count of 1's
            // one more than count of 0's
            len = lenOfLongSubarr(temp, n, start, finish);

1713
Chapter 234. Maximum sub-matrix area having count of 1’s one more than count of 0’s

  
            // Compare with maximum area
            // so far and accordingly update the
            // final variables
            if ((len != 0) && (maxArea < (finish - start + 1)
                                             * (right - left + 1))) {
                finalLeft = left;
                finalRight = right;
                finalTop = start;
                finalBottom = finish;
                maxArea = (finish - start + 1) * (right - left + 1);
            }
        }
    }
  
    // Print final values
    cout << "(Top, Left): (" << finalTop << ", "
         << finalLeft << ")\n";
  
    cout << "(Bottom, Right): (" << finalBottom << ", "
         << finalRight << ")\n";
  
    cout << "Maximum area: " << maxArea;
}
  
// Driver Code
int main()
{
    int mat[SIZE][SIZE] = { { 1, 0, 0, 1 },
                            { 0, 1, 1, 1 },
                            { 1, 0, 0, 0 },
                            { 0, 1, 0, 1 } };
    int n = 4;
    largestSubmatrix(mat, n);
    return 0;
}

Output:

(Top, Left): (1, 1)


(Bottom, Right): (3, 3)
Maximum area: 9

Time Complexity: O(N3 ).


Auxiliary Space: O(N).

1714
Chapter 234. Maximum sub-matrix area having count of 1’s one more than count of 0’s

Source

https://www.geeksforgeeks.org/maximum-sub-matrix-area-having-count-of-1s-one-more-than-count-of-0s/

1715
Chapter 235

Maximum subarray sum in O(n)


using prefix sum

Maximum subarray sum in O(n) using prefix sum - GeeksforGeeks


Given an Array of Positive and Negative Integers, find out the Maximum Subarray Sum in
that Array.

Examples:

Input1 : arr = {-2, -3, 4, -1, -2, 1, 5, -3}


Output1 : 7

Input2 : arr = {4, -8, 9, -4, 1, -8, -1, 6}


Output2 : 9

Kadane’s Algorithm solves this problem using Dynamic Programming approach in linear
time. Here is another approach using Dynamic Programming and Prefix Sum to find out
maximum subarray sum in Linear time.
Prerequisite: Prefix Sum Array

1. First calculate the prefix sum (prefix_sum) of the input array.


2. Sum of a subarray from index x to y can be presented as,

1716
Chapter 235. Maximum subarray sum in O(n) using prefix sum

3. Now maximum of these subarrays is,

That is, we keep track of minimum prefix sum for x <= y and maximum
subarray sum so far.

Implementation:
1. Calculate the prefix sum of the input array.
2. Initialize : min_prefix_sum = 0, res = -infinite
3. Maintain a loop for i = 0 to n. (n is the size of the input array).
a) cand = prefix_sum[i] – mini
b) If cand is greater than res (maximum subarray sum so far), then update res by cand.
c) If prefix_sum[i] is less than min_prefix_sum (minimum prefix sum so far), then
update min_prefix_sum by prefix_sum[i].
4. Return res.
Reference: Algorithms for the problem of k maximum sums and a VLSI algorithm for the
k maximum subarrays problem
C++

// C++ program to find out maximum subarray


// sum in linear time using prefix sum.
#include <iostream>
#include <limits>
using namespace std;
  
// Function to compute maximum subarray
// sum in linear time.
int maximumSumSubarray(int arr[], int n)
{
    // Initialize minimum prefix sum to 0.
    int min_prefix_sum = 0;
  

1717
Chapter 235. Maximum subarray sum in O(n) using prefix sum

    // Initialize maximum subarray sum so 


    // far to -infinity.
    int res = numeric_limits<int>::min();
  
    // Initialize and compute the prefix 
    // sum array.
    int prefix_sum[n];
    prefix_sum[0] = arr[0];
    for (int i = 1; i < n; i++) 
        prefix_sum[i] = prefix_sum[i - 1] + arr[i];        
  
    // loop through the array, keep track
    // of minimum prefix sum so far and
    // maximum subarray sum.
    for (int i = 0; i < n; i++) {
        res = max(res, prefix_sum[i] - 
                       min_prefix_sum);
        min_prefix_sum = min(min_prefix_sum, 
                             prefix_sum[i]);
    }
      
    return res;
}
  
// Driver Program
int main()
{
    // Test case 1
    int arr1[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
    int n1 = sizeof(arr1) / sizeof(arr1[0]);
    cout << maximumSumSubarray(arr1, n1) << endl;
  
    // Test case 2
    int arr2[] = { 4, -8, 9, -4, 1, -8, -1, 6 };
    int n2 = sizeof(arr2) / sizeof(arr2[0]);
    cout << maximumSumSubarray(arr2, n2);
  
    return 0;
}

Java

// Java program to find 


// out maximum subarray
// sum in linear time 
// using prefix sum.
  
class GFG 

1718
Chapter 235. Maximum subarray sum in O(n) using prefix sum

{
    // Function to compute maximum 
    // subarray sum in linear time.
    static int maximumSumSubarray(int arr[], int n)
    {
        // Initialize minimum 
        // prefix sum to 0.
        int min_prefix_sum = 0;
      
        // Initialize maximum subarray 
        // sum so far to -infinity.
        int res = Integer.MIN_VALUE;
      
        // Initialize and compute 
        // the prefix sum array.
        int prefix_sum[] = new int[n];
        prefix_sum[0] = arr[0];
        for (int i = 1; i < n; i++) 
            prefix_sum[i] = prefix_sum[i - 1] 
                            + arr[i];     
      
        // loop through the array, keep 
        // track of minimum prefix sum so 
        // far and maximum subarray sum.
        for (int i = 0; i < n; i++) 
        {
            res = Math.max(res, prefix_sum[i] - 
                           min_prefix_sum);
            min_prefix_sum = Math.min(min_prefix_sum, 
                                     prefix_sum[i]);
        }
          
        return res;
    }
      
    // Driver Program
    public static void main (String[] args)
    {
        // Test case 1
        int arr1[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n1 = arr1.length;
        System.out.println(maximumSumSubarray(arr1, n1));
      
        // Test case 2
        int arr2[] = { 4, -8, 9, -4, 1, -8, -1, 6 };
        int n2 = arr2.length;
        System.out.println(maximumSumSubarray(arr2, n2));
    }

1719
Chapter 235. Maximum subarray sum in O(n) using prefix sum

}
  
// This code is contributed by Ansu Kumari.

Python3

# Python3 program to find out


# maximum subarray sum in 
# linear time using prefix 
# sum.
import math
  
# Function to compute maximum
# subarray sum in linear time.
def maximumSumSubarray(arr, n):
      
    # Initialize minimum prefix
    # sum to 0.
    min_prefix_sum = 0
  
    # Initialize maximum subarray
    # sum so far to -infinity.
    res = -math.inf
  
    # Initialize and compute the 
    # prefix sum array.
    prefix_sum = []
    prefix_sum.append(arr[0])
      
    for i in range(1, n):
        prefix_sum.append(prefix_sum[i - 1] + arr[i])     
  
    # loop through the array keep
    # track of minimum prefix sum
    # so far and maximum subarray 
    # sum.
    for i in range(n):
          
        res = max(res, prefix_sum[i] - min_prefix_sum)
        min_prefix_sum = min(min_prefix_sum, prefix_sum[i])
      
    return res
  
# Driver Program
  
# Test case 1
arr1 = [ -2, -3, 4, -1, -2, 1, 5, -3 ]
n1 = len(arr1)

1720
Chapter 235. Maximum subarray sum in O(n) using prefix sum

print(maximumSumSubarray(arr1, n1))
  
# Test case 2
arr2 = [ 4, -8, 9, -4, 1, -8, -1, 6 ]
n2 = len(arr2)
print(maximumSumSubarray(arr2, n2))
  
# This code is contributed by Ansu Kuamri.

C#

// C# program to find 
// out maximum subarray
// sum in linear time 
// using prefix sum.
using System;
  
class GFG 
{
    // Function to compute maximum 
    // subarray sum in linear time.
    static int maximumSumSubarray(int []arr, int n)
    {
        // Initialize minimum 
        // prefix sum to 0.
        int min_prefix_sum = 0;
      
        // Initialize maximum subarray 
        // sum so far to -infinity.
        int res = int.MinValue;
      
        // Initialize and compute 
        // the prefix sum array.
        int []prefix_sum = new int[n];
        prefix_sum[0] = arr[0];
        for (int i = 1; i < n; i++) 
            prefix_sum[i] = prefix_sum[i - 1] 
                            + arr[i]; 
      
        // loop through the array, keep 
        // track of minimum prefix sum so 
        // far and maximum subarray sum.
        for (int i = 0; i < n; i++) 
        {
            res = Math.Max(res, prefix_sum[i] - 
                        min_prefix_sum);
            min_prefix_sum = Math.Min(min_prefix_sum, 
                                    prefix_sum[i]);

1721
Chapter 235. Maximum subarray sum in O(n) using prefix sum

        }
          
        return res;
    }
      
    // Driver Program
    public static void Main ()
    {
        // Test case 1
        int []arr1 = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n1 = arr1.Length;
        Console.WriteLine(maximumSumSubarray(arr1, n1));
      
        // Test case 2
        int []arr2 = { 4, -8, 9, -4, 1, -8, -1, 6 };
        int n2 = arr2.Length;
        Console.WriteLine(maximumSumSubarray(arr2, n2));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to find out 
// maximum subarray sum in 
// linear time using prefix sum.
  
// Function to compute maximum 
// subarray sum in linear time.
function maximumSumSubarray($arr, $n)
{
    // Initialize minimum
    // prefix sum to 0.
    $min_prefix_sum = 0;
  
    // Initialize maximum subarray 
    // sum so far to -infinity.
    $res = PHP_INT_MIN;
  
    // Initialize and compute 
    // the prefix sum array.
    $prefix_sum = array();
    $prefix_sum[0] = $arr[0];
    for ($i = 1; $i < $n; $i++) 
        $prefix_sum[$i] = $prefix_sum[$i - 1] + 
                                      $arr[$i]; 

1722
Chapter 235. Maximum subarray sum in O(n) using prefix sum

  
    // loop through the array, 
    // keep track of minimum 
    // prefix sum so far and 
    // maximum subarray sum.
    for ($i = 0; $i < $n; $i++)
    {
        $res = max($res, $prefix_sum[$i] - 
                         $min_prefix_sum);
        $min_prefix_sum = min($min_prefix_sum, 
                              $prefix_sum[$i]);
    }
      
    return $res;
}
  
// Driver Code
  
// Test case 1
$arr1 = array(-2, -3, 4, -1, 
              -2, 1, 5, -3);
$n1 = count($arr1);
echo maximumSumSubarray($arr1, $n1), " \n" ;
  
// Test case 2
$arr2 = array(4, -8, 9, -4, 
              1, -8, -1, 6);
                
$n2 = count($arr2);
echo maximumSumSubarray($arr2, $n2);
  
// This code is contributed by anuj_67.
?>

Output :

7
9

Time Complexity: O(n). It takes linear time to compute the prefix sum and takes
constant time in each iteration of the for loop. Hence overall complexity is O(n).
Improved By : vt_m

Source

https://www.geeksforgeeks.org/maximum-subarray-sum-using-prefix-sum/

1723
Chapter 236

Maximum subarray sum in an


array created after repeated
concatenation

Maximum subarray sum in an array created after repeated concatenation - GeeksforGeeks


Given an array and a number k, find the largest sum of contiguous array in the modified
array which is formed by repeating the given array k times.
Examples :

Input : arr[] = {-1, 10, 20}, k = 2


Output : 59
After concatenating array twice, we
get {-1, 10, 20, -1, 10, 20} which has
maximum subarray sum as 59.

Input : arr[] = {-1, -2, -3}, k = 3


Output : -1

A simple solution is to create an array of size n*k, then run Kadane’s algorithm. Time
complexity would be O(nk) and auxiliary space would be O(n*k)
A better solution is to run a loop on same array and use modular arithmetic to move
back beginning after end of array.

C++

// C++ program to print largest contiguous


// array sum when array is created after

1724
Chapter 236. Maximum subarray sum in an array created after repeated concatenation

// concatenating a small array k times.


#include<bits/stdc++.h>
using namespace std;
  
// Returns sum of maximum sum subarray created
// after concatenating a[0..n-1] k times.
int maxSubArraySumRepeated(int a[], int n, int k)
{
    int max_so_far = INT_MIN, max_ending_here = 0;
  
    for (int i = 0; i < n*k; i++)
    {
        // This is where it differs from Kadane's
        // algorithm. We use modular arithmetic to
        // find next element.
        max_ending_here = max_ending_here + a[i%n];
  
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
  
        if (max_ending_here < 0)
            max_ending_here = 0;
    }
    return max_so_far;
}
  
/*Driver program to test maxSubArraySum*/
int main()
{
    int a[] = {10, 20, -30, -1};
    int n = sizeof(a)/sizeof(a[0]);
    int k = 3;
    cout << "Maximum contiguous sum is "
         << maxSubArraySumRepeated(a, n, k);
    return 0;
}

Java

// Java program to print largest contiguous


// array sum when array is created after
// concatenating a small array k times.
import java.io.*;
  
class GFG {
      
// Returns sum of maximum sum 
// subarray created after 

1725
Chapter 236. Maximum subarray sum in an array created after repeated concatenation

// concatenating a[0..n-1] k times.


static int maxSubArraySumRepeated(int a[],
                             int n, int k)
{
    int max_so_far = 0;
    int INT_MIN, max_ending_here=0;
  
    for (int i = 0; i < n*k; i++)
    {
        // This is where it differs from 
        // Kadane's algorithm. We use modular
        //  arithmetic to find next element.
        max_ending_here = max_ending_here +
                                    a[i % n];
  
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
  
        if (max_ending_here < 0)
            max_ending_here = 0;
    }
    return max_so_far;
}
  
// Driver program to test maxSubArraySum
public static void main (String[] args) {
      
    int a[] = {10, 20, -30, -1};
    int n = a.length;
    int k = 3;
      
    System.out.println("Maximum contiguous sum is "
                   + maxSubArraySumRepeated(a, n, k));
}
  
}
      
// This code is contributed by vt_m

Python3

# Python program to print


# largest contiguous
# array sum when array
# is created after
# concatenating a small
# array k times.
  

1726
Chapter 236. Maximum subarray sum in an array created after repeated concatenation

# Returns sum of maximum


# sum subarray created
# after concatenating
# a[0..n-1] k times.
def maxSubArraySumRepeated(a, n, k):
  
    max_so_far = -2147483648
    max_ending_here = 0
   
    for i in range(n*k):
      
        # This is where it
        # differs from Kadane's
        # algorithm. We use
        #  modular arithmetic to
        # find next element.
        max_ending_here = max_ending_here + a[i%n]
   
        if (max_so_far < max_ending_here):
            max_so_far = max_ending_here
   
        if (max_ending_here < 0):
            max_ending_here = 0
      
    return max_so_far
   
# Driver program
# to test maxSubArraySum
  
a = [10, 20, -30, -1]
n = len(a)
k = 3
  
print("Maximum contiguous sum is ",
    maxSubArraySumRepeated(a, n, k))
  
# This code is contributed
# by Anant Agarwal.

C#

// C# program to print largest contiguous


// array sum when array is created after
// concatenating a small array k times.
using System;
  
class GFG {
      

1727
Chapter 236. Maximum subarray sum in an array created after repeated concatenation

// Returns sum of maximum sum 


// subarray created after 
// concatenating a[0..n-1] k times.
static int maxSubArraySumRepeated(int []a, 
                                  int n, 
                                  int k)
{
    int max_so_far = 0;
    int max_ending_here=0;
  
    for (int i = 0; i < n * k; i++)
    {
        // This is where it differs from 
        // Kadane's algorithm. We use modular
        // arithmetic to find next element.
        max_ending_here = max_ending_here +
                                  a[i % n];
  
        if (max_so_far < max_ending_here)
            max_so_far = max_ending_here;
  
        if (max_ending_here < 0)
            max_ending_here = 0;
    }
    return max_so_far;
}
  
// Driver Code
public static void Main ()
{
      
    int []a = {10, 20, -30, -1};
    int n = a.Length;
    int k = 3;
      
    Console.Write("Maximum contiguous sum is "
                  + maxSubArraySumRepeated(a, n, k));
}
}
      
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to print largest contiguous
// array sum when array is created after
// concatenating a small array k times.

1728
Chapter 236. Maximum subarray sum in an array created after repeated concatenation

  
// Returns sum of maximum 
// sum subarray created
// after concatenating 
// a[0..n-1] k times.
function maxSubArraySumRepeated($a, $n, $k)
{
    $INT_MIN=0; 
    $max_so_far = $INT_MIN; $max_ending_here = 0;
  
    for ($i = 0; $i < $n*$k; $i++)
    {
          
        // This is where it differs 
        // from Kadane's algorithm. 
        // We use modular arithmetic
        // to find next element.
        $max_ending_here = $max_ending_here + 
                                  $a[$i % $n];
  
        if ($max_so_far < $max_ending_here)
            $max_so_far = $max_ending_here;
  
        if ($max_ending_here < 0)
            $max_ending_here = 0;
    }
    return $max_so_far;
}
  
    // Driver Code
    $a = array(10, 20, -30, -1);
    $n = sizeof($a);
    $k = 3;
    echo "Maximum contiguous sum is "
          , maxSubArraySumRepeated($a, $n, $k);
  
// This code is contributed by nitin mittal.
?>

Output :

Maximum contiguous sum is 30

Can we use the repeating property of array to get a better solution ?


Improved By : nitin mittal

1729
Chapter 236. Maximum subarray sum in an array created after repeated concatenation

Source

https://www.geeksforgeeks.org/maximum-subarray-sum-array-created-repeated-concatenation/

1730
Chapter 237

Maximum subsequence sum


such that no three are
consecutive

Maximum subsequence sum such that no three are consecutive - GeeksforGeeks


Given a sequence of positive numbers, find the maximum sum that can be formed which
has no three consecutive elements present.
Examples :

Input: arr[] = {1, 2, 3}


Output: 5
We can't take three of them, so answer is
2 + 3 = 5

Input: arr[] = {3000, 2000, 1000, 3, 10}


Output: 5013
3000 + 2000 + 3 + 10 = 5013

Input: arr[] = {100, 1000, 100, 1000, 1}


Output: 2101
100 + 1000 + 1000 + 1 = 2101

Input: arr[] = {1, 1, 1, 1, 1}


Output: 4

Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8}


Output: 27

This problem is mainly an extension of below problem.

1731
Chapter 237. Maximum subsequence sum such that no three are consecutive

Maximum sum such that no two elements are adjacent


We maintain an auxiliary array sum[] (of same size as input array) to find the result.

sum[i] : Stores result for subarray arr[0..i], i.e.,


maximum possible sum in subarray arr[0..i]
such that no three elements are consecutive.

sum[0] = arr[0]

// Note : All elements are positive


sum[1] = arr[0] + arr[1]

// We have three cases


// 1) Exclude arr[2], i.e., sum[2] = sum[1]
// 2) Exclude arr[1], i.e., sum[2] = sum[0] + arr[2]
// 3) Exclude arr[0], i.e., sum[2] = arr[1] + arr[2]
sum[2] = max(sum[1], arr[0] + arr[2], arr[1] + arr[2])

In general,
// We have three cases
// 1) Exclude arr[i], i.e., sum[i] = sum[i-1]
// 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
// 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1]
sum[i] = max(sum[i-1], sum[i-2] + arr[i],
sum[i-3] + arr[i] + arr[i-1])

Below is implementation of above idea.

C/C++

// C++ program to find the maximum sum such that


// no three are consecutive
#include <bits/stdc++.h>
using namespace std;
  
// Returns maximum subsequence sum such that no three
// elements are consecutive
int maxSumWO3Consec(int arr[], int n)
{
    // Stores result for subarray arr[0..i], i.e.,
    // maximum possible sum in subarray arr[0..i]
    // such that no three elements are consecutive.
    int sum[n];
  
    // Base cases (process first three elements)

1732
Chapter 237. Maximum subsequence sum such that no three are consecutive

    if (n >= 1)
        sum[0] = arr[0];
  
    if (n >= 2)
        sum[1] = arr[0] + arr[1];
  
    if (n > 2)
        sum[2] = max(sum[1], max(arr[1] + arr[2], arr[0] + arr[2]));
  
    // Process rest of the elements
    // We have three cases
    // 1) Exclude arr[i], i.e., sum[i] = sum[i-1]
    // 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
    // 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1]
    for (int i = 3; i < n; i++)
        sum[i] = max(max(sum[i - 1], sum[i - 2] + arr[i]),
                     arr[i] + arr[i - 1] + sum[i - 3]);
  
    return sum[n - 1];
}
  
// Driver code
int main()
{
    int arr[] = { 100, 1000 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSumWO3Consec(arr, n);
    return 0;
}

Java

// java program to find the maximum sum


// such that no three are consecutive
import java.io.*;
  
class GFG {
  
    // Returns maximum subsequence sum such that no three
    // elements are consecutive
    static int maxSumWO3Consec(int arr[], int n)
    {
        // Stores result for subarray arr[0..i], i.e.,
        // maximum possible sum in subarray arr[0..i]
        // such that no three elements are consecutive.
        int sum[] = new int[n];
  
        // Base cases (process first three elements)

1733
Chapter 237. Maximum subsequence sum such that no three are consecutive

        if (n >= 1)
            sum[0] = arr[0];
  
        if (n >= 2)
            sum[1] = arr[0] + arr[1];
  
        if (n > 2)
            sum[2] = Math.max(sum[1], Math.max(arr[1] + arr[2], arr[0] + arr[2]));
  
        // Process rest of the elements
        // We have three cases
        // 1) Exclude arr[i], i.e., sum[i] = sum[i-1]
        // 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
        // 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1]
        for (int i = 3; i < n; i++)
            sum[i] = Math.max(Math.max(sum[i - 1], sum[i - 2] + arr[i]),
                              arr[i] + arr[i - 1] + sum[i - 3]);
  
        return sum[n - 1];
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = { 100, 1000, 100, 1000, 1 };
        int n = arr.length;
        System.out.println(maxSumWO3Consec(arr, n));
    }
}
  
// This code is contributed by vt_m

Python

# Python program to find the maximum sum such that


# no three are consecutive
  
# Returns maximum subsequence sum such that no three
# elements are consecutive
def maxSumWO3Consec(arr, n):
    # Stores result for subarray arr[0..i], i.e.,
    # maximum possible sum in subarray arr[0..i]
    # such that no three elements are consecutive.
    sum = [0 for k in range(n)]
  
    # Base cases (process first three elements)
      
    if n >= 1 :

1734
Chapter 237. Maximum subsequence sum such that no three are consecutive

        sum[0] = arr[0]
      
    if n >= 2 :
        sum[1] = arr[0] + arr[1]
      
    if n > 2 :
        sum[2] = max(sum[1], max(arr[1] + arr[2], arr[0] + arr[2]))
  
    # Process rest of the elements
    # We have three cases
    # 1) Exclude arr[i], i.e., sum[i] = sum[i-1]
    # 2) Exclude arr[i-1], i.e., sum[i] = sum[i-2] + arr[i]
    # 3) Exclude arr[i-2], i.e., sum[i-3] + arr[i] + arr[i-1]
    for i in range(3, n):
        sum[i] = max(max(sum[i-1], sum[i-2] + arr[i]), arr[i] + arr[i-1] + sum[i-3])
  
    return sum[n-1]
  
# Driver code
arr = [100, 1000, 100, 1000, 1]
n = len(arr)
print maxSumWO3Consec(arr, n)
  
# This code is contributed by Afzal Ansari

C#

// C# program to find the maximum sum


// such that no three are consecutive
using System;
class GFG {
  
    // Returns maximum subsequence
    // sum such that no three
    // elements are consecutive
    static int maxSumWO3Consec(int[] arr,
                               int n)
    {
        // Stores result for subarray
        // arr[0..i], i.e., maximum
        // possible sum in subarray
        // arr[0..i] such that no
        // three elements are consecutive.
        int[] sum = new int[n];
  
        // Base cases (process
        // first three elements)
        if (n >= 1)

1735
Chapter 237. Maximum subsequence sum such that no three are consecutive

            sum[0] = arr[0];
  
        if (n >= 2)
            sum[1] = arr[0] + arr[1];
  
        if (n > 2)
            sum[2] = Math.Max(sum[1], Math.Max(arr[1] + arr[2], arr[0] + arr[2]));
  
        // Process rest of the elements
        // We have three cases
        // 1) Exclude arr[i], i.e.,
        // sum[i] = sum[i-1]
        // 2) Exclude arr[i-1], i.e.,
        // sum[i] = sum[i-2] + arr[i]
        // 3) Exclude arr[i-2], i.e.,
        // sum[i-3] + arr[i] + arr[i-1]
        for (int i = 3; i < n; i++)
            sum[i] = Math.Max(Math.Max(sum[i - 1],
                                       sum[i - 2] + arr[i]),
                              arr[i] + arr[i - 1] + sum[i - 3]);
  
        return sum[n - 1];
    }
  
    // Driver code
    public static void Main()
    {
        int[] arr = { 100, 1000, 100, 1000, 1 };
        int n = arr.Length;
        Console.Write(maxSumWO3Consec(arr, n));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to find the maximum
// sum such that no three are consecutive
  
// Returns maximum subsequence
// sum such that no three
// elements are consecutive
function maxSumWO3Consec($arr, $n)
{
    // Stores result for subarray
    // arr[0..i], i.e., maximum 

1736
Chapter 237. Maximum subsequence sum such that no three are consecutive

    // possible sum in subarray


    // arr[0..i] such that no three 
    // elements are consecutive$.
    $sum = array();
  
    // Base cases (process 
    // first three elements)
    if ( $n >= 1)
    $sum[0] = $arr[0];
      
    if ($n >= 2)
    $sum[1] = $arr[0] + $arr[1];
      
    if ( $n > 2)
    $sum[2] = max($sum[1], max($arr[1] + $arr[2], 
                            $arr[0] + $arr[2]));
  
    // Process rest of the elements
    // We have three cases
    // 1) Exclude arr[i], i.e., 
    // sum[i] = sum[i-1]
    // 2) Exclude arr[i-1], i.e., 
    // sum[i] = sum[i-2] + arr[i]
    // 3) Exclude arr[i-2], i.e., 
    // sum[i-3] + arr[i] + arr[i-1]
    for ($i = 3; $i < $n; $i++)
        $sum[$i] = max(max($sum[$i - 1], 
                        $sum[$i - 2] + $arr[$i]), 
                        $arr[$i] + $arr[$i - 1] + 
                                    $sum[$i - 3]);
  
    return $sum[$n-1];
}
  
// Driver code
$arr = array(100, 1000, 100, 1000, 1);
$n =count($arr);
echo maxSumWO3Consec($arr, $n);
  
// This code is contributed by anuj_67.
?>

Output :

2101

Time Complexity : O(n)

1737
Chapter 237. Maximum subsequence sum such that no three are consecutive

Auxiliary Space : O(n)


Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/maximum-subsequence-sum-such-that-no-three-are-consecutive/

1738
Chapter 238

Maximum sum Bi-tonic


Sub-sequence

Maximum sum Bi-tonic Sub-sequence - GeeksforGeeks


Given an array of integers. A subsequenceof arr[] is called Bitonic if it is first increasing,
then decreasing.
Examples :

Input : arr[] = {1, 15, 51, 45, 33,


100, 12, 18, 9}
Output : 194
Explanation : Bi-tonic Sub-sequence are :
{1, 51, 9} or {1, 50, 100, 18, 9} or
{1, 15, 51, 100, 18, 9} or
{1, 15, 45, 100, 12, 9} or
{1, 15, 45, 100, 18, 9} .. so on
Maximum sum Bi-tonic sub-sequence is 1 + 15 +
51 + 100 + 18 + 9 = 194

Input : arr[] = {80, 60, 30, 40, 20, 10}


Output : 210

This problem is a variation of standard Longest Increasing Subsequence (LIS) problem and
longest Bitonic Sub-sequence.
We construct two arrays MSIBS[] and MSDBS[]. MSIBS[i] stores the sum of the Increasing
subsequence ending with arr[i]. MSDBS[i] stores the sum of the Decreasing subsequence
starting from arr[i]. Finally, we need to return the max sum of MSIBS[i] + MSDBS[i] –
Arr[i].
Below is the implementation of above idea

1739
Chapter 238. Maximum sum Bi-tonic Sub-sequence

C/C++

// C++ program to find maximum sum of bi-tonic sub-sequence


#include <bits/stdc++.h>
using namespace std;
  
// Function return maximum sum of Bi-tonic sub-sequence
int MaxSumBS(int arr[], int n)
{
    int max_sum = INT_MIN;
  
    // MSIBS[i] ==> Maximum sum Increasing Bi-tonic
    // subsequence ending with arr[i]
    // MSDBS[i] ==> Maximum sum Decreasing Bi-tonic
    // subsequence starting with arr[i]
    // Initialize MSDBS and MSIBS values as arr[i] for
    // all indexes
    int MSIBS[n], MSDBS[n];
    for (int i = 0; i < n; i++) {
        MSDBS[i] = arr[i];
        MSIBS[i] = arr[i];
    }
  
    // Compute MSIBS values from left to right */
    for (int i = 1; i < n; i++)
        for (int j = 0; j < i; j++)
            if (arr[i] > arr[j] && MSIBS[i] < MSIBS[j] + arr[i])
                MSIBS[i] = MSIBS[j] + arr[i];
  
    // Compute MSDBS values from right to left
    for (int i = n - 2; i >= 0; i--)
        for (int j = n - 1; j > i; j--)
            if (arr[i] > arr[j] && MSDBS[i] < MSDBS[j] + arr[i])
                MSDBS[i] = MSDBS[j] + arr[i];
  
    // Find the maximum value of MSIBS[i] + MSDBS[i] - arr[i]
    for (int i = 0; i < n; i++)
        max_sum = max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i]));
  
    // return max sum of bi-tonic sub-sequence
    return max_sum;
}
  
// Driver program
int main()
{
    int arr[] = { 1, 15, 51, 45, 33, 100, 12, 18, 9 };
    int n = sizeof(arr) / sizeof(arr[0]);

1740
Chapter 238. Maximum sum Bi-tonic Sub-sequence

    cout << "Maximum Sum : " << MaxSumBS(arr, n);


  
    return 0;
}

Java

// java program to find maximum


// sum of bi-tonic sub-sequence
import java.io.*;
  
class GFG {
  
    // Function return maximum sum
    // of Bi-tonic sub-sequence
    static int MaxSumBS(int arr[], int n)
    {
        int max_sum = Integer.MIN_VALUE;
  
        // MSIBS[i] ==> Maximum sum Increasing Bi-tonic
        // subsequence ending with arr[i]
        // MSDBS[i] ==> Maximum sum Decreasing Bi-tonic
        // subsequence starting with arr[i]
        // Initialize MSDBS and MSIBS values as arr[i] for
        // all indexes
        int MSIBS[] = new int[n];
        int MSDBS[] = new int[n];
        for (int i = 0; i < n; i++) {
            MSDBS[i] = arr[i];
            MSIBS[i] = arr[i];
        }
  
        // Compute MSIBS values from left to right */
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] > arr[j] && MSIBS[i] < MSIBS[j] + arr[i])
                    MSIBS[i] = MSIBS[j] + arr[i];
  
        // Compute MSDBS values from right to left
        for (int i = n - 2; i >= 0; i--)
            for (int j = n - 1; j > i; j--)
                if (arr[i] > arr[j] && MSDBS[i] < MSDBS[j] + arr[i])
                    MSDBS[i] = MSDBS[j] + arr[i];
  
        // Find the maximum value of MSIBS[i] +
        // MSDBS[i] - arr[i]
        for (int i = 0; i < n; i++)
            max_sum = Math.max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i]));

1741
Chapter 238. Maximum sum Bi-tonic Sub-sequence

  
        // return max sum of bi-tonic
        // sub-sequence
        return max_sum;
    }
  
    // Driver program
    public static void main(String[] args)
    {
        int arr[] = { 1, 15, 51, 45, 33, 100, 12, 18, 9 };
        int n = arr.length;
        System.out.println("Maximum Sum : " + MaxSumBS(arr, n));
    }
}
  
// This code is contributed by vt_m

Python

# Dynamic Programming implementation of maximum sum of bitonic subsequence 


  
# Function return maximum sum of Bi-tonic sub-sequence
def max_sum(arr, n):
  
    # MSIBS[i] ==> Maximum sum Increasing Bi-tonic
    # subsequence ending with arr[i]
    # MSDBS[i] ==> Maximum sum Decreasing Bi-tonic
    # subsequence starting with arr[i]
  
    # allocate memory for MSIBS and initialize it to arr[i] for
    # all indexes
    MSIBS = arr[:]
  
    # Compute MSIBS values from left to right
    for i in range(n):
  
        for j in range(0, i):
  
            if arr[i] > arr[j] and MSIBS[i] < MSIBS[j] + arr[i]:
  
                MSIBS[i] = MSIBS[j] + arr[i]
  
    # allocate memory for MSDBS and initialize it to arr[i] for
    # all indexes
    MSDBS = arr[:]
  
    # Compute MSDBS values from right to left
    for i in range(1, n + 1):

1742
Chapter 238. Maximum sum Bi-tonic Sub-sequence

  
        for j in range(1, i):
  
            if arr[-i] > arr[-j] and MSDBS[-i] < MSDBS[-j] + arr[-i]:
      
                MSDBS[-i] = MSDBS[-j] + arr[-i]
  
    max_sum = float("-Inf") 
  
    # Find the maximum value of MSIBS[i] + MSDBS[i] - arr[i]
    for i, j, k in zip(MSIBS, MSDBS, arr):
  
        max_sum = max(max_sum, i + j - k)
  
    # return max sum of bi-tonic sub-sequence
    return max_sum
  
  
# Driver program to test the above function
def main():
  
    arr = [1, 15, 51, 45, 33, 100, 12, 18, 9]
  
    n = len(arr)
  
    print max_sum(arr, n)
  
if __name__ == '__main__':
    main()
# This code is contributed by Neelam Yadav

C#

// C# program to find maximum


// sun of bi-tonic sub-sequence
using System;
  
class GFG {
  
    // Function return maximum sum
    // of Bi-tonic sub-sequence
    static int MaxSumBS(int[] arr, int n)
    {
        int max_sum = int.MinValue;
  
        // MSIBS[i] ==> Maximum sum Increasing Bi-tonic
        // subsequence ending with arr[i]
        // MSDBS[i] ==> Maximum sum Decreasing Bi-tonic

1743
Chapter 238. Maximum sum Bi-tonic Sub-sequence

        // subsequence starting with arr[i]


        // Initialize MSDBS and MSIBS values as arr[i] for
        // all indexes
        int[] MSIBS = new int[n];
        int[] MSDBS = new int[n];
        for (int i = 0; i < n; i++) {
            MSDBS[i] = arr[i];
            MSIBS[i] = arr[i];
        }
  
        // Compute MSIBS values from left to right */
        for (int i = 1; i < n; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] > arr[j] && MSIBS[i] < MSIBS[j] + arr[i])
                    MSIBS[i] = MSIBS[j] + arr[i];
  
        // Compute MSDBS values from right to left
        for (int i = n - 2; i >= 0; i--)
            for (int j = n - 1; j > i; j--)
                if (arr[i] > arr[j] && MSDBS[i] < MSDBS[j] + arr[i])
                    MSDBS[i] = MSDBS[j] + arr[i];
  
        // Find the maximum value of MSIBS[i] +
        // MSDBS[i] - arr[i]
        for (int i = 0; i < n; i++)
            max_sum = Math.Max(max_sum, (MSDBS[i] + MSIBS[i] - arr[i]));
  
        // return max sum of bi-tonic
        // sub-sequence
        return max_sum;
    }
  
    // Driver program
    public static void Main()
    {
        int[] arr = { 1, 15, 51, 45, 33, 100, 12, 18, 9 };
        int n = arr.Length;
        Console.WriteLine("Maximum Sum : " + MaxSumBS(arr, n));
    }
}
  
// This code is contributed by vt_m

PHP

<?php
// PHP program to find maximum
// sun of bi-tonic sub-sequence

1744
Chapter 238. Maximum sum Bi-tonic Sub-sequence

function MaxSumBS($arr, $n)


{
    $max_sum = PHP_INT_MIN;
  
    // MSIBS[i] ==> Maximum sum Increasing 
    // Bi-tonic subsequence ending with arr[i]
    // MSDBS[i] ==> Maximum sum Decreasing 
    // Bi-tonic subsequence starting with arr[i]
    // Initialize MSDBS and MSIBS values
    // as arr[i] for all indexes
    $MSIBS = array();
    $MSDBS = array();
    for ($i = 0; $i < $n; $i++) 
    {
        $MSDBS[$i] = $arr[$i];
        $MSIBS[$i] = $arr[$i];
    }
  
    // Compute MSIBS values
    // from left to right */
    for ($i = 1; $i < $n; $i++)
        for ($j = 0; $j < $i; $j++)
            if ($arr[$i] > $arr[$j] && 
                $MSIBS[$i] < $MSIBS[$j] + 
                             $arr[$i])
                $MSIBS[$i] = $MSIBS[$j] + 
                             $arr[$i];
  
    // Compute MSDBS values 
    // from right to left
    for ($i = $n - 2; $i >= 0; $i--)
        for ($j = $n - 1; $j > $i; $j--)
            if ($arr[$i] > $arr[$j] && 
                $MSDBS[$i] < $MSDBS[$j] + 
                             $arr[$i])
                $MSDBS[$i] = $MSDBS[$j] + 
                             $arr[$i];
  
    // Find the maximum value of
    // MSIBS[i] + MSDBS[i] - arr[i]
    for ($i = 0; $i < $n; $i++)
        $max_sum = max($max_sum, ($MSDBS[$i] + 
                                  $MSIBS[$i] - 
                                  $arr[$i]));
  
    // return max sum of 
    // bi-tonic sub-sequence
    return $max_sum;

1745
Chapter 238. Maximum sum Bi-tonic Sub-sequence

}
  
// Driver Code
$arr = array(1, 15, 51, 45, 33, 
             100, 12, 18, 9);
$n = count($arr);
echo "Maximum Sum : " , 
      MaxSumBS($arr, $n);
  
// This code is contributed
// by shiv_bhakt.
?>

Output:

Maximum Sum : 194

Time complexity : O(n2 )


Improved By : vt_m, shiv_bhakt

Source

https://www.geeksforgeeks.org/maximum-sum-bi-tonic-sub-sequence/

1746
Chapter 239

Maximum sum alternating


subsequence

Maximum sum alternating subsequence - GeeksforGeeks


Given an array, the task is to find sum of maximum sum alternating subsequence starting
with first element. Here alternating sequence means first decreasing, then increasing, then
decreasing, … For example 10, 5, 14, 3 is an alternating sequence.
Note that the reverse type of sequence (increasing – decreasing – increasing -…) is not
considered alternating here.
Examples:

Input : arr[] = {4, 3, 8, 5, 3, 8}


Output : 28
Explanation:
The alternating subsequence (starting with first element)
that has above maximum sum is {4, 3, 8, 5, 8}

Input : arr[] = {4, 8, 2, 5, 6, 8}


Output : 14
The alternating subsequence (starting with first element)
that has above maximum sum is {4, 2, 8}

This problem is similar to Longest Increasing Subsequence (LIS) problem. and can be solved
using Dynamic Programming.

Create two empty array that store result of maximum


sum of alternate sub-sequence
inc[] : inc[i] stores results of maximum sum alternating

1747
Chapter 239. Maximum sum alternating subsequence

subsequence ending with arr[i] such that arr[i]


is greater than previous element of the subsequence
dec[] : dec[i] stores results of maximum sum alternating
subsequence ending with arr[i] such that arr[i]
is less than previous element of the subsequence

Include first element of 'arr' in both inc[] and dec[]


inc[0] = dec[0] = arr[0]

// Maintain a flag i.e. it will makes the greater


// elements count only if the first decreasing element
// is counted.
flag = 0

Traversal two loops


i goes from 1 to n-1
j goes 0 to i-1
IF arr[j] > arr[i]
dec[j] = max(dec[i], inc[j] + arr[i])

// Denotes first decreasing is found


flag = 1

ELSE IF arr[j] < arr[i] && flag == 1


inc[i] = max(inc[i], dec[j]+arr[i]);

Final Last Find maximum value inc[] and dec[] .

Below is implementation of above idea.


C/C++

// C++ program to find sum of maximum


// sum alternating sequence starting with
// first element.
#include<bits/stdc++.h>
using namespace std;
  
// Return sum of maximum sum alternating
// sequence starting with arr[0] and is first
// decreasing.
int maxAlternateSum(int arr[], int n)
{
    if (n == 1)
        return arr[0];
  
   // create two empty array that store result of
   // maximum sum of alternate sub-sequence

1748
Chapter 239. Maximum sum alternating subsequence

  
    // stores sum of decreasing and increasing
    // sub-sequence
    int dec[n];
    memset(dec, 0, sizeof(dec));
  
    // store sum of increasing and decreasing sun-sequence
    int inc[n];
    memset(inc, 0, sizeof(inc));
  
    // As per question, first element must be part
    // of solution.
    dec[0] = inc[0] = arr[0];
  
    int flag = 0 ;
  
    // Traverse remaining elements of array
    for (int i=1; i<n; i++)
    {
        for (int j=0; j<i; j++)
        {
            // IF current sub-sequence is decreasing the
            // update dec[j] if needed. dec[i] by current
            // inc[j] + arr[i]
            if (arr[j] > arr[i])
            {
                dec[i] = max(dec[i], inc[j]+arr[i]);
  
                // Revert the flag , if first decreasing
                // is found
                flag = 1;
            }
  
            // If next element is greater but flag should be 1
            // i.e. this element should be counted after the
            // first decreasing element gets counted
            else if (arr[j] < arr[i] && flag == 1)
  
                // If current sub-sequence is increasing
                // then update inc[i]
                inc[i] = max(inc[i], dec[j]+arr[i]);
        }
    }
  
    // find maximum sum in b/w inc[] and dec[]
    int result = INT_MIN;
    for (int i = 0 ; i < n; i++)
    {

1749
Chapter 239. Maximum sum alternating subsequence

        if (result < inc[i])


            result = inc[i];
        if (result < dec[i])
            result = dec[i];
    }
  
    // return maximum sum alternate sun-sequence
    return result;
}
  
//Driver program
int main()
{
    int arr[]= {8, 2, 3, 5, 7, 9, 10};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Maximum sum = "
         << maxAlternateSum(arr , n ) << endl;
    return 0;
}

Java

// Java program to find sum of maximum


// sum alternating sequence starting with
// first element.
  
public class GFG 
{
    // Return sum of maximum sum alternating
    // sequence starting with arr[0] and is first
    // decreasing.
    static int maxAlternateSum(int arr[], int n)
    {
        if (n == 1)
            return arr[0];
       
       // create two empty array that store result of
       // maximum sum of alternate sub-sequence
       
        // stores sum of decreasing and increasing
        // sub-sequence
        int dec[] = new int[n];
          
       
        // store sum of increasing and decreasing sun-sequence
        int inc[] = new int[n];
       
        // As per question, first element must be part

1750
Chapter 239. Maximum sum alternating subsequence

        // of solution.
        dec[0] = inc[0] = arr[0];
       
        int flag = 0 ;
       
        // Traverse remaining elements of array
        for (int i=1; i<n; i++)
        {
            for (int j=0; j<i; j++)
            {
                // IF current sub-sequence is decreasing the
                // update dec[j] if needed. dec[i] by current
                // inc[j] + arr[i]
                if (arr[j] > arr[i])
                {
                    dec[i] = Math.max(dec[i], inc[j]+arr[i]);
       
                    // Revert the flag , if first decreasing
                    // is found
                    flag = 1;
                }
       
                // If next element is greater but flag should be 1
                // i.e. this element should be counted after the
                // first decreasing element gets counted
                else if (arr[j] < arr[i] && flag == 1)
       
                    // If current sub-sequence is increasing
                    // then update inc[i]
                    inc[i] = Math.max(inc[i], dec[j]+arr[i]);
            }
        }
       
        // find maximum sum in b/w inc[] and dec[]
        int result = Integer.MIN_VALUE;
        for (int i = 0 ; i < n; i++)
        {
            if (result < inc[i])
                result = inc[i];
            if (result < dec[i])
                result = dec[i];
        }
       
        // return maximum sum alternate sun-sequence
        return result;
    }
      
    // Driver Method

1751
Chapter 239. Maximum sum alternating subsequence

    public static void main(String[] args)


    {
        int arr[]= {8, 2, 3, 5, 7, 9, 10};
        System.out.println("Maximum sum = " +
                  maxAlternateSum(arr , arr.length));
    }
}

Python3

# Python3 program to find sum of maximum


# sum alternating sequence starting with
# first element.
  
# Return sum of maximum sum alternating
# sequence starting with arr[0] and is 
# first decreasing.
def maxAlternateSum(arr, n):
  
    if (n == 1):
        return arr[0]
  
    # Create two empty array that
    # store result of maximum sum
    # of alternate sub-sequence
  
    # Stores sum of decreasing and 
    # increasing sub-sequence
    dec = [0 for i in range(n + 1)]
  
    # store sum of increasing and
    # decreasing sun-sequence
    inc = [0 for i in range(n + 1)]
  
    # As per question, first element 
    # must be part of solution.
    dec[0] = inc[0] = arr[0]
  
    flag = 0
  
    # Traverse remaining elements of array
    for i in range(1, n):
      
        for j in range(i):
          
            # IF current sub-sequence is decreasing the
            # update dec[j] if needed. dec[i] by current
            # inc[j] + arr[i]

1752
Chapter 239. Maximum sum alternating subsequence

            if (arr[j] > arr[i]):


              
                dec[i] = max(dec[i], inc[j] + arr[i])
  
                # Revert the flag, if first 
                # decreasing is found
                flag = 1
  
            # If next element is greater but flag should be 1
            # i.e. this element should be counted after the
            # first decreasing element gets counted
            elif (arr[j] < arr[i] and flag == 1):
  
                # If current sub-sequence is 
                # increasing then update inc[i]
                inc[i] = max(inc[i], dec[j] + arr[i])
  
    # Find maximum sum in b/w inc[] and dec[]
    result = -2147483648
    for i in range(n):
      
        if (result < inc[i]):
            result = inc[i]
        if (result < dec[i]):
            result = dec[i]
  
    # Return maximum sum
    # alternate sun-sequence
    return result
  
# Driver program
arr = [8, 2, 3, 5, 7, 9, 10]
n = len(arr)
print("Maximum sum = ",
       maxAlternateSum(arr , n ))
         
# This code is contributed by Anant Agarwal.

C#

// C# program to find sum of maximum


// sum alternating sequence starting with
// first element.
using System;
class GFG {
      
    // Return sum of maximum 
    // sum alternating

1753
Chapter 239. Maximum sum alternating subsequence

    // sequence starting with 


    // arr[0] and is first
    // decreasing.
    static int maxAlternateSum(int []arr, int n)
    {
        if (n == 1)
            return arr[0];
      
        // create two empty array that 
        // store result of maximum sum 
        // of alternate sub-sequence
        // stores sum of decreasing 
        // and increasing sub-sequence
        int []dec = new int[n];
          
        // store sum of increasing and
        // decreasing sun-sequence
        int []inc = new int[n];
      
        // As per question, first 
        // element must be part
        // of solution.
        dec[0] = inc[0] = arr[0];
      
        int flag = 0 ;
      
        // Traverse remaining elements of array
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j < i; j++)
            {
                  
                // IF current sub-sequence
                // is decreasing the
                // update dec[j] if needed.
                // dec[i] by current
                // inc[j] + arr[i]
                if (arr[j] > arr[i])
                {
                    dec[i] = Math.Max(dec[i], 
                             inc[j] + arr[i]);
      
                    // Revert the flag , if
                    // first decreasing
                    // is found
                    flag = 1;
                }
      

1754
Chapter 239. Maximum sum alternating subsequence

                // If next element is greater


                // but flag should be 1
                // i.e. this element should 
                // be counted after the
                // first decreasing element
                // gets counted
                else if (arr[j] < arr[i] && flag == 1)
      
                    // If current sub-sequence
                    // is increasing then update
                    // inc[i]
                    inc[i] = Math.Max(inc[i], 
                             dec[j] + arr[i]);
            }
        }
      
        // find maximum sum in b/w
        // inc[] and dec[]
        int result = int.MinValue;
        for (int i = 0 ; i < n; i++)
        {
            if (result < inc[i])
                result = inc[i];
            if (result < dec[i])
                result = dec[i];
        }
      
        // return maximum sum 
        // alternate sun-sequence
        return result;
    }
      
    // Driver Method
    public static void Main()
    {
        int []arr= {8, 2, 3, 5, 7, 9, 10};
        Console.Write("Maximum sum = " +
                maxAlternateSum(arr , arr.Length));
    }
}
  
// This code is contributed by Nitin Mittal.

Output:

Maximum sum = 25

1755
Chapter 239. Maximum sum alternating subsequence

Time Complexity : O(n2 )


Auxiliary Space : O(n)
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/maximum-sum-alternating-subsequence-sum/

1756
Chapter 240

Maximum sum bitonic subarray

Maximum sum bitonic subarray - GeeksforGeeks


Given an array containing n numbers. The problem is to find the maximum sum bitonic
subarray. A bitonic subarray is a subarray in which elements are first increasing and then
decreasing. A strictly increasing or strictly decreasing subarray is also considered as bitonic
subarray. Time Complexity of O(n) is required.
Examples:

Input : arr[] = {5, 3, 9, 2, 7, 6, 4}


Output : 19
The subarray is {2, 7, 6, 4}.

Input : arr[] = {9, 12, 14, 8, 6, 5, 10, 20}


Output : 54

Approach: The problem is closely related to Maximum Sum Bitonic Subsequence. We cre-
ate two arrays msis[] and msds[]. msis[i] stores the sum of Increasing subarray ending with
arr[i]. msds[i] stores the sum of Decreasing subarray starting from arr[i]. Now, maximum
sum bitonic subarray is calculated as max(msis[i]+msds[i]-arr[i]) for each index i of the
array.
C++

// C++ implementation to find the


// maximum sum bitonic subarray
#include <bits/stdc++.h>
  
using namespace std;
  
// function to find the maximum sum 
// bitonic subarray

1757
Chapter 240. Maximum sum bitonic subarray

int maxSumBitonicSubArr(int arr[], int n)


{
    // 'msis[]' to store the maximum sum increasing subarray
    // up to each index of 'arr' from the beginning
    // 'msds[]' to store the maximum sum decreasing subarray
    // from each index of 'arr' up to the end
    int msis[n], msds[n];
      
    // to store the maximum sum
    // bitonic subarray
    int max_sum = INT_MIN;
      
    // building up the maximum sum increasing subarray
    // for each array index
    msis[0] = arr[0];
    for (int i=1; i<n; i++)
        if (arr[i] > arr[i-1])
            msis[i] = msis[i-1] + arr[i];
        else
            msis[i] = arr[i];    
      
    // building up the maximum sum decreasing subarray
    // for each array index
    msds[n-1] = arr[n-1];
    for (int i=n-2; i>=0; i--)
        if (arr[i] > arr[i+1])
            msds[i] = msds[i+1] + arr[i];
        else
            msds[i] = arr[i];
      
    // for each array index, calculating the maximum sum
    // of bitonic subarray of which it is a part of
    for (int i=0; i<n; i++)            
        // if true , then update 'max' bitonic
        // subarray sum
        if (max_sum < (msis[i] + msds[i] - arr[i]))
            max_sum = msis[i] + msds[i] - arr[i];
      
    // required maximum sum
    return max_sum;
}
  
// Driver program to test above
int main()
{
    int arr[] = {5, 3, 9, 2, 7, 6, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Maximum Sum = "

1758
Chapter 240. Maximum sum bitonic subarray

         << maxSumBitonicSubArr(arr, n);


    return 0;     

Java

// Java implementation to 


// find the maximum sum
// bitonic subarray
class GFG
{
  
    // function to find the maximum 
    // sum bitonic subarray
    static int maxSumBitonicSubArr(int arr[], 
                                   int n)
    {
          
    // 'msis[]' to store the maximum 
    // sum increasing subarray up to
    // each index of 'arr' from the 
    // beginning 'msds[]' to store 
    // the maximum sum decreasing 
    // subarray from each index of 
    // 'arr' up to the end
    int []msis = new int[n];
    int []msds = new int[n];
      
    // to store the maximum 
    // sum bitonic subarray
    int max_sum = Integer.MIN_VALUE;
      
    // building up the maximum 
    // sum increasing subarray
    // for each array index
    msis[0] = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > arr[i - 1])
            msis[i] = msis[i - 1] + 
                       arr[i];
        else
            msis[i] = arr[i]; 
      
    // building up the maximum 
    // sum decreasing subarray
    // for each array index
    msds[n - 1] = arr[n - 1];
    for (int i = n - 2; i >= 0; i--)

1759
Chapter 240. Maximum sum bitonic subarray

        if (arr[i] > arr[i + 1])


            msds[i] = msds[i + 1] + arr[i];
        else
            msds[i] = arr[i];
      
    // for each array index, 
    // calculating the maximum 
    // sum of bitonic subarray 
    // of which it is a part of
    for (int i = 0; i < n; i++)         
      
        // if true , then update 
        // 'max' bitonic subarray sum
        if (max_sum < (msis[i] +
                       msds[i] - arr[i]))
            max_sum = msis[i] + 
                      msds[i] - arr[i];
      
    // required maximum sum
    return max_sum;
    }
      
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = {5, 3, 9, 2, 7, 6, 4};
        int n = arr.length;
        System.out.println( "Maximum Sum = " + 
                 maxSumBitonicSubArr(arr, n));
    }
}
  
// This code is contributed
// by ChitraNayal

Python 3

# Python 3 implementation 
# to find the maximum sum
# bitonic subarray
  
# function to find the 
# maximum sum bitonic subarray
def maxSumBitonicSubArr(arr, n):
      
    # 'msis[]' to store the maximum 
    # sum increasing subarray up to 
    # each index of 'arr' from the 

1760
Chapter 240. Maximum sum bitonic subarray

    # beginning 'msds[]' to store 


    # the maximum sum decreasing 
    # subarray from each index of 
    # 'arr' up to the end
    msis = [None] * n
    msds = [None] * n
      
    # to store the maximum 
    # sum bitonic subarray
    max_sum = 0
      
    # building up the maximum
    # sum increasing subarray
    # for each array index
    msis[0] = arr[0]
    for i in range(1, n):
        if (arr[i] > arr[i - 1]):
            msis[i] = msis[i - 1] + arr[i]
        else:
            msis[i] = arr[i] 
      
    # building up the maximum 
    # sum decreasing subarray
    # for each array index
    msds[n - 1] = arr[n - 1]
    for i in range(n - 2, -1, -1):
        if (arr[i] > arr[i + 1]):
            msds[i] = msds[i + 1] + arr[i]
        else:
            msds[i] = arr[i]
      
    # for each array index, 
    # calculating the maximum 
    # sum of bitonic subarray 
    # of which it is a part of
    for i in range(n):    
          
        # if true , then update 
        # 'max' bitonic subarray sum
        if (max_sum < (msis[i] + 
                       msds[i] - arr[i])):
            max_sum = (msis[i] + 
                       msds[i] - arr[i])
      
    # required maximum sum
    return max_sum
  
# Driver Code

1761
Chapter 240. Maximum sum bitonic subarray

arr = [5, 3, 9, 2, 7, 6, 4];


n = len(arr)
print("Maximum Sum = "+
       str(maxSumBitonicSubArr(arr, n)))
         
# This code is contributed
# by ChitraNayal

C#

// C# implementation to find 
// the maximum sum bitonic subarray
using System;
  
class GFG
{
  
    // function to find the maximum 
    // sum bitonic subarray
    static int maxSumBitonicSubArr(int[] arr,
                                   int n)
    {
    // 'msis[]' to store the maximum 
    // sum increasing subarray up to
    // each index of 'arr' from the 
    // beginning 'msds[]' to store 
    // the maximum sum decreasing 
    // subarray from each index of 
    // 'arr' up to the end
    int []msis = new int[n];
    int []msds = new int[n];
      
    // to store the maximum 
    // sum bitonic subarray
    int max_sum = int.MinValue;
      
    // building up the maximum 
    // sum increasing subarray
    // for each array index
    msis[0] = arr[0];
    for (int i = 1; i < n; i++)
        if (arr[i] > arr[i - 1])
            msis[i] = msis[i - 1] + 
                       arr[i];
        else
            msis[i] = arr[i]; 
      
    // building up the maximum 

1762
Chapter 240. Maximum sum bitonic subarray

    // sum decreasing subarray


    // for each array index
    msds[n - 1] = arr[n - 1];
    for (int i = n - 2; i >= 0; i--)
        if (arr[i] > arr[i + 1])
            msds[i] = msds[i + 1] + 
                       arr[i];
        else
            msds[i] = arr[i];
      
    // for each array index, calculating 
    // the maximum sum of bitonic subarray
    // of which it is a part of
    for (int i = 0; i < n; i++)    
      
        // if true , then update 
        // 'max' bitonic subarray sum
        if (max_sum < (msis[i] + 
                       msds[i] - arr[i]))
            max_sum = msis[i] + 
                      msds[i] - arr[i];
      
    // required maximum sum
    return max_sum;
    }
      
    // Driver Code
    public static void Main() 
    {
        int[] arr = {5, 3, 9, 2, 7, 6, 4};
        int n = arr.Length;
        Console.Write("Maximum Sum = " +
           maxSumBitonicSubArr(arr, n));
    }
}
  
// This code is contributed
// by ChitraNayal

PHP

<?php
// PHP implementation to find the
// maximum sum bitonic subarray
  
// function to find the maximum sum 
// bitonic subarray
function maxSumBitonicSubArr($arr, $n)

1763
Chapter 240. Maximum sum bitonic subarray

{
    // 'msis[]' to store the maximum
    // sum increasing subarray up to
    // each index of 'arr' from the 
    // beginning 'msds[]' to store 
    // the maximum sum decreasing 
    // subarray from each index of 
    // 'arr' up to the end
    $msis = array(); 
    $msds = array();
      
    // to store the maximum 
    // sum bitonic subarray
    $max_sum = PHP_INT_MIN;
      
    // building up the maximum
    // sum increasing subarray
    // for each array index
    $msis[0] = $arr[0];
    for ($i = 1; $i < $n; $i++)
        if ($arr[$i] > $arr[$i - 1])
            $msis[$i] = $msis[$i - 1] + 
                              $arr[$i];
        else
            $msis[$i] = $arr[$i]; 
      
    // building up the maximum 
    // sum decreasing subarray
    // for each array index
    $msds[$n - 1] = $arr[$n - 1];
    for ($i = $n - 2; $i >= 0; $i--)
        if ($arr[$i] > $arr[$i + 1])
            $msds[$i] = $msds[$i + 1] +
                              $arr[$i];
        else
            $msds[$i] = $arr[$i];
      
    // for each array index, 
    // calculating the maximum sum
    // of bitonic subarray of which 
    // it is a part of
    for ($i = 0; $i < $n; $i++)     
        // if true , then update 
        // 'max' bitonic subarray sum
        if ($max_sum < ($msis[$i] + 
                        $msds[$i] - $arr[$i]))
            $max_sum = $msis[$i] + 
                       $msds[$i] - $arr[$i];

1764
Chapter 240. Maximum sum bitonic subarray

      
    // required maximum sum
    return $max_sum;
}
  
// Driver Code
$arr = array(5, 3, 9, 
             2, 7, 6, 4);
$n = sizeof($arr);
echo "Maximum Sum = ",
      maxSumBitonicSubArr($arr, $n);
  
// This code is contributed by ajit
?>

Output:

Maximum Sum = 19

Time Complexity: O(n)


Auxiliary Space: O(n)
Space optimized solution:
It can be solved with constant memory. Indeed, since we are looking for contiguous subar-
rays, we can separate the initial array into bitonic chunks and compare their sums.
C++

// C++ implementation to find the


// maximum sum bitonic subarray
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the maximum sum bitonic
// subarray.
int maxSumBitonicSubArr(int arr[], int n)
{
    // to store the maximum sum
    // bitonic subarray
    int max_sum = INT_MIN;
  
    int i = 0;
    while (i < n) {
  
        // Find the longest increasing subarray
        // starting at i.
        int j = i;

1765
Chapter 240. Maximum sum bitonic subarray

        while (j+1 < n && arr[j] < arr[j+1])


            j++;
  
        // Now we know that a[i..j] is an
        // increasing subarray. Remove non-
        // positive elements from the left
        // side as much as possible.
        while (i < j && arr[i] <= 0)
            i++;
  
        // Find the longest decreasing subarray
        // starting at j.
        int k = j;
        while (k+1 < n && arr[k] > arr[k+1])
            k++;
  
        // Now we know that a[j..k] is a
        // decreasing subarray. Remove non-
        // positive elements from the right
        // side as much as possible.
        // last is needed to keep the last
        // seen element.
        int last = k;
        while (k > j && arr[k] <= 0)
            k--;
  
  
        // Compute the max sum of the
        // increasing part.
        int sum_inc =
               accumulate(arr+i, arr+j+1, 0);
  
        // Compute the max sum of the
        // decreasing part.
        int sum_dec =
               accumulate(arr+j, arr+k+1, 0);
  
        // The overall max sum is the sum of
        // both parts minus the peak element,
        // because it was counted twice.
        int sum_all = sum_inc + sum_dec - arr[j];
  
        max_sum = max({max_sum, sum_inc,
                       sum_dec, sum_all});
  
        // If the next element is equal to the
        // current, i.e. arr[i+1] == arr[i],
        // last == i.

1766
Chapter 240. Maximum sum bitonic subarray

        // To ensure the algorithm has progress,


        // get the max of last and i+1.
        i = max(last, i+1);
    }
  
    // required maximum sum
    return max_sum;
}
  
// Driver program to test above
int main()
{
    // The example from the article, the
    // answer is 19.
    int arr[] = {5, 3, 9, 2, 7, 6, 4};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr, n)
         << endl;
  
    // Always increasing, the answer is 15.
    int arr2[] = {1, 2, 3, 4, 5};
    int n2 = sizeof(arr2) / sizeof(arr2[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr2, n2)
         << endl;
  
    // Always decreasing, the answer is 15.
    int arr3[] = {5, 4, 3, 2, 1};
    int n3 = sizeof(arr3) / sizeof(arr3[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr3, n3)
         << endl;
  
    // All are equal, the answer is 5.
    int arr4[] = {5, 5, 5, 5};
    int n4 = sizeof(arr4) / sizeof(arr4[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr4, n4)
         << endl;
  
    // The whole array is bitonic, but the answer is 7.
    int arr5[] = {-1, 0, 1, 2, 3, 1, 0, -1, -10};
    int n5 = sizeof(arr5) / sizeof(arr5[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr5, n5)
         << endl;
  

1767
Chapter 240. Maximum sum bitonic subarray

    // The answer is 4 (the tail).


    int arr6[] = {-1, 0, 1, 2, 0, -1, -2, 0, 1, 3};
    int n6 = sizeof(arr6) / sizeof(arr6[0]);
    cout << "Maximum Sum = "
         << maxSumBitonicSubArr(arr6, n6)
         << endl;
  
    return 0;
}

Output:

Maximum Sum = 19
Maximum Sum = 15
Maximum Sum = 15
Maximum Sum = 5
Maximum Sum = 7
Maximum Sum = 4

Thanks to Andrey Khayrutdinov for suggesting this solution.


Improved By : jit_t, ChitraNayal

Source

https://www.geeksforgeeks.org/maximum-sum-bitonic-subarray/

1768
Chapter 241

Maximum sum in a 2 x n grid


such that no two elements are
adjacent

Maximum sum in a 2 x n grid such that no two elements are adjacent - GeeksforGeeks
Given a rectangular grid of dimension 2 x n. We need to find out the maximum sum such
that no two chosen numbers are adjacent, vertically, diagonally or horizontally.
Examples:

Input : 1 4 5
2 0 0
Output : 7
If we start from 1 then we can add only 5 or 0.
So max_sum = 6 in this case.
If we select 2 then also we can add only 5 or 0.
So max_sum = 7 in this case.
If we select from 4 or 0 then there is no further
elements can be added.
So, Max sum is 7.

Input : 1 2 3 4 5
6 7 8 9 10
Output : 24

This problem is an extension of Maximum sum such that no two elements are adjacent.
Only thing to be changed is to take maximum element of both row of a particular column.
We traverse column by column and maintain maximum sum considering two cases.
1) An element of current column is included. In this case we take maximum of two elements

1769
Chapter 241. Maximum sum in a 2 x n grid such that no two elements are adjacent

in current column.
2) An element of current column is excluded (or not included)
Below is the implementation of above steps.

C++

// C++ program to find maximum sum in a grid such that


// no two elements are adjacent.
#include<bits/stdc++.h>
#define MAX 1000
using namespace std;
  
// Function to find max sum without adjacent
int maxSum(int grid[2][MAX], int n)
{
    // Sum including maximum element of first column
    int incl = max(grid[0][0], grid[1][0]);
  
    // Not including first column's element
    int excl = 0, excl_new;
  
    // Traverse for further elements
    for (int i = 1; i<n; i++ )
    {
        // Update max_sum on including or excluding
        // of previous column
        excl_new = max(excl, incl);
  
        // Include current column. Add maximum element
        // from both row of current column
        incl = excl + max(grid[0][i], grid[1][i]);
  
        // If current column doesn't to be included
        excl = excl_new;
    }
  
    // Return maximum of excl and incl
    // As that will be the maximum sum
    return max(excl, incl);
}
  
// Driver code
int main()
{
    int grid[2][MAX] = {{ 1, 2, 3, 4, 5},
                        { 6, 7, 8, 9, 10}};
  

1770
Chapter 241. Maximum sum in a 2 x n grid such that no two elements are adjacent

    int n = 5;
    cout << maxSum(grid, n);
  
    return 0;
}

Java

// JAVA Code for Maximum sum in a 2 x n grid


// such that no two elements are adjacent
import java.util.*;
  
class GFG {
      
    // Function to find max sum without adjacent
    public static int maxSum(int grid[][], int n)
    {
        // Sum including maximum element of first
        // column
        int incl = Math.max(grid[0][0], grid[1][0]);
       
        // Not including first column's element
        int excl = 0, excl_new;
       
        // Traverse for further elements
        for (int i = 1; i < n; i++ )
        {
            // Update max_sum on including or 
            // excluding of previous column
            excl_new = Math.max(excl, incl);
       
            // Include current column. Add maximum element
            // from both row of current column
            incl = excl + Math.max(grid[0][i], grid[1][i]);
       
            // If current column doesn't to be included
            excl = excl_new;
        }
       
        // Return maximum of excl and incl
        // As that will be the maximum sum
        return Math.max(excl, incl);
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
         int grid[][] = {{ 1, 2, 3, 4, 5},

1771
Chapter 241. Maximum sum in a 2 x n grid such that no two elements are adjacent

                         { 6, 7, 8, 9, 10}};
  
         int n = 5;
         System.out.println(maxSum(grid, n));
    }
  }
// This code is contributed by Arnav Kr. Mandal.

Output:

24

Time Complexity : O(n)

Source

https://www.geeksforgeeks.org/maximum-sum-2-x-n-grid-no-two-elements-adjacent/

1772
Chapter 242

Maximum sum in circular array


such that no two elements are
adjacent

Maximum sum in circular array such that no two elements are adjacent - GeeksforGeeks
Given a circular array containing of positive integers value. The task is to find the maximum
sum of a subsequence with the constraint that no 2 numbers in the sequence should be
adjacent in the array.
Examples:

Input: circular arr = {1, 2, 3, 1}


Output : 4
subsequence will be(1, 3), hence 1 + 3 = 4

Input: circular arr = {1, 2, 3, 4, 5, 1}


Output: 9
subsequence will be(1, 3, 5), hence 1 + 3 + 5 = 9

Approach The problem can be solved using DP. An approach has already been discussed
in thispost, but it for an array. We can treat the circular subarray a two arrays one from
(0th to n-2-th) and (1st to n-1-th) index, and use the approach used in the previous post.
The maximum sum returned by both will be the answer.

1773
Chapter 242. Maximum sum in circular array such that no two elements are adjacent

Below is the implementation of the above approach.

// CPP program to find maximum sum in a circular array 


// such that no elements are adjacent in the sum.
#include <bits/stdc++.h>
using namespace std;
  
// Function to calculate the sum
// from 0th position to(n-2)th position
int maxSum1(int arr[], int n)
{
    int dp[n];
    int maxi = 0;
  

1774
Chapter 242. Maximum sum in circular array such that no two elements are adjacent

    for (int i = 0; i < n - 1; i++) {


  
        // copy the element of original array to dp[]
        dp[i] = arr[i];
  
        // find the maximum element in the array
        if (maxi < arr[i])
            maxi = arr[i];
    }
  
    // start from 2nd to n-1th pos
    for (int i = 2; i < n - 1; i++) {
  
        // traverse for all pairs
        // bottom-up approach
        for (int j = 0; j < i - 1; j++) {
  
            // dp-condition
            if (dp[i] < dp[j] + arr[i]) {
                dp[i] = dp[j] + arr[i];
  
                // find maximum sum
                if (maxi < dp[i])
                    maxi = dp[i];
            }
        }
    }
  
    // return the maximum
    return maxi;
}
  
// Function to find the maximum sum
// from 1st position to n-1-th position
int maxSum2(int arr[], int n)
{
    int dp[n];
    int maxi = 0;
  
    for (int i = 1; i < n; i++) {
        dp[i] = arr[i];
  
        if (maxi < arr[i])
            maxi = arr[i];
    }
  
    // Traverse from third to n-th pos
    for (int i = 3; i < n; i++) {

1775
Chapter 242. Maximum sum in circular array such that no two elements are adjacent

  
        // bootom-up approach
        for (int j = 1; j < i - 1; j++) {
  
            // dp condition
            if (dp[i] < arr[i] + dp[j]) {
                dp[i] = arr[i] + dp[j];
  
                // find max sum
                if (maxi < dp[i])
                    maxi = dp[i];
            }
        }
    }
  
    // return max
    return maxi;
}
  
int findMaxSum(int arr[], int n)
{
   return max(maxSum1(arr, n), maxSum2(arr, n));
}
  
// Driver Code
int main()
{
    int arr[] = { 1, 2, 3, 1 };
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << findMaxSum(arr, n);
    return 0;
}

Output:

Time Complexity: O(N^2)


Improved By : Mohd_Saliem

Source

https://www.geeksforgeeks.org/maximum-sum-in-circular-array-such-that-no-two-elements-are-adjacent/

1776
Chapter 243

Maximum sum increasing


subsequence from a prefix and a
given element after prefix is
must

Maximum sum increasing subsequence from a prefix and a given element after prefix is must
- GeeksforGeeks
Given an array of n positive integers, write a program to find the maximum sum of increasing
subsequence from prefix till i-th index and also including a given kth element which is after
i, i.e., k > i .
Examples :

Input : arr[] = {1, 101, 2, 3, 100, 4, 5}


i-th index = 4 (Element at 4th index is 100)
K-th index = 6 (Element at 6th index is 5.)
Output : 11
So we need to calculate the maximum sum of subsequence (1 101 2 3 100 5) such
that 5 is necessarily included in the subsequence, so answer is 11 by subsequence
(1 2 3 5).
Input : arr[] = {1, 101, 2, 3, 100, 4, 5}
i-th index = 2 (Element at 2nd index is 2)
K-th index = 5 (Element at 5th index is 4.)
Output : 7
So we need to calculate the maximum sum of subsequence (1 101 2 4) such that
4 is necessarily included in the subsequence, so answer is 7 by subsequence (1 2
4).

Prerequisite : Maximum Sum Increasing Subsequence

1777
Chapter 243. Maximum sum increasing subsequence from a prefix and a given element
after prefix is must

Simple Approach:

1. Construct a new array containing elements till ith index and the kth element.
2. Recursively calculate all the increasing subsequences.
3. Discard all the subsequences not having kth element included.
4. Calculate the maximum sum from the left over subsequences and display it.

Time Complexity: O(2n )


Efficient Approach: Use a dynamic approach to maintain a table dp[][]. The value of
dp[i][k] stores the maximum sum of increasing subsequence till ith index and containing
the kth element.

C++

// CPP program to find maximum sum increasing


// subsequence till i-th index and including
// k-th index.
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
  
ll pre_compute(ll a[], ll n, ll index, ll k)
{
    ll dp[n][n] = { 0 };
  
    // Initializing the first row of the dp[][].
    for (int i = 0; i < n; i++) {
        if (a[i] > a[0]) 
            dp[0][i] = a[i] + a[0];        
        else 
            dp[0][i] = a[i];        
    }
  
    // Creating the dp[][] matrix.
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (a[j] > a[i] && j > i) {
                if (dp[i - 1][i] + a[j] > dp[i - 1][j]) 
                    dp[i][j] = dp[i - 1][i] + a[j];                
                else 
                    dp[i][j] = dp[i - 1][j];
            }
            else 
                dp[i][j] = dp[i - 1][j];            
        }
    }

1778
Chapter 243. Maximum sum increasing subsequence from a prefix and a given element
after prefix is must

  
    // To calculate for i=4 and k=6.
    return dp[index][k];
}
  
int main()
{
    ll a[] = { 1, 101, 2, 3, 100, 4, 5 };
    ll n = sizeof(a) / sizeof(a[0]);
    ll index = 4, k = 6;
    printf("%lld", pre_compute(a, n, index, k));
    return 0;
}

Java

// Java program to find maximum sum increasing


// subsequence tiint i-th index and including
// k-th index.
class GFG {
      
    static int pre_compute(int a[], int n,
                             int index, int k)
    {
        int dp[][] = new int[n][n];
      
        // Initializing the first row of 
        // the dp[][].
        for (int i = 0; i < n; i++) {
            if (a[i] > a[0]) 
                dp[0][i] = a[i] + a[0]; 
            else
                dp[0][i] = a[i];     
        }
      
        // Creating the dp[][] matrix.
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (a[j] > a[i] && j > i)
                {
                    if (dp[i - 1][i] + a[j] >
                                 dp[i - 1][j]) 
                        dp[i][j] = dp[i - 1][i]
                                        + a[j];         
                    else
                        dp[i][j] = dp[i - 1][j];

1779
Chapter 243. Maximum sum increasing subsequence from a prefix and a given element
after prefix is must

                }
                else
                    dp[i][j] = dp[i - 1][j];         
            }
        }
      
        // To calculate for i=4 and k=6.
        return dp[index][k];
    }
      
    // Driver code
    public static void main(String[] args)
    {
        int a[] = { 1, 101, 2, 3, 100, 4, 5 };
        int n = a.length;
        int index = 4, k = 6;
        System.out.println(
                  pre_compute(a, n, index, k));
    }
}
  
// This code is contributed by Smitha.

C#

// C# program to find maximum 


// sum increasing subsequence 
// till i-th index and including
// k-th index.
using System;
  
class GFG
{
    static int pre_compute(int []a, int n,
                           int index, int k)
    {
    int [,]dp = new int[n, n];
  
    // Initializing the first 
    // row of the dp[][].
    for (int i = 0; i < n; i++) 
    {
        if (a[i] > a[0]) 
            dp[0, i] = a[i] + a[0]; 
        else
            dp[0, i] = a[i]; 
    }
  

1780
Chapter 243. Maximum sum increasing subsequence from a prefix and a given element
after prefix is must

    // Creating the dp[][] matrix.


    for (int i = 1; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            if (a[j] > a[i] && j > i)
            {
                if (dp[i - 1, i] + a[j] >
                            dp[i - 1, j]) 
                    dp[i, j] = dp[i - 1, i] +
                                        a[j];     
                else
                    dp[i, j] = dp[i - 1, j];
            }
            else
                dp[i, j] = dp[i - 1, j];         
        }
    }
  
    // To calculate for i=4 and k=6.
    return dp[index, k];
}
  
// Driver code
static public void Main ()
{
    int []a = {1, 101, 2, 
               3, 100, 4, 5};
    int n = a.Length;
    int index = 4, k = 6;
    Console.WriteLine(pre_compute(a, n, 
                                  index, k));
}
}
  
// This code is contributed by @ajit

Output:

11

Time Complexity : O(n2 )


Note: This approach is very useful if you have to answer multiple such queries of i and k
because using the pre calculated dp matrix you can answer such query in O(1) time.

1781
Chapter 243. Maximum sum increasing subsequence from a prefix and a given element
after prefix is must

To try similar problem, give this article a read: Maximum product of an increasing subse-
quence
Improved By : Smitha Dinesh Semwal, jit_t

Source

https://www.geeksforgeeks.org/maximum-sum-increasing-subsequence-from-a-prefix-and-a-given-element-after-pre

1782
Chapter 244

Maximum sum of a path in a


Right Number Triangle

Maximum sum of a path in a Right Number Triangle - GeeksforGeeks


Given a right triangle of numbers, find the largest of the sum of numbers that appear on
the paths starting from the top towards the base, so that on each path the next number is
located directly below or below-and-one-place-to-the-right.
Examples :

Input : 1
1 2
4 1 2
2 3 1 1
Output : 9
Explanation : 1 + 1 + 4 + 3

Input : 2
4 1
1 2 7
Output : 10
Explanation : 2 + 1 + 7

The idea is to find largest sum ending at every cell of last row and return maximum of
these sums. We can recursively compute these sums by recursively considering above two
cells. Since there are overlapping subproblems, we use dynamic programming to find the
maximum sum ending at particular cell of last row.
Below is the implementation of above idea.
C++

1783
Chapter 244. Maximum sum of a path in a Right Number Triangle

// C++ program to print maximum sum


// in a right triangle of numbers
#include<bits/stdc++.h>
using namespace std;
  
// function to find maximum sum path
int maxSum(int tri[][3], int n)
{
    // Adding the element of row 1 to both the
    // elements of row 2 to reduce a step from
    // the loop
    if (n > 1)
        tri[1][1] = tri[1][1] + tri[0][0];
        tri[1][0] = tri[1][0] + tri[0][0];
  
    // Traverse remaining rows
    for(int i = 2; i < n; i++) {
        tri[i][0] = tri[i][0] + tri[i-1][0];
        tri[i][i] = tri[i][i] + tri[i-1][i-1];
  
        //Loop to traverse columns
        for (int j = 1; j < i; j++){
  
            // Checking the two conditions, 
            // directly below and below right.
            // Considering the greater one
              
            // tri[i] would store the possible 
            // combinations of sum of the paths
            if (tri[i][j] + tri[i-1][j-1] >= 
                            tri[i][j] + tri[i-1][j])
                  
                tri[i][j] = tri[i][j] + tri[i-1][j-1];
            else
                tri[i][j] = tri[i][j]+tri[i-1][j];
        }
    }
      
    // array at n-1 index (tri[i]) stores 
    // all possible adding combination, finding 
    // the maximum one out of them
    int max=tri[n-1][0];
      
    for(int i=1;i<n;i++)
    {
        if(max<tri[n-1][i])
            max=tri[n-1][i];
    }

1784
Chapter 244. Maximum sum of a path in a Right Number Triangle

      
    return max;
}
  
// driver program
int main(){
      
    int tri[3][3] = {{1}, {2,1}, {3,3,2}};
  
    cout<<maxSum(tri, 3);
      
    return 0;
}

Java

// Java program to print maximum sum


// in a right triangle of numbers
class GFG
{
      
    // function to find maximum sum path
    static int maxSum(int tri[][], int n)
    {
          
        // Adding the element of row 1 to both the
        // elements of row 2 to reduce a step from
        // the loop
        if (n > 1)
            tri[1][1] = tri[1][1] + tri[0][0];
            tri[1][0] = tri[1][0] + tri[0][0];
      
        // Traverse remaining rows
        for(int i = 2; i < n; i++) {
            tri[i][0] = tri[i][0] + tri[i-1][0];
            tri[i][i] = tri[i][i] + tri[i-1][i-1];
      
            //Loop to traverse columns
            for (int j = 1; j < i; j++){
      
                // Checking the two conditions, 
                // directly below and below right.
                // Considering the greater one
                  
                // tri[i] would store the possible 
                // combinations of sum of the paths
                if (tri[i][j] + tri[i-1][j-1] >= 
                           tri[i][j] + tri[i-1][j])

1785
Chapter 244. Maximum sum of a path in a Right Number Triangle

                      
                    tri[i][j] = tri[i][j] 
                                  + tri[i-1][j-1];
                      
                else
                    tri[i][j] = tri[i][j]
                                    + tri[i-1][j];
            }
        }
          
        // array at n-1 index (tri[i]) stores 
        // all possible adding combination, 
        // finding the maximum one out of them
        int max = tri[n-1][0];
          
        for(int i = 1; i < n; i++)
        {
            if(max < tri[n-1][i])
                max = tri[n-1][i];
        }
          
        return max;
    } 
          
    // Driver code
    public static void main (String[] args)
    {
        int tri[][] = {{1}, {2,1}, {3,3,2}};
          
        System.out.println(maxSum(tri, 3));
    }
}
  
// This code is contributed by Anant Agarwal.

Python

# Python program to print maximum sum


# in a right triangle of numbers.
  
# tri[][] is a 2D array that stores the
# triangle, n is number of lines or rows.
def maxSum(tri, n):
  
    # Adding the element of row 1 to both the
    # elements of row 2 to reduce a step from
    # the loop
    if n > 1:

1786
Chapter 244. Maximum sum of a path in a Right Number Triangle

        tri[1][1] = tri[1][1]+tri[0][0]
        tri[1][0] = tri[1][0]+tri[0][0]
  
    # Traverse remaining rows
    for i in range(2, n):
        tri[i][0] = tri[i][0] + tri[i-1][0]
        tri[i][i] = tri[i][i] + tri[i-1][i-1]
  
        # Loop to traverse columns
        for j in range(1, i):
  
            # Checking the two conditions, directly below
            # and below right. Considering the greater one
  
            # tri[i] would store the possible combinations
            # of sum of the paths
            if tri[i][j]+tri[i-1][j-1] >= tri[i][j]+tri[i-1][j]:
                tri[i][j] = tri[i][j] + tri[i-1][j-1]
            else:
                tri[i][j] = tri[i][j]+tri[i-1][j]
  
    # array at n-1 index (tri[i]) stores all possible
    # adding combination, finding the maximum one
    # out of them
    print max(tri[n-1])
  
# driver program
tri = [[1], [2,1], [3,3,2]]
maxSum(tri, 3)

C#

// C# program to print 
// maximum sum in a right
// triangle of numbers
using System;
  
class GFG
{
      
    // function to find 
    // maximum sum path
    static int maxSum(int [,]tri, 
                      int n)
    {
          
        // Adding the element of row 1 
        // to both the elements of row 2 

1787
Chapter 244. Maximum sum of a path in a Right Number Triangle

        // to reduce a step from the loop


        if (n > 1)
            tri[1, 1] = tri[1, 1] + 
                        tri[0, 0];
            tri[1, 0] = tri[1, 0] + 
                        tri[0, 0];
      
        // Traverse remaining rows
        for(int i = 2; i < n; i++) 
        {
            tri[i, 0] = tri[i, 0] + 
                        tri[i - 1, 0];
            tri[i, i] = tri[i, i] + 
                        tri[i - 1, i - 1];
       
            //Loop to traverse columns
            for (int j = 1; j < i; j++)
            {
      
                // Checking the two conditions, 
                // directly below and below right.
                // Considering the greater one
                  
                // tri[i] would store the possible 
                // combinations of sum of the paths
                if (tri[i, j] + tri[i - 1, j - 1] >= 
                    tri[i, j] + tri[i - 1, j])
                  
                    tri[i, j] = tri[i, j] + 
                                tri[i - 1, j - 1];
                      
                else
                    tri[i, j] = tri[i, j] + 
                                tri[i - 1, j];
            }
        }
          
        // array at n-1 index (tri[i]) 
        // stores all possible adding 
        // combination, finding the 
        // maximum one out of them
        int max = tri[n - 1, 0];
          
        for(int i = 1; i < n; i++)
        {
            if(max < tri[n - 1, i])
                max = tri[n - 1, i];
        }

1788
Chapter 244. Maximum sum of a path in a Right Number Triangle

          
        return max;
    } 
          
// Driver Code
public static void Main ()
{
      
        int [,]tri = {{1,0,0}, 
                      {2,1,0},
                      {3,3,2}};
          
        Console.Write(maxSum(tri, 3));
}
}
  
// This code is contributed by ajit.

PHP

<?php
// PHP program to print maximum sum
// in a right triangle of numbers
  
// function to find maximum sum path
function maxSum($tri, $n)
{
    // Adding the element of row 1 
    // to both the elements of row 
    // 2 to reduce a step from the loop
    if ($n > 1)
        $tri[1][1] = $tri[1][1] + $tri[0][0];
        $tri[1][0] = $tri[1][0] + $tri[0][0];
  
    // Traverse remaining rows
    for($i = 2; $i < $n; $i++)
    {
        $tri[$i][0] = $tri[$i][0] + 
                      $tri[$i - 1][0];
        $tri[$i][$i] = $tri[$i][$i] + 
                       $tri[$i - 1][$i - 1];
  
        //Loop to traverse columns
        for ($j = 1; $j < $i; $j++)
        {
  
            // Checking the two conditions, 
            // directly below and below right.

1789
Chapter 244. Maximum sum of a path in a Right Number Triangle

            // Considering the greater one


              
            // tri[i] would store the possible 
            // combinations of sum of the paths
            if ($tri[$i][$j] + $tri[$i - 1][$j - 1] >= 
                 $tri[$i][$j] + $tri[$i - 1][$j])
                  
                $tri[$i][$j] = $tri[$i][$j] + 
                               $tri[$i - 1][$j - 1];
            else
                $tri[$i][$j] = $tri[$i][$j] + 
                               $tri[$i - 1][$j];
        }
    }
      
    // array at n-1 index (tri[i]) 
    // stores all possible adding 
    // combination, finding the 
    // maximum one out of them
      
    $max = $tri[$n - 1][0];
      
    for($i = 1; $i < $n; $i++)
    {
        if($max < $tri[$n - 1][$i])
            $max = $tri[$n - 1][$i];
    }
      
    return $max;
}
  
// Driver Code
$tri = array(array(1),
             array(2,1), 
             array(3,3,2));
  
echo maxSum($tri, 3);
  
// This code is contributed by ajit
?>

Output :

Improved By : jit_t

1790
Chapter 244. Maximum sum of a path in a Right Number Triangle

Source

https://www.geeksforgeeks.org/maximum-sum-path-right-number-triangle/

1791
Chapter 245

Maximum sum of pairs with


specific difference

Maximum sum of pairs with specific difference - GeeksforGeeks


Given an array of integers and a number k. We can pair two number of array if difference
between them is strictly less than k. The task is to find maximum possible sum of disjoint
pairs. Sum of P pairs is sum of all 2P numbers of pairs.
Examples:

Input : arr[] = {3, 5, 10, 15, 17, 12, 9}, K = 4


Output : 62
Then disjoint pairs with difference less than K are,
(3, 5), (10, 12), (15, 17)
So maximum sum which we can get is 3 + 5 + 12 + 10 + 15 + 17 = 62
Note that an alternate way to form disjoint pairs is,
(3, 5), (9, 12), (15, 17), but this pairing produces lesser sum.

Input : arr[] = {5, 15, 10, 300}, k = 12


Output : 25

First we sort the given array in increasing order. Once array is sorted, we traverse the
array. For every element, we try to pair it with its previous element first. Why do we prefer
previous element? Let arr[i] can be paired with arr[i-1] and arr[i-2] (i.e. arr[i] – arr[i-1] <
K and arr[i]-arr[i-2] < K). Since the array is sorted, value of arr[i-1] would be more than
arr[i-2]. Also, we need to pair with difference less than k, it means if arr[i-2] can be paired,
then arr[i-1] can also be paired in a sorted array.
Now observing the above facts, we can formulate our dynamic programming solution as
below,
Let dp[i] denotes the maximum disjoint pair sum we can achieve using first i elements of
the array. Assume currently we are at i’th position, then there are two possibilities for us.

1792
Chapter 245. Maximum sum of pairs with specific difference

Pair up i with (i-1)th element, i.e.


dp[i] = dp[i-2] + arr[i] + arr[i-1]
Don't pair up, i.e.
dp[i] = dp[i-1]

Above iteration takes O(N) time and sorting of array will take O(N log N) time so total
time complexity of the solution will be O(N log N)

C++

// C++ program to find maximum pair sum whose


// difference is less than K
#include <bits/stdc++.h>
using namespace std;
  
// method to return maximum sum we can get by
// finding less than K difference pair
int maxSumPairWithDifferenceLessThanK(int arr[], int N, int K)
{
    // Sort input array in ascending order.
    sort(arr, arr+N);
  
    // dp[i] denotes the maximum disjoint pair sum
    // we can achieve using first i elements
    int dp[N];
  
    //  if no element then dp value will be 0
    dp[0] = 0;
  
    for (int i = 1; i < N; i++)
    {
        // first give previous value to dp[i] i.e.
        // no pairing with (i-1)th element
        dp[i] = dp[i-1];
  
        // if current and previous element can form a pair
        if (arr[i] - arr[i-1] < K)
        {
            // update dp[i] by choosing maximum between
            // pairing and not pairing
            if (i >= 2)
                dp[i] = max(dp[i], dp[i-2] + arr[i] + arr[i-1]);
            else
                dp[i] = max(dp[i], arr[i] + arr[i-1]);
        }
    }

1793
Chapter 245. Maximum sum of pairs with specific difference

  
    //  last index will have the result
    return dp[N - 1];
}
  
//  Driver code to test above methods
int main()
{
    int arr[] = {3, 5, 10, 15, 17, 12, 9};
    int N = sizeof(arr)/sizeof(int);
  
    int K = 4;
    cout << maxSumPairWithDifferenceLessThanK(arr, N, K);
    return 0;
}

Java

// Java program to find maximum pair sum whose


// difference is less than K
  
import java.io.*;
import java.util.*;
  
class GFG {
      
    // method to return maximum sum we can get by
    // finding less than K difference pair
    static int maxSumPairWithDifferenceLessThanK(int arr[],
                                               int N, int K)
    {
          
        // Sort input array in ascending order.
        Arrays.sort(arr);
      
        // dp[i] denotes the maximum disjoint pair sum
        // we can achieve using first i elements
        int dp[] = new int[N];
      
        // if no element then dp value will be 0
        dp[0] = 0;
      
        for (int i = 1; i < N; i++)
        {
            // first give previous value to dp[i] i.e.
            // no pairing with (i-1)th element
            dp[i] = dp[i-1];
      

1794
Chapter 245. Maximum sum of pairs with specific difference

            // if current and previous element can form a pair


            if (arr[i] - arr[i-1] < K)
            {
                  
                // update dp[i] by choosing maximum between
                // pairing and not pairing
                if (i >= 2)
                    dp[i] = Math.max(dp[i], dp[i-2] + arr[i] +
                                                    arr[i-1]);
                else
                    dp[i] = Math.max(dp[i], arr[i] + arr[i-1]);
            }
        }
      
        // last index will have the result
        return dp[N - 1];
    }
  
    // Driver code to test above methods
    public static void main (String[] args) {
          
        int arr[] = {3, 5, 10, 15, 17, 12, 9};
        int N = arr.length;
        int K = 4;
          
        System.out.println ( maxSumPairWithDifferenceLessThanK(
                                                    arr, N, K));
          
    }
}
  
//This code is contributed by vt_m.

Python3

# Python3 program to find maximum pair 


# sum whose difference is less than K
  
# method to return maximum sum we can 
# get by get by finding less than K
# difference pair
def maxSumPairWithDifferenceLessThanK(arr, N, K):
  
    # Sort input array in ascending order.
    arr.sort()
  
    # dp[i] denotes the maximum disjoint
    # pair sum we can achieve using first

1795
Chapter 245. Maximum sum of pairs with specific difference

    # i elements
    dp = [0] * N
  
    # if no element then dp value will be 0
    dp[0] = 0
  
    for i in range(1, N):
      
        # first give previous value to
        # dp[i] i.e. no pairing with
        # (i-1)th element
        dp[i] = dp[i-1]
  
        # if current and previous element 
        # can form a pair
        if (arr[i] - arr[i-1] < K):
          
            # update dp[i] by choosing
            # maximum between pairing
            # and not pairing
            if (i >= 2):
                dp[i] = max(dp[i], dp[i-2] + arr[i] + arr[i-1]);
            else:
                dp[i] = max(dp[i], arr[i] + arr[i-1]);
          
    # last index will have the result
    return dp[N - 1]
  
# Driver code to test above methods
arr = [3, 5, 10, 15, 17, 12, 9]
N = len(arr)
K = 4
print(maxSumPairWithDifferenceLessThanK(arr, N, K))
  
# This code is contributed by Smitha Dinesh Semwal

C#

// C# program to find maximum pair sum whose


// difference is less than K
using System;
  
class GFG {
      
    // method to return maximum sum we can get by
    // finding less than K difference pair
    static int maxSumPairWithDifferenceLessThanK(int []arr,
                                              int N, int K)

1796
Chapter 245. Maximum sum of pairs with specific difference

    {
          
        // Sort input array in ascending order.
        Array.Sort(arr);
      
        // dp[i] denotes the maximum disjoint pair sum
        // we can achieve using first i elements
        int []dp = new int[N];
      
        // if no element then dp value will be 0
        dp[0] = 0;
      
        for (int i = 1; i < N; i++)
        {
            // first give previous value to dp[i] i.e.
            // no pairing with (i-1)th element
            dp[i] = dp[i-1];
      
            // if current and previous element can form 
            // a pair
            if (arr[i] - arr[i-1] < K)
            {
                  
                // update dp[i] by choosing maximum 
                // between pairing and not pairing
                if (i >= 2)
                    dp[i] = Math.Max(dp[i], dp[i-2] 
                                + arr[i] + arr[i-1]);
                else
                    dp[i] = Math.Max(dp[i], arr[i]
                                        + arr[i-1]);
            }
        }
      
        // last index will have the result
        return dp[N - 1];
    }
  
    // Driver code to test above methods
    public static void Main () {
          
        int []arr = {3, 5, 10, 15, 17, 12, 9};
        int N = arr.Length;
        int K = 4;
          
        Console.WriteLine( 
          maxSumPairWithDifferenceLessThanK(arr, N, K));
          

1797
Chapter 245. Maximum sum of pairs with specific difference

    }
}
  
// This code is contributed by anuj_67.

Output:

62

Time complexity : O(N Log N)


Auxiliary Space : O(N)
An optimised solution contributed by Amit Sane is given below,

C++

// C++ program to find maximum pair sum whose


// difference is less than K
#include <bits/stdc++.h>
using namespace std;
  
// Method to return maximum sum we can get by
// finding less than K difference pairs
int maxSumPairWithDifferenceLessThanK(int arr[], int N, int k)
{
    int maxSum = 0;
  
    // Sort elements to ensure every i and i-1 is closest
    // possible pair
    sort(arr, arr+N);
  
    // To get maximum possible sum, iterate from largest to
    // smallest, giving larger numbers priority over smaller
    // numbers.
    for (int i=N-1; i>0; --i)
    {
        // Case I: Diff of arr[i] and arr[i-1] is less then K,
        //         add to maxSum
        // Case II: Diff between arr[i] and arr[i-1] is not less
        //          then K, move to next i since with sorting we
        //          know, arr[i]-arr[i-1] < arr[i]-arr[i-2] and
        //          so on.
        if (arr[i]-arr[i-1] < k)
        {
            //Assuming only positive numbers.
            maxSum += arr[i];

1798
Chapter 245. Maximum sum of pairs with specific difference

            maxSum += arr[i-1];
  
            //When a match is found skip this pair
            --i;
        }
    }
  
    return maxSum;
}
  
// Driver code to test above methods
int main()
{
    int arr[] = {3, 5, 10, 15, 17, 12, 9};
    int N = sizeof(arr)/sizeof(int);
  
    int K = 4;
    cout << maxSumPairWithDifferenceLessThanK(arr, N, K);
    return 0;
}

Java

// Java program to find maximum pair sum whose


// difference is less than K
  
import java.io.*;
import java .util.*;
  
class GFG {
      
    // Method to return maximum sum we can get by
    // finding less than K difference pairs
    static int maxSumPairWithDifferenceLessThanK(int arr[], 
                                               int N, int k)
    {
        int maxSum = 0;
      
        // Sort elements to ensure every i and i-1 is closest
        // possible pair
        Arrays.sort(arr);
      
        // To get maximum possible sum, iterate from largest
        // to smallest, giving larger numbers priority over 
        // smaller numbers.
        for (int i = N-1; i > 0; --i)
        {
            // Case I: Diff of arr[i] and arr[i-1] is less then K,

1799
Chapter 245. Maximum sum of pairs with specific difference

            //     add to maxSum


            // Case II: Diff between arr[i] and arr[i-1] is not less
            //     then K, move to next i since with sorting we
            //     know, arr[i]-arr[i-1] < arr[i]-arr[i-2] and
            //     so on.
            if (arr[i] - arr[i-1] < k)
            {
                //Assuming only positive numbers.
                maxSum += arr[i];
                maxSum += arr[i-1];
      
                //When a match is found skip this pair
                --i;
            }
        }
      
        return maxSum;
    }
  
    // Driver code to test above methods
    public static void main (String[] args) {
          
        int arr[] = {3, 5, 10, 15, 17, 12, 9};
        int N = arr.length;
        int K = 4;
          
        System.out.println ( maxSumPairWithDifferenceLessThanK(
                                                    arr, N, K));
    }
}
  
//This code is contributed by vt_m.

C#

// C# program to find maximum pair sum whose


// difference is less than K
using System;
class GFG {
      
    // Method to return maximum sum we can get by
    // finding less than K difference pairs
    static int maxSumPairWithDifferenceLessThanK(int []arr, 
                                               int N, int k)
    {
        int maxSum = 0;
      
        // Sort elements to ensure

1800
Chapter 245. Maximum sum of pairs with specific difference

        // every i and i-1 is closest


        // possible pair
        Array.Sort(arr);
      
        // To get maximum possible sum, 
        // iterate from largest
        // to smallest, giving larger
        // numbers priority over 
        // smaller numbers.
        for (int i = N-1; i > 0; --i)
        {
              
            /* Case I: Diff of arr[i] and 
                       arr[i-1] is less then K,
                       add to maxSum 
               Case II: Diff between arr[i] and 
                        arr[i-1] is not less
                        then K, move to next i 
                        since with sorting we
                        know, arr[i]-arr[i-1] < 
                        arr[i]-arr[i-2] and
                        so on.*/
            if (arr[i] - arr[i-1] < k)
            {
                  
                // Assuming only positive numbers.
                maxSum += arr[i];
                maxSum += arr[i - 1];
      
                // When a match is found 
                // skip this pair
                --i;
            }
        }
      
        return maxSum;
    }
  
    // Driver Code
    public static void Main () 
    {
        int []arr = {3, 5, 10, 15, 17, 12, 9};
        int N = arr.Length;
        int K = 4;
          
        Console.Write( maxSumPairWithDifferenceLessThanK(arr, 
                                                         N, K));
    }

1801
Chapter 245. Maximum sum of pairs with specific difference

}
  
// This code is contributed by nitin mittal.

Output:

62

Time complexity : O(N Log N)


Auxiliary Space : O(1)
Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/maximum-sum-pairs-specific-difference/

1802
Chapter 246

Maximum sum path in a matrix


from top to bottom

Maximum sum path in a matrix from top to bottom - GeeksforGeeks


Consider a n*n matrix. Suppose each cell in the matrix has a value assigned. We can go
from each cell in row i to a diagonally higher cell in row i+1 only [i.e from cell(i, j) to
cell(i+1, j-1) and cell(i+1, j+1) only]. Find the path from the top row to the bottom row
following the aforementioned condition such that the maximum sum is obtained.
Examples:

Input : mat[][] = { {5, 6, 1, 7},


{-2, 10, 8, -1},
{3, -7, -9, 11},
{12, -4, 2, 6} }
Output : 28

{5, 6, 1, 7},
{-2, 10, 8, -1},
{3, -7, -9, 11},
{12, -4, 2, 6} }

The highlighted numbers from top to bottom


gives the required maximum sum path.
(7 + 8 + 11 + 2) = 28

Algorithm: The idea is to find maximum sum or all paths starting with every cell of first
row and finally return maximum of all values in first row. We use Dynamic Programming
as results of many subproblems are needed again and again.
C++

1803
Chapter 246. Maximum sum path in a matrix from top to bottom

// C++ implementation to find the maximum sum


// path in a matrix
#include <bits/stdc++.h>
using namespace std;
  
#define SIZE 10
  
// function to find the maximum sum
// path in a matric
int maxSum(int mat[SIZE][SIZE], int n)
{
    // if there is a single element only
    if (n == 1)
        return mat[0][0];
  
    // dp[][] matrix to store the results
    // of each iteration
    int dp[n][n];
    int maxSum = INT_MIN, max;
  
    // base case, copying elements of
    // last row
    for (int j = 0; j < n; j++)
        dp[n - 1][j] = mat[n - 1][j];
  
    // building up the dp[][] matrix from
    // bottom to the top row
    for (int i = n - 2; i >= 0; i--) {
        for (int j = 0; j < n; j++) {
            max = INT_MIN;
  
            // finding the maximum diagonal element in the
            // (i+1)th row if that cell exists
            if (((j - 1) >= 0) && (max < dp[i + 1][j - 1]))
                max = dp[i + 1][j - 1];
            if (((j + 1) < n) && (max < dp[i + 1][j + 1]))
                max = dp[i + 1][j + 1];
  
            // adding that 'max' element to the
            // mat[i][j] element
            dp[i][j] = mat[i][j] + max;
        }
    }
  
    // finding the maximum value from the
    // first row of dp[][]
    for (int j = 0; j < n; j++)
        if (maxSum < dp[0][j])

1804
Chapter 246. Maximum sum path in a matrix from top to bottom

            maxSum = dp[0][j];
  
    // required maximum sum
    return maxSum;
}
  
// Driver program to test above
int main()
{
    int mat[SIZE][SIZE] = { { 5, 6, 1, 7 },
                            { -2, 10, 8, -1 },
                            { 3, -7, -9, 11 },
                            { 12, -4, 2, 6 } };
    int n = 4;
  
    cout << "Maximum Sum = "
         << maxSum(mat, n);
  
    return 0;
}

Java

// Java implementation to find the 


// maximum sum path in a matrix
import java.io.*;
  
class MaxSumPath {
//int mat[][];
  
// function to find the maximum 
// sum path in a matrix
static int maxSum(int[][] mat, int n)
{
    // if there is a single element only
    if (n == 1)
        return mat[0][0];
  
    // dp[][] matrix to store the results
    // of each iteration
    int dp[][] = new int[n][n];
    int maxSum = Integer.MIN_VALUE, max;
  
    // base case, copying elements of
    // last row
    for (int j = 0; j < n; j++)
        dp[n - 1][j] = mat[n - 1][j];
  

1805
Chapter 246. Maximum sum path in a matrix from top to bottom

    // building up the dp[][] matrix 


    // from bottom to the top row
    for (int i = n - 2; i >= 0; i--) {
        for (int j = 0; j < n; j++) {
            max = Integer.MIN_VALUE;
  
            // finding the maximum diagonal 
            // element in the (i+1)th row 
            // if that cell exists
            if (((j - 1) >= 0) && 
                 (max < dp[i + 1][j - 1]))
                 max = dp[i + 1][j - 1];
            if (((j + 1) < n) && 
                (max < dp[i + 1][j + 1]))
                max = dp[i + 1][j + 1];
  
            // adding that 'max' element
            // to the mat[i][j] element
            dp[i][j] = mat[i][j] + max;
        }
    }
  
    // finding the maximum value from
    // the first row of dp[][]
    for (int j = 0; j < n; j++)
        if (maxSum < dp[0][j])
            maxSum = dp[0][j];
  
    // required maximum sum
    return maxSum;
}
  
    // Driver code
    public static void main (String[] args) {
      
    int mat[][] = { { 5, 6, 1, 7 },
                    { -2, 10, 8, -1 },
                    { 3, -7, -9, 11 },
                    { 12, -4, 2, 6 } };
    int n = 4;
  
    System.out.println("Maximum Sum = "+
                        maxSum(mat , n));
  
    }
}
  
// This code is contributed by Prerna Saini

1806
Chapter 246. Maximum sum path in a matrix from top to bottom

C#

// C# implementation to find the 


// maximum sum path in a matrix
using System;
  
class MaxSumPath 
{
    //int mat[][];
      
    // function to find the maximum 
    // sum path in a matrix
    static int maxSum(int[,] mat, int n)
    {
        // if there is a single element only
        if (n == 1)
            return mat[0, 0];
      
        // dp[][] matrix to store the results
        // of each iteration
        int [,]dp = new int[n, n];
        int maxSum = int.MinValue, max;
      
        // base case, copying elements of
        // last row
        for (int j = 0; j < n; j++)
            dp[n - 1, j] = mat[n - 1, j];
      
        // building up the dp[][] matrix 
        // from bottom to the top row
        for (int i = n - 2; i >= 0; i--)
        {
            for (int j = 0; j < n; j++) 
            {
                max = int.MinValue;
      
                // finding the maximum diagonal 
                // element in the (i+1)th row 
                // if that cell exists
                if (((j - 1) >= 0) && 
                    (max < dp[i + 1, j - 1]))
                    max = dp[i + 1, j - 1];
                if (((j + 1) < n) && 
                    (max < dp[i + 1, j + 1]))
                    max = dp[i + 1, j + 1];
      
                // adding that 'max' element
                // to the mat[i][j] element

1807
Chapter 246. Maximum sum path in a matrix from top to bottom

                dp[i, j] = mat[i, j] + max;


            }
        }
      
        // finding the maximum value from
        // the first row of dp[][]
        for (int j = 0; j < n; j++)
            if (maxSum < dp[0, j])
                maxSum = dp[0, j];
      
        // required maximum sum
        return maxSum;
    }
  
    // Driver code
    public static void Main () {
      
    int [,]mat = { { 5, 6, 1, 7 },
                    { -2, 10, 8, -1 },
                    { 3, -7, -9, 11 },
                    { 12, -4, 2, 6 } };
    int n = 4;
  
    Console.WriteLine("Maximum Sum = "+
                        maxSum(mat , n));
  
    }
}
  
// This code is contributed by vt_m

PHP

<?php
// PHP implementation to find 
// the maximum sum path in a matrix
  
$SIZE = 10;
  
// function to find the maximum sum
// path in a matric
function maxSum( $mat, $n)
{
      
    // if there is a single
    // element only
    if ($n == 1)
        return $mat[0][0];

1808
Chapter 246. Maximum sum path in a matrix from top to bottom

  
    // dp[][] matrix to store the results
    // of each iteration
    $dp = array(array());
    $maxSum = PHP_INT_MIN;
    $max;
  
    // base case, copying elements of
    // last row
    for($j = 0; $j < $n; $j++)
        $dp[$n - 1][$j] = $mat[$n - 1][$j];
  
    // building up the dp[][] matrix from
    // bottom to the top row
    for ( $i = $n - 2; $i >= 0; $i--) 
    {
        for ( $j = 0; $j < $n; $j++)
        {
            $max = PHP_INT_MIN;
  
            // finding the maximum 
            // diagonal element in the
            // (i+1)th row if that cell 
            // exists
            if ((($j - 1) >= 0) and 
                ($max < $dp[$i + 1][$j - 1]))
                  
                $max = $dp[$i + 1][$j - 1];
                  
            if ((($j + 1) < $n) and ($max < 
                      $dp[$i + 1][$j + 1]))
                        
                $max = $dp[$i + 1][$j + 1];
  
            // adding that 'max' element to the
            // mat[i][j] element
            $dp[$i][$j] = $mat[$i][$j] + $max;
        }
    }
  
    // finding the maximum value from the
    // first row of dp[][]
    for ( $j = 0; $j < $n; $j++)
        if ($maxSum < $dp[0][$j])
            $maxSum = $dp[0][$j];
  
    // required maximum sum
    return $maxSum;

1809
Chapter 246. Maximum sum path in a matrix from top to bottom

}
  
    // Driver Code
    $mat = array(array(5, 6, 1, 7),
                 array(-2, 10, 8, -1),
                 array(3, -7, -9, 11),
                 array(12, -4, 2, 6));
    $n = 4;
    echo "Maximum Sum = "
        , maxSum($mat, $n);
  
// This code is contributed by anuj_67.
?>

Output:

Maximum Sum = 28

Time Complexity: O(n2 ).


Auxiliary Space: O(n2 ).
Exercise: Try to solve it in auxiliary space of O(n).
Improved By : vt_m

Source

https://www.geeksforgeeks.org/maximum-sum-path-matrix-top-bottom/

1810
Chapter 247

Maximum sum subarray


removing at most one element

Maximum sum subarray removing at most one element - GeeksforGeeks


Given an array, we need to find maximum sum subarray, removing one element is also
allowed to get the maximum sum.
Examples :

Input : arr[] = {1, 2, 3, -4, 5}


Output : 11
Explanation : We can get maximum sum subarray by
removing -4.

Input : arr[] = [-2, -3, 4, -1, -2, 1, 5, -3]


Output : 9
Explanation : We can get maximum sum subarray by
removing -2 as, [4, -1, 1, 5] summing 9, which is
the maximum achievable sum.

If element removal condition is not applied, we can solve this problem using Kadane’s
algorithm but here one element can be removed also for increasing maximum sum. This
condition can be handled using two arrays, forward and backward array, these arrays store
the current maximum subarray sum from starting to ith index, and from ith index to
ending respectively.
In below code, two loops are written, first one stores maximum current sum in forward
direction in fw[] and other loop stores the same in backward direction in bw[]. Getting
current maximum and updation is same as Kadane’s algorithm.
Now when both arrays are created, we can use them for one element removal conditions as
follows, at each index i, maximum subarray sum after ignoring i’th element will be fw[i-1]
+ bw[i+1] so we loop for all possible i values and we choose maximum among them.

1811
Chapter 247. Maximum sum subarray removing at most one element

Total time complexity and space complexity of solution is O(N)

C/C++

// C++ program to get maximum sum subarray removing


// at-most one element
#include <bits/stdc++.h>
using namespace std;
  
// Method returns maximum sum of all subarray where
// removing one element is also allowed
int maxSumSubarrayRemovingOneEle(int arr[], int n)
{
    // Maximum sum subarrays in forward and backward
    // directions
    int fw[n], bw[n];
  
    // Initialize current max and max so far.
    int cur_max = arr[0], max_so_far = arr[0];
  
    // calculating maximum sum subarrays in forward
    // direction
    fw[0] = arr[0];
    for (int i = 1; i < n; i++)
    {
        cur_max = max(arr[i], cur_max + arr[i]);
        max_so_far = max(max_so_far, cur_max);
  
        // storing current maximum till ith, in
        // forward array
        fw[i] = cur_max;
    }
  
    // calculating maximum sum subarrays in backward
    // direction
    cur_max = max_so_far = bw[n-1] = arr[n-1];
    for (int i = n-2; i >= 0; i--)
    {
        cur_max = max(arr[i], cur_max + arr[i]);
        max_so_far = max(max_so_far, cur_max);
  
        // storing current maximum from ith, in
        // backward array
        bw[i] = cur_max;
    }
  
    /*  Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum

1812
Chapter 247. Maximum sum subarray removing at most one element

        subarray is also handled  */


    int fans = max_so_far;
  
    //  choosing maximum ignoring ith element
    for (int i = 1; i < n - 1; i++)
        fans = max(fans, fw[i - 1] + bw[i + 1]);
  
    return fans;
}
  
//  Driver code to test above methods
int main()
{
    int arr[] = {-2, -3, 4, -1, -2, 1, 5, -3};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSumSubarrayRemovingOneEle(arr, n);
    return 0;
}

Java

// Java program to get maximum sum subarray 


// removing at-most one element
class GFG {
      
    // Method returns maximum sum of all subarray where
    // removing one element is also allowed
    static int maxSumSubarrayRemovingOneEle(int arr[], 
                                                 int n)
    {
          
        // Maximum sum subarrays in forward and 
        // backward directions
        int fw[] = new int[n];
        int bw[] = new int[n];
  
        // Initialize current max and max so far.
        int cur_max = arr[0], max_so_far = arr[0];
  
        // calculating maximum sum subarrays in forward
        // direction
        fw[0] = arr[0];
  
        for (int i = 1; i < n; i++) {
  
            cur_max = Math.max(arr[i], cur_max + arr[i]);
            max_so_far = Math.max(max_so_far, cur_max);
  

1813
Chapter 247. Maximum sum subarray removing at most one element

            // storing current maximum till ith, in


            // forward array
            fw[i] = cur_max;
        }
  
        // calculating maximum sum subarrays in backward
        // direction
        cur_max = max_so_far = bw[n - 1] = arr[n - 1];
          
        for (int i = n - 2; i >= 0; i--) {
  
            cur_max = Math.max(arr[i], cur_max + arr[i]);
            max_so_far = Math.max(max_so_far, cur_max);
  
            // storing current maximum from ith, in
            // backward array
            bw[i] = cur_max;
        }
  
        /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
        int fans = max_so_far;
  
        // choosing maximum ignoring ith element
        for (int i = 1; i < n - 1; i++)
            fans = Math.max(fans, fw[i - 1] + bw[i + 1]);
  
        return fans;
    }
      
    // Driver code
    public static void main(String arg[])
    {
        int arr[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = arr.length;
          
        System.out.print(maxSumSubarrayRemovingOneEle(
                                             arr, n));
    }
}
  
// This code is contributed by Anant Agarwal.

Python

# Python program to get maximum sum subarray removing


# at-most one element

1814
Chapter 247. Maximum sum subarray removing at most one element

  
# Method returns maximum sum of all subarray where
# removing one element is also allowed
def maxSumSubarrayRemovingOneEle(arr, n):
    # Maximum sum subarrays in forward and backward
    # directions
    fw = [0 for k in range(n)]
    bw = [0 for k in range(n)]
   
    # Initialize current max and max so far.
    cur_max, max_so_far = arr[0], arr[0]
   
    # calculating maximum sum subarrays in forward
    # direction
    for i in range(n):
        cur_max = max(arr[i], cur_max + arr[i])
        max_so_far = max(max_so_far, cur_max)
   
        # storing current maximum till ith, in
        # forward array
        fw[i] = cur_max
   
    # calculating maximum sum subarrays in backward
    # direction
    cur_max = max_so_far = bw[n-1] = arr[n-1]
    i = n-2
    while i >= 0:
        cur_max = max(arr[i], cur_max + arr[i])
        max_so_far = max(max_so_far, cur_max)
   
        # storing current maximum from ith, in
        # backward array
        bw[i] = cur_max
        i -= 1
   
    #  Initializing final ans by max_so_far so that,
    #  case when no element is removed to get max sum
    #  subarray is also handled
    fans = max_so_far
   
    #  choosing maximum ignoring ith element
    for i in range(1,n-1):
        fans = max(fans, fw[i - 1] + bw[i + 1])
   
    return fans
   
#  Driver code to test above methods
arr = [-2, -3, 4, -1, -2, 1, 5, -3]

1815
Chapter 247. Maximum sum subarray removing at most one element

n = len(arr)
print  maxSumSubarrayRemovingOneEle(arr, n)
  
# Contributed by: Afzal_Saan

C#

// C# program to get maximum sum subarray 


// removing at-most one element
using System;
class GFG {
      
    // Method returns maximum sum of all subarray where
    // removing one element is also allowed
    static int maxSumSubarrayRemovingOneEle(int []arr, 
                                                int n)
    {
          
        // Maximum sum subarrays in forward and 
        // backward directions
        int []fw = new int[n];
        int []bw = new int[n];
  
        // Initialize current max and max so far.
        int cur_max = arr[0], max_so_far = arr[0];
  
        // calculating maximum sum subarrays in forward
        // direction
        fw[0] = arr[0];
  
        for (int i = 1; i < n; i++) {
  
            cur_max = Math.Max(arr[i], cur_max + arr[i]);
            max_so_far = Math.Max(max_so_far, cur_max);
  
            // storing current maximum till ith, in
            // forward array
            fw[i] = cur_max;
        }
  
        // calculating maximum sum subarrays in backward
        // direction
        cur_max = max_so_far = bw[n - 1] = arr[n - 1];
          
        for (int i = n - 2; i >= 0; i--) {
  
            cur_max = Math.Max(arr[i], cur_max + arr[i]);
            max_so_far = Math.Max(max_so_far, cur_max);

1816
Chapter 247. Maximum sum subarray removing at most one element

  
            // storing current maximum from ith, in
            // backward array
            bw[i] = cur_max;
        }
  
        /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
        int fans = max_so_far;
  
        // choosing maximum ignoring ith element
        for (int i = 1; i < n - 1; i++)
            fans = Math.Max(fans, fw[i - 1] + bw[i + 1]);
  
        return fans;
    }
      
    // Driver code
    public static void Main()
    {
        int []arr = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = arr.Length;
          
        Console.WriteLine(maxSumSubarrayRemovingOneEle(
                                            arr, n));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to get maximum 
// sum subarray removing
// at-most one element
  
// Method returns maximum sum 
// of all subarray where removing 
// one element is also allowed
function maxSumSubarrayRemovingOneEle( $arr, $n)
{
    // Maximum sum subarrays in 
    // forward and backward directions
    $fw = array(); $bw = array();
  
    // Initialize current 

1817
Chapter 247. Maximum sum subarray removing at most one element

    // max and max so far.


    $cur_max = $arr[0]; 
    $max_so_far = $arr[0];
  
    // calculating maximum sum 
    // subarrays in forward direction
    $fw[0] = $arr[0];
    for ($i = 1; $i < $n; $i++)
    {
        $cur_max = max($arr[$i], 
                       $cur_max + $arr[$i]);
        $max_so_far = max($max_so_far, 
                          $cur_max);
  
        // storing current maximum till 
        // ith, in forward array
        $fw[$i] = $cur_max;
    }
  
    // calculating maximum sum 
    // subarrays in backward direction
    $cur_max = $max_so_far = 
    $bw[$n - 1] = $arr[$n - 1];
    for ( $i = $n - 2; $i >= 0; $i--)
    {
        $cur_max = max($arr[$i], 
                       $cur_max + $arr[$i]);
        $max_so_far = max($max_so_far, 
                          $cur_max);
  
        // storing current maximum from 
        // ith, in backward array
        $bw[$i] = $cur_max;
    }
  
    /* Initializing final ans by 
        max_so_far so that, case 
        when no element is removed 
        to get max sum subarray is 
        also handled */
    $fans = $max_so_far;
  
    // choosing maximum 
    // ignoring ith element
    for ($i = 1; $i < $n - 1; $i++)
        $fans = max($fans, $fw[$i - 1] + 
                           $bw[$i + 1]);
  

1818
Chapter 247. Maximum sum subarray removing at most one element

    return $fans;
}
  
// Driver Code
$arr = array(-2, -3, 4, -1, 
             -2, 1, 5, -3);
$n = count($arr);
echo maxSumSubarrayRemovingOneEle($arr, $n);
  
// This code is contributed by anuj_67.
?>

Output :

Time Complexity : O(n)


Auxiliary Space : O(n)
Improved By : vt_m

Source

https://www.geeksforgeeks.org/maximum-sum-subarray-removing-one-element/

1819
Chapter 248

Maximum sum subsequence


with at-least k distant elements

Maximum sum subsequence with at-least k distant elements - GeeksforGeeks


Given an array and a number k, find a subsequence such that
Sum of elements in subsequence is maximum
Indices of elements of subsequence differ atleast by k
Examples

Input : arr[] = {4, 5, 8, 7, 5, 4, 3, 4, 6, 5}


k = 2
Output: 19
Explanation: The highest value is obtained
if you pick indices 1, 4, 7, 10 giving
4 + 7 + 3 + 5 = 19

Input: arr[] = {50, 70, 40, 50, 90, 70, 60,


40, 70, 50}
k = 2
Output: 230
Explanation: There are 10 elements and k = 2.
If you select 2, 5, and 9 you get a total
value of 230, which is the maximum possible.

A simple solution is to considerall subsequences one by one. In every subsequence, check


for distance condition and return the maximum sum subsequence.
An efficient solution is to use dynamic programming.
There are two cases:

1820
Chapter 248. Maximum sum subsequence with at-least k distant elements

1. If we select element at index i such that i + k + 1 >= N, then we cannot select any
other element as part of the subsequence. Hence we need to decide whether to select
this element or one of the elements after it.
2. If we select element at index i such that i + k + 1 < N, then the next element we
can select is at i + k + 1 index. Thus we need to decide whether to select these two
elements, or move on to the next adjacent element.

These two cases can be written as:

Let MS[i] denotes the maximum sum of subsequence


from i = N-2 to 0.

Base Case:
MS[N-1] = arr[N-1]

If i + 1 + k >= N
MS[i] = max(arr[i], MS[i+1]),
Else
MS[i] = max(arr[i] + MS[i+k+1], MS[i+1])

Evidently, the solution to the problem


is to find MS[0].

Below is the implementation:

C++

// CPP program to find maximum sum subsequence


// such that elements are at least k distance
// away.
#include <bits/stdc++.h>
using namespace std;
  
int maxSum(int arr[], int N, int k)
{
    // MS[i] is going to store maximum sum
    // subsequence in subarray from arr[i]
    // to arr[n-1]
    int MS[N];
  
    // We fill MS from right to left.
    MS[N - 1] = arr[N - 1];
    for (int i = N - 2; i >= 0; i--) {
        if (i + k + 1 >= N)
            MS[i] = max(arr[i], MS[i + 1]);
        else
            MS[i] = max(arr[i] + MS[i + k + 1], MS[i + 1]);

1821
Chapter 248. Maximum sum subsequence with at-least k distant elements

    }
  
    return MS[0];
}
  
// Driver code
int main()
{
    int N = 10, k = 2;
    int arr[] = { 50, 70, 40, 50, 90, 70, 60, 40, 70, 50 };
    cout << maxSum(arr, N, k);
    return 0;
}

Java

// Java program to find maximum sum subsequence


// such that elements are at least k distance
// away.
import java.io.*;
  
class GFG {
  
    static int maxSum(int arr[], int N, int k)
    {
        // MS[i] is going to store maximum sum
        // subsequence in subarray from arr[i]
        // to arr[n-1]
        int MS[] = new int[N];
  
        // We fill MS from right to left.
        MS[N - 1] = arr[N - 1];
        for (int i = N - 2; i >= 0; i--) {
            if (i + k + 1 >= N)
                MS[i] = Math.max(arr[i], MS[i + 1]);
            else
                MS[i] = Math.max(arr[i] + MS[i + k + 1],
                                MS[i + 1]);
        }
  
        return MS[0];
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int N = 10, k = 2;
        int arr[] = { 50, 70, 40, 50, 90, 70, 60,

1822
Chapter 248. Maximum sum subsequence with at-least k distant elements

                      40, 70, 50 };
        System.out.println(maxSum(arr, N, k));
    }
}
// This code is contributed by Prerna Saini

Python3

   
# Python3 program to find maximum
# sum subsequence such that elements
# are at least k distance away.
  
def maxSum(arr, N, k):
  
    # MS[i] is going to store maximum sum
    # subsequence in subarray from arr[i]
    # to arr[n-1]
    MS = [0 for i in range(N)]
  
    # We fill MS from right to left.
    MS[N - 1] = arr[N - 1]
    for i in range(N - 2, -1, -1):
        if (i + k + 1 >= N):
            MS[i] = max(arr[i], MS[i + 1])
        else:
            MS[i] = max(arr[i] + MS[i + k + 1],
                                 MS[i + 1])
      
    return MS[0]
  
# Driver code
N = 10; k = 2
arr = [ 50, 70, 40, 50, 90, 70, 60, 40, 70, 50 ]
print(maxSum(arr, N, k))
      
# This code is contributed by Anant Agarwal.

C#

// C# program to find maximum sum


// subsequence such that elements
// are at least k distance away.
using System;
   
class GFG {
   

1823
Chapter 248. Maximum sum subsequence with at-least k distant elements

    static int maxSum(int []arr, int N, int k)


    {
        // MS[i] is going to store maximum sum
        // subsequence in subarray from arr[i]
        // to arr[n-1]
        int []MS = new int[N];
   
        // We fill MS from right to left.
        MS[N - 1] = arr[N - 1];
        for (int i = N - 2; i >= 0; i--) {
              
            if (i + k + 1 >= N)
                MS[i] = Math.Max(arr[i], MS[i + 1]);
            else
                MS[i] = Math.Max(arr[i] + MS[i + k + 1],
                                MS[i + 1]);
        }
   
        return MS[0];
    }
   
    // Driver code
    public static void Main()
    {
        int N = 10, k = 2;
        int []arr = { 50, 70, 40, 50, 90, 70, 60,
                                    40, 70, 50 };
        Console.WriteLine(maxSum(arr, N, k));
    }
}
  
// This code is contributed by Anant Agarwal.

PHP

<?php
// PHP program to find 
// maximum sum subsequence
// such that elements are 
// at least k distance
// away.
  
function maxSum($arr, $N, $k)
{
      
    // MS[i] is going to
    // store maximum sum
    // subsequence in 

1824
Chapter 248. Maximum sum subsequence with at-least k distant elements

    // subarray from arr[i]


    // to arr[n-1]
  
    // We fill MS from 
    // right to left.
    $MS[$N - 1] = $arr[$N - 1];
    for ($i = $N - 2; $i >= 0; $i--) 
    {
        if ($i + $k + 1 >= $N)
            $MS[$i] = max($arr[$i], 
                      $MS[$i + 1]);
        else
            $MS[$i] = max($arr[$i] + 
                      $MS[$i + $k + 1], 
                      $MS[$i + 1]);
    }
  
    return $MS[0];
}
  
// Driver code
$N = 10; $k = 2;
$arr = array(50, 70, 40, 50, 90, 
             70, 60, 40, 70, 50);
echo(maxSum($arr, $N, $k));
  
// This code is contributed by Ajit.
?>

Output:

230

Time Complexity : O(n)


Auxiliary Space : O(n)
Improved By : jit_t, Devesh Krishnani

Source

https://www.geeksforgeeks.org/maximum-sum-subsequence-least-k-distant-elements/

1825
Chapter 249

Maximum sum such that no two


elements are adjacent

Maximum sum such that no two elements are adjacent - GeeksforGeeks


Given an array of positive numbers, find the maximum sum of a subsequence with the
constraint that no 2 numbers in the sequence should be adjacent in the array. So 3 2 7 10
should return 13 (sum of 3 and 10) or 3 2 5 10 7 should return 15 (sum of 3, 5 and 7).Answer
the question in most efficient way.
Examples :

Input : arr[] = {5, 5, 10, 100, 10, 5}


Output : 110

Input : arr[] = {1, 2, 3}


Output : 4

Input : arr[] = {1, 20, 3}


Output : 20

Algorithm:
Loop for all elements in arr[] and maintain two sums incl and excl where incl = Max sum
including the previous element and excl = Max sum excluding the previous element.
Max sum excluding the current element will be max(incl, excl) and max sum including the
current element will be excl + current element (Note that only excl is considered because
elements cannot be adjacent).
At the end of the loop return max of incl and excl.
Example:

1826
Chapter 249. Maximum sum such that no two elements are adjacent

arr[] = {5, 5, 10, 40, 50, 35}

incl = 5
excl = 0

For i = 1 (current element is 5)


incl = (excl + arr[i]) = 5
excl = max(5, 0) = 5

For i = 2 (current element is 10)


incl = (excl + arr[i]) = 15
excl = max(5, 5) = 5

For i = 3 (current element is 40)


incl = (excl + arr[i]) = 45
excl = max(5, 15) = 15

For i = 4 (current element is 50)


incl = (excl + arr[i]) = 65
excl = max(45, 15) = 45

For i = 5 (current element is 35)


incl = (excl + arr[i]) = 80
excl = max(65, 45) = 65

And 35 is the last element. So, answer is max(incl, excl) = 80

Thanks to Debanjan for providing code.


Implementation:

C/C++

#include<stdio.h>
  
/*Function to return max sum such that no two elements
 are adjacent */
int FindMaxSum(int arr[], int n)
{
  int incl = arr[0];
  int excl = 0;
  int excl_new;
  int i;
  
  for (i = 1; i < n; i++)
  {
     /* current max excluding i */
     excl_new = (incl > excl)? incl: excl;

1827
Chapter 249. Maximum sum such that no two elements are adjacent

  
     /* current max including i */
     incl = excl + arr[i];
     excl = excl_new;
  }
  
   /* return max of incl and excl */
   return ((incl > excl)? incl : excl);
}
  
/* Driver program to test above function */
int main()
{
  int arr[] = {5, 5, 10, 100, 10, 5};
  int n = sizeof(arr) / sizeof(arr[0]);
  printf("%d n", FindMaxSum(arr, n));
  return 0;
}

Java

class MaximumSum
{
    /*Function to return max sum such that no two elements
      are adjacent */
    int FindMaxSum(int arr[], int n)
    {
        int incl = arr[0];
        int excl = 0;
        int excl_new;
        int i;
  
        for (i = 1; i < n; i++)
        {
            /* current max excluding i */
            excl_new = (incl > excl) ? incl : excl;
  
            /* current max including i */
            incl = excl + arr[i];
            excl = excl_new;
        }
  
        /* return max of incl and excl */
        return ((incl > excl) ? incl : excl);
    }
  
    // Driver program to test above functions
    public static void main(String[] args)

1828
Chapter 249. Maximum sum such that no two elements are adjacent

    {
        MaximumSum sum = new MaximumSum();
        int arr[] = new int[]{5, 5, 10, 100, 10, 5};
        System.out.println(sum.FindMaxSum(arr, arr.length));
    }
}
  
// This code has been contributed by Mayank Jaiswal

Python

# Function to return max sum such that 


# no two elements are adjacent
def find_max_sum(arr):
    incl = 0
    excl = 0
     
    for i in arr:
          
        # Current max excluding i (No ternary in 
        # Python)
        new_excl = excl if excl>incl else incl
         
        # Current max including i
        incl = excl + i
        excl = new_excl
      
    # return max of incl and excl
    return (excl if excl>incl else incl)
  
# Driver program to test above function
arr = [5, 5, 10, 100, 10, 5]
print find_max_sum(arr)
  
# This code is contributed by Kalai Selvan

C#

/* Program to return max sum such that no 


two elements are adjacent */
using System;
  
class GFG {
      
    /* Function to return max sum such
    that no two elements are adjacent */
    static int FindMaxSum(int []arr, int n)

1829
Chapter 249. Maximum sum such that no two elements are adjacent

    {
        int incl = arr[0];
        int excl = 0;
        int excl_new;
        int i;
  
        for (i = 1; i < n; i++)
        {
            /* current max excluding i */
            excl_new = (incl > excl) ? 
                            incl : excl;
  
            /* current max including i */
            incl = excl + arr[i];
            excl = excl_new;
        }
  
        /* return max of incl and excl */
        return ((incl > excl) ? 
                            incl : excl);
    }
  
    // Driver program to test above 
    // functions
    public static void Main()
    {
        int []arr = new int[]{5, 5, 10,
                              100, 10, 5};
                                
        Console.Write(
             FindMaxSum(arr, arr.Length));
    }
}
  
// This code has been contributed by
// nitin mittal

PHP

<?php
// PHP code to find Maximum sum 
// such that no two elements 
// are adjacent
  
/* Function to return max sum
   such that no two elements
   are adjacent */
function FindMaxSum($arr, $n)

1830
Chapter 249. Maximum sum such that no two elements are adjacent

{
    $incl = $arr[0];
    $excl = 0;
    $excl_new;
    $i;
  
for ($i = 1; $i <$n; $i++)
{
      
    // current max excluding i 
    $excl_new = ($incl > $excl)? $incl: $excl;
  
    // current max including i 
    $incl = $excl + $arr[$i];
    $excl = $excl_new;
}
  
// return max of incl and excl 
return (($incl > $excl)? $incl : $excl);
}
  
// Driver Code
$arr = array(5, 5, 10, 100, 10, 5);
$n = sizeof($arr);
echo FindMaxSum($arr, $n);
      
// This code is contributed by Ajit
?>

Output:

110

Time Complexity: O(n)


Refer Find maximum possible stolen value from houses for more explanation.
Now try the same problem for an array with negative numbers also.
Improved By : jit_t, nitin mittal, RimjhimBhadani

Source

https://www.geeksforgeeks.org/maximum-sum-such-that-no-two-elements-are-adjacent/

1831
Chapter 250

Maximum value with the choice


of either dividing or considering
as it is

Maximum value with the choice of either dividing or considering as it is - GeeksforGeeks


We are given a number n, we need to find the maximum sum possible with the help of
following function:
F(n) = max( (F(n/2) + F(n/3) + F(n/4) + F(n/5)), n). To calculate F(n, ) we
may either have n as our result or we can further break n into four part as in given function
definition. This can be done as much time as we can. Find the maximum possible sum you
can get from a given N. Note : 1 can not be break further so F(1) = 1 as a base case.
Examples :

Input : n = 10
Output : MaxSum = 12
Explanation:
f(10) = f(10/2) + f(10/3) + f(10/4) + f(10/5)
= f(5) + f(3) + f(2) + f(2)
= 12
5, 3 and 2 cannot be further divided.

Input : n = 2
Output : MaxSum = 2

Approach : This problem can be solve with recursive approach but that will cost us a high
complexity because of its overlapping sub problems. So we apply dynamic programming
concept to solve this question in bottom up manner as:
C++

1832
Chapter 250. Maximum value with the choice of either dividing or considering as it is

// CPP program for maximize result when


// we have choice to divide or consider
// as it is.
#include <bits/stdc++.h>
using namespace std;
  
// function for calculating max possible result
int maxDP(int n)
{
    int res[n + 1];
    res[0] = 0;
    res[1] = 1;
  
    // Compute remaining values in bottom
    // up manner.
    for (int i = 2; i <= n; i++)
        res[i] = max(i, (res[i / 2] + res[i / 3] + res[i / 4] + res[i / 5]));
  
    return res[n];
}
  
// driver program
int main()
{
    int n = 60;
    cout << "MaxSum =" << maxDP(n);
    return 0;
}

Java

// Java program for maximize result when


// we have choice to divide or consider
// as it is.
import java.io.*;
  
class GFG {
  
    // function for calculating max
    // possible result
    static int maxDP(int n)
    {
        int res[] = new int[n + 1];
        res[0] = 0;
        res[1] = 1;
  
        // Compute remaining values in
        // bottom up manner.

1833
Chapter 250. Maximum value with the choice of either dividing or considering as it is

        for (int i = 2; i <= n; i++)


            res[i] = Math.max(i, (res[i / 2] + res[i / 3] + res[i / 4] + res[i / 5]));
  
        return res[n];
    }
  
    // driver program
    public static void main(String[] args)
    {
        int n = 60;
        System.out.println("MaxSum = " + maxDP(n));
    }
}
  
// This code is contributed by vt_m

Python3

# Python3 code to maximize result when


# we have choice to divide or consider
# as it is.
  
# function for calculating max 
# possible result
def maxDP (n):
    res = list()
    res.append(0)
    res.append(1)
      
    # Compute remaining values in 
    # bottom up manner.
    i = 2
    while i<n + 1:
        res.append(max(i, (res[int(i / 2)] + res[int(i / 3)] +
                          res[int(i / 4)]+ res[int(i / 5)])))
        i = i + 1
      
    return res[n]
  
# driver code
n = 60
print("MaxSum =", maxDP(n))
  
# This code is contributed by "Sharad_Bhardwaj".

C#

// C# program for maximize result when

1834
Chapter 250. Maximum value with the choice of either dividing or considering as it is

// we have choice to divide or consider


// as it is.
using System;
  
class GFG {
  
    // function for calculating max
    // possible result
    static int maxDP(int n)
    {
        int[] res = new int[n + 1];
        res[0] = 0;
        res[1] = 1;
  
        // Compute remaining values in
        // bottom up manner.
        for (int i = 2; i <= n; i++)
            res[i] = Math.Max(i, (res[i / 2] + res[i / 3] + res[i / 4] + res[i / 5]));
  
        return res[n];
    }
  
    // Driver program
    public static void Main()
    {
        int n = 60;
        Console.WriteLine("MaxSum = " + maxDP(n));
    }
}
  
// This code is contributed by vt_m

PHP

<?php
  
// PHP program to maximize 
// result when we have choice
// to divide or consider as it is.
  
// function for calculating
// max possible result
  
function maxDP ($n)
{
  
    $res[0] = 0;
    $res[1] = 1;

1835
Chapter 250. Maximum value with the choice of either dividing or considering as it is

  
    // Compute remaining values  
    // in bottom up manner.
    for ($i = 2; $i <= $n; $i++)
    $res[$i] = max($i, ($res[$i / 2] + 
                        $res[$i / 3] + 
                        $res[$i / 4] + 
                        $res[$i / 5]));
  
    return $res[$n];
}
  
// Driver Code
$n = 60;
echo "MaxSum =", maxDP ($n);
  
// This code is contributed by aj_36
?>

Output :

MaxSum = 106

Improved By : jit_t

Source

https://www.geeksforgeeks.org/maximum-value-choice-either-dividing-considering/

1836
Chapter 251

Maximum weight path ending


at any element of last row in a
matrix

Maximum weight path ending at any element of last row in a matrix - GeeksforGeeks
Given a matrix of integers where every element represents weight of the cell. Find the path
having the maximum weight in matrix [N X N]. Path Traversal Rules are:

• It should begin from top left element.


• The path can end at any element of last row.
• We can move to following two cells from a cell (i, j).
1. Down Move : (i+1, j)
2. Diagonal Move : (i+1, j+1)

Examples:

Input : N = 5
mat[5][5] = {{ 4, 2 ,3 ,4 ,1 },
{ 2 , 9 ,1 ,10 ,5 },
{15, 1 ,3 , 0 ,20 },
{16 ,92, 41, 44 ,1},
{8, 142, 6, 4, 8} };
Output : 255
Path with max weight : 4 + 2 +15 + 92 + 142 = 255

The above problem can be recursively defined.

1837
Chapter 251. Maximum weight path ending at any element of last row in a matrix

Let maxCost(i, j) be the cost maximum cost to


reach mat[i][j]. Since end point can be any point
in last row, we finally return maximum of all values
maxCost(N-1, j) where j varies from 0 to N-1.

If i == 0 and j == 0
maxCost(0, 0) = mat[0][0]

// We can traverse through first column only by


// down move
Else if j = 0
maxCost(i, 0) = maxCost(i-1, 0) + mat[i][0]

// In other cases, a cell mat[i][j] can be reached


// through previous two cells ma[i-1][j] and
// mat[i-1][j-1]
Else
maxCost(i, j) = mat[i][j] + max(maxCost(i-1, j),
maxCost(i-1, j-1)),

If we draw recursion tree of above recursive solution, we can observe overlapping subprob-
lems. Since the problem has overlapping subproblems, we can solve it efficiently using
Dynamic Programming. Below is Dynamic Programming based solution.
C++

// C++ program to find the path having the


// maximum weight in matrix
#include<bits/stdc++.h>
using namespace std;
const int MAX = 1000;
  
/* Function which return the maximum weight
   path sum */
int maxCost(int mat[][MAX], int N)
{
    // creat 2D matrix to store the sum of the path
    int dp[N][N];
    memset(dp, 0, sizeof(dp));
  
    dp[0][0] = mat[0][0];
  
    // Initialize first column of total weight
    // array (dp[i to N][0])
    for (int i=1; i<N; i++)
        dp[i][0] = mat[i][0] + dp[i-1][0];
  

1838
Chapter 251. Maximum weight path ending at any element of last row in a matrix

    // Calculate rest paht sum of weight matrix


    for (int i=1; i<N; i++)
       for (int j=1; j<i+1&&j<N; j++)
          dp[i][j] = mat[i][j] +
                    max(dp[i-1][j-1], dp[i-1][j]);
  
    // find the max weight path sum to rech
    // the last row
    int result = 0;
    for (int i=0; i<N; i++)
        if (result < dp[N-1][i])
            result = dp[N-1][i];
  
    // return maximum weight path sum
    return result;
}
  
// Driver program
int main()
{
    int mat[MAX][MAX] = {  { 4, 1 ,5 ,6 , 1 },
        { 2 ,9 ,2 ,11 ,10 },
        { 15,1 ,3 ,15, 2 },
        { 16, 92, 41,4,3},
        { 8, 142, 6, 4, 8 }
    };
    int N = 5;
    cout << "Maximum Path Sum : "
        << maxCost(mat, N)<<endl;
    return 0;
}

Java

// JAVA Code for Maximum weight path ending at 


// any element of last row in a matrix
import java.util.*;
  
class GFG {
      
    /* Function which return the maximum weight
       path sum */
    public static int maxCost(int mat[][], int N)
    {
        // create 2D matrix to store the sum of 
        // the path
        int dp[][]=new int[N][N];
          

1839
Chapter 251. Maximum weight path ending at any element of last row in a matrix

        dp[0][0] = mat[0][0];
       
        // Initialize first column of total 
        // weight array (dp[i to N][0])
        for (int i = 1; i < N; i++)
            dp[i][0] = mat[i][0] + dp[i-1][0];
       
        // Calculate rest path sum of weight matrix
        for (int i = 1; i < N; i++)
           for (int j = 1; j < i + 1 && j < N; j++)
              dp[i][j] = mat[i][j] +
                        Math.max(dp[i-1][j-1], 
                                 dp[i-1][j]);
       
        // find the max weight path sum to reach
        // the last row
        int result = 0;
        for (int i = 0; i < N; i++)
            if (result < dp[N-1][i])
                result = dp[N-1][i];
       
        // return maximum weight path sum
        return result;
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int mat[][] = {  { 4, 1 ,5 ,6 , 1 },
                { 2 ,9 ,2 ,11 ,10 },
                { 15,1 ,3 ,15, 2 },
                { 16, 92, 41,4,3},
                { 8, 142, 6, 4, 8 }
            };
            int N = 5;
           System.out.println("Maximum Path Sum : "+ 
                               maxCost(mat, N));
    }
}
// This code is contributed by Arnav Kr. Mandal.  

Python3

# Python3 program to find the path 


# having the maximum weight in matrix
  
MAX = 1000
  

1840
Chapter 251. Maximum weight path ending at any element of last row in a matrix

# Function which return the 


# maximum weight path sum
def maxCost(mat, N):
      
    # creat 2D matrix to store the sum of the path
    dp = [[0 for i in range(N)] for j in range(N)]
  
    dp[0][0] = mat[0][0]
  
    # Initialize first column of total weight
    # array (dp[i to N][0])
    for i in range(1, N):
        dp[i][0] = mat[i][0] + dp[i - 1][0]
  
    # Calculate rest path sum of weight matrix
    for i in range(1, N):
        for j in range(1, min(i + 1, N)):
            dp[i][j] = mat[i][j] + \
                       max(dp[i - 1][j - 1],
                           dp[i - 1][j])
  
    # find the max weight path sum to reach
    # the last row
    result = 0
    for i in range(N):
        if (result < dp[N - 1][i]):
            result = dp[N - 1][i]
  
    # return maximum weight path sum
    return result
  
# Driver Program
  
mat = [ [4, 1 ,5 ,6 , 1],
        [2 ,9 ,2 ,11 ,10],
        [15,1 ,3 ,15, 2],
        [16, 92, 41,4,3],
        [8, 142, 6, 4, 8]]
  
N = 5
print('Maximum Path Sum :', maxCost(mat, N))
  
# This code is contributed by Soumen Ghosh.

C#

// C# Code for Maximum weight path


// ending at any element of last

1841
Chapter 251. Maximum weight path ending at any element of last row in a matrix

// row in a matrix
using System;
  
class GFG {
      
    /* Function which return the
    maximum weight path sum */
    public static int maxCost(int [,] mat, int N)
    {
          
        // create 2D matrix to store the 
        // sum of the path
        int [,] dp = new int[N,N];
          
        dp[0,0] = mat[0,0];
      
        // Initialize first column of total 
        // weight array (dp[i to N][0])
        for (int i = 1; i < N; i++)
            dp[i,0] = mat[i,0] + dp[i-1,0];
      
        // Calculate rest path sum of weight matrix
        for (int i = 1; i < N; i++)
            for (int j = 1; j < i + 1 && j < N; j++)
                dp[i,j] = mat[i,j] +
                   Math.Max(dp[i-1,j-1], dp[i-1,j]);
      
        // find the max weight path sum to reach
        // the last row
        int result = 0;
          
        for (int i = 0; i < N; i++)
            if (result < dp[N-1,i])
                result = dp[N-1,i];
      
        // return maximum weight path sum
        return result;
    }
      
    /* Driver program to test above function */
    public static void Main() 
    {
        int [,] mat = { { 4, 1 ,5 ,6 , 1 },
                        { 2 ,9 ,2 ,11 ,10 },
                        { 15,1 ,3 ,15, 2 },
                        { 16, 92, 41,4,3},
                        { 8, 142, 6, 4, 8 }
                      };

1842
Chapter 251. Maximum weight path ending at any element of last row in a matrix

        int N = 5;
          
        Console.Write("Maximum Path Sum : " 
                           + maxCost(mat, N));
    }
}
  
// This code is contributed by KRV.

Output:

Maximum Path Sum : 255

Time complexity : O(N*N)


Improved By : KRV

Source

https://www.geeksforgeeks.org/maximum-weight-path-ending-element-last-row-matrix/

1843
Chapter 252

Maximum weight
transformation of a given string

Maximum weight transformation of a given string - GeeksforGeeks


Given a string consisting of only A’s and B’s. We can transform the given string to another
string by toggling any character. Thus many transformations of the given string are possible.
The task is to find Weight of the maximum weight transformation.
Weight of a sting is calculated using below formula.

Weight of string = Weight of total pairs +


weight of single characters -
Total number of toggles.

Two consecutive characters are considered as pair only if they


are different.
Weight of a single pair (both character are different) = 4
Weight of a single character = 1

Examples :

Input: str = "AA"


Output: 3
Transformations of given string are "AA", "AB", "BA" and "BB".
Maximum weight transformation is "AB" or "BA". And weight
is "One Pair - One Toggle" = 4-1 = 3.

Input: str = "ABB"

1844
Chapter 252. Maximum weight transformation of a given string

Output: 5
Transformations are "ABB", "ABA", "AAB", "AAA", "BBB",
"BBA", "BAB" and "BAA"
Maximum weight is of original string 4+1 (One Pair + 1
character)

If (n == 1)
maxWeight(str[0..n-1]) = 1

Else If str[0] != str[1]


// Max of two cases: First character considered separately
// First pair considered separately
maxWeight(str[0..n-1]) = Max (1 + maxWeight(str[1..n-1]),
4 + getMaxRec(str[2..n-1])
Else
// Max of two cases: First character considered separately
// First pair considered separately
// Since first two characters are same and a toggle is
// required to form a pair, 3 is added for pair instead
// of 4
maxWeight(str[0..n-1]) = Max (1 + maxWeight(str[1..n-1]),
3 + getMaxRec(str[2..n-1])

If we draw the complete recursion tree, we can observer that many subproblems are solved
again and again. Since same suproblems are called again, this problem has Overlapping
Subprolems property. So min square sum problem has both properties (see thisand this) of
a dynamic programming problem. Like other typical Dynamic Programming(DP) problems.
Below is a memoization based solution. A lookup table is used to see if a problem is already
computed.

C++

// C++ program to find maximum weight 


// transformation of a given string
#include<bits/stdc++.h>
using namespace std;
  
// Returns weight of the maximum 
// weight transformation
int getMaxRec(string &str, int i, int n, 
                           int lookup[])
{
    // Base case
    if (i >= n) return 0;
  

1845
Chapter 252. Maximum weight transformation of a given string

    //If this subproblem is already solved


    if (lookup[i] != -1) return lookup[i];
  
    // Don't make pair, so 
    // weight gained is 1
    int ans = 1 + getMaxRec(str, i + 1, n, 
                                  lookup);
  
    // If we can make pair
    if (i + 1 < n)
    {
    // If elements are dissmilar,
    // weight gained is 4
    if (str[i] != str[i+1])
        ans = max(4 + getMaxRec(str, i + 2, 
                                n, lookup), ans);
  
    // if elements are similar so for 
    // making a pair we toggle any of them.
    // Since toggle cost is 1 so 
    // overall weight gain becomes 3
    else ans = max(3 + getMaxRec(str, i + 2, 
                                 n, lookup), ans);
    }
  
    // save and return maximum
    // of above cases
    return lookup[i] = ans;
}
  
// Initializes lookup table 
// and calls getMaxRec()
int getMaxWeight(string str)
{
    int n = str.length();
  
    // Create and initialize lookup table
    int lookup[n];
    memset(lookup, -1, sizeof lookup);
  
    // Call recursive function
    return getMaxRec(str, 0, str.length(), 
                                 lookup);
}
  
// Driver Code
int main()
{

1846
Chapter 252. Maximum weight transformation of a given string

    string str = "AAAAABB";


    cout << "Maximum weight of a transformation of "
          << str << " is " << getMaxWeight(str);
    return 0;
}

C#

// C# program to find maximum 


// weight transformation of a
// given string
using System;
  
class GFG
{
// Returns wieght of the maximum 
// weight transformation
static int getMaxRec(string str, int i, 
                     int n, int []lookup)
{
    // Base case
    if (i >= n) return 0;
  
    //If this subproblem is already solved
    if (lookup[i] != -1) return lookup[i];
  
    // Don't make pair, so 
    // weight gained is 1
    int ans = 1 + getMaxRec(str, i + 1, 
                            n, lookup);
  
    // If we can make pair
    if (i + 1 < n)
    {
    // If elements are dissmilar, 
    // weight gained is 4
    if (str[i] != str[i + 1])
        ans = Math.Max(4 + getMaxRec(str, i + 2, 
                                     n, lookup), ans);
  
    // if elements are similar so for 
    // making a pair we toggle any of 
    // them. Since toggle cost is
    // 1 so overall weight gain becomes 3
    else ans = Math.Max(3 + getMaxRec(str, i + 2, 
                                      n, lookup), ans);
    }
  

1847
Chapter 252. Maximum weight transformation of a given string

    // save and return maximum


    // of above cases
    return lookup[i] = ans;
}
  
// Initializes lookup table
// and calls getMaxRec()
static int getMaxWeight(string str)
{
    int n = str.Length;
  
    // Create and initialize lookup table
    int[] lookup = new int[n];
    for(int i = 0 ; i < n ; i++)
    lookup[i] = -1;
  
    // Call recursive function
    return getMaxRec(str, 0, str.Length, 
                                 lookup);
}
  
// Driver Code
public static void Main()
{
    string str = "AAAAABB";
    Console.Write("Maximum weight of a" + 
                  " transformation of " +
                           str + " is " + 
                      getMaxWeight(str));
}
}
  
// This code is contributed by Sumit Sudhakar

Output:

Maximum weight of a transformation of AAAAABB is 11

Thanks to Gaurav Ahirwar for providing above solution.


Improved By : Sam007

Source

https://www.geeksforgeeks.org/maximum-weight-transformation-of-a-given-string/

1848
Chapter 253

Memoization (1D, 2D and 3D)

Memoization (1D, 2D and 3D) - GeeksforGeeks


Most of the Dynamic Programming problems are solved in two ways:

1. Tabulation: Bottom Up
2. Memoization: Top Down

One of the easier approaches to solve most of the problems in DP is to write the recursive
code at first and then write the Bottom-up Tabulation Method or Top-down Memoization
of the recursive function. The steps to write the DP solution of Top-down approach to any
problem is to:

1. Write the recursive code


2. Memoize the return value and use it to reduce recursive calls.

1-D Memoization
The first step will be to write the recursive code. In the program below, a program related
to recursion where only one parameter changes its value has been shown. Since only one
parameter is non-constant, this method is known as 1-D memoization. E.g., the Fibonacci
series problem to find the N-th term in the Fibonacci series. The recursive approach has
been discussed over here.
Given below is the recursive code to find the N-th term:
C++

// C++ program to find the Nth term


// of Fibonacci series
#include <bits/stdc++.h>
using namespace std;
  

1849
Chapter 253. Memoization (1D, 2D and 3D)

// Fibonacci Series using Recursion


int fib(int n)
{
  
    // Base case
    if (n <= 1)
        return n;
  
    // recursive calls
    return fib(n - 1) + fib(n - 2);
}
  
// Driver Code
int main()
{
    int n = 6;
    printf("%d", fib(n));
    return 0;
}

Java

// Java program to find the 


// Nth term of Fibonacci series
import java.io.*;
  
class GFG
{
      
// Fibonacci Series 
// using Recursion
static int fib(int n)
{
  
    // Base case
    if (n <= 1)
        return n;
  
    // recursive calls
    return fib(n - 1) +
           fib(n - 2);
}
  
// Driver Code
public static void main (String[] args) 
{
    int n = 6;
    System.out.println(fib(n));

1850
Chapter 253. Memoization (1D, 2D and 3D)

}
}
  
// This code is contributed
// by ajit

C#

// C# program to find 
// the Nth term of 
// Fibonacci series
using System;
  
class GFG
{
      
// Fibonacci Series 
// using Recursion
static int fib(int n)
{
    // Base case
    if (n <= 1)
        return n;
  
    // recursive calls
    return fib(n - 1) +
           fib(n - 2);
}
// Driver Code
static public void Main ()
{
    int n = 6;
    Console.WriteLine(fib(n));
}
}
  
// This code is contributed
// by akt_mit

PHP

<?php
// PHP program to find 
// the Nth term of 
// Fibonacci series
// using Recursion
  

1851
Chapter 253. Memoization (1D, 2D and 3D)

function fib($n)
{
  
    // Base case
    if ($n <= 1)
        return $n;
  
    // recursive calls
    return fib($n - 1) +
           fib($n - 2);
}
  
// Driver Code
$n = 6;
echo fib($n);
  
// This code is contributed 
// by ajit
?>

Output:

A common observation is that this implementation does a lot of repeated work (see the
following recursion tree). So this will consume a lot of time for finding the N-th Fibonacci
number if done.

fib(5)
/ \
fib(4) fib(3)
/ \ / \
fib(3) fib(2) fib(2) fib(1)
/ \ / \ / \
fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
/ \
fib(1) fib(0)

In the above tree fib(3), fib(2), fib(1), fib(0) all are called more then once.

The following problem has been solved using Tabulation method.


In the program below, the steps to write a Top-Down approach program has been
explained. Some modifications in the recursive program will reduce the complexity of the
program and give the desired result. If fib(x) has not occurred previously, then we store

1852
Chapter 253. Memoization (1D, 2D and 3D)

the value of fib(x) in an array term at index x and return term[x]. By memoizing
the return value of fib(x) at index x of an array, reduce the number of recursive calls at
the next step when fib(x) has already been called. So without doing further recursive calls
to compute the value of fib(x), return term[x] when fib(x) has already been computed
previously to avoid a lot of repeated work as shown in the tree.
Given below is the memoized recursive code to find the N-th term.

C++

// CPP program to find the Nth term


// of Fibonacci series
#include <bits/stdc++.h>
using namespace std;
int term[1000];
// Fibonacci Series using memoized Recursion
int fib(int n)
{
    // base case
    if (n <= 1)
        return n;
  
    // if fib(n) has already been computed
    // we do not do further recursive calls
    // and hence reduce the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
  
    else {
  
        // store the computed value of fib(n)
        // in an array term at index n to
        // so that it does not needs to be
        // precomputed again
        term[n] = fib(n - 1) + fib(n - 2);
  
        return term[n];
    }
}
  
// Driver Code
int main()
{
    int n = 6;
    printf("%d", fib(n));
    return 0;
}

1853
Chapter 253. Memoization (1D, 2D and 3D)

Java

// Java program to find 


// the Nth term of 
// Fibonacci series
import java.io.*;
  
class GFG 
{
      
// Fibonacci Series using
// memoized Recursion
static int fib(int n)
{
    int []term = new int [1000];
      
    // base case
    if (n <= 1)
        return n;
  
    // if fib(n) has already 
    // been computed we do not
    // do further recursive 
    // calls and hence reduce 
    // the number of repeated
    // work
    if (term[n] != 0)
        return term[n];
  
    else 
    {
  
        // store the computed value
        // of fib(n) in an array 
        // term at index n to so that 
        // it does not needs to be 
        // precomputed again
        term[n] = fib(n - 1) + 
                  fib(n - 2);
  
        return term[n];
    }
}
  
// Driver Code
public static void main (String[] args) 
{
    int n = 6;

1854
Chapter 253. Memoization (1D, 2D and 3D)

    System.out.println(fib(n));
}
}
  
// This code is contributed by ajit

Output:

If the recursive code has been written once, then memoization is just modifying the recursive
program and storing the return values to avoid repetitive calls of functions which have been
computed previously.
2-D Memoization
In the above program, the recursive function had only one argument whose value was
not constant after every function call. Below, an implementation where the recursive
program has two non-constant arguments has been shown.
For e.g., Program to solve the standard Dynamic Problem LCS problem when two strings are
given. The general recursive solution of the problem is to generate all subsequences of both
given sequences and find the longest matching subsequence. Total possible combinations
will be 2n . Hence recursive solution will take O(2n ). The approach to write the recursive
solution has been discussed here.
Given below is the recursive solution to the LCS problem:

C++

// A Naive recursive implementation of LCS problem


#include <bits/stdc++.h>
  
int max(int a, int b);
  
// Returns length of LCS for X[0..m-1], Y[0..n-1]
int lcs(char* X, char* Y, int m, int n)
{
    if (m == 0 || n == 0)
        return 0;
    if (X[m - 1] == Y[n - 1])
        return 1 + lcs(X, Y, m - 1, n - 1);
    else
        return max(lcs(X, Y, m, n - 1),
                  lcs(X, Y, m - 1, n));
}
  
// Utility function to get max of 2 integers

1855
Chapter 253. Memoization (1D, 2D and 3D)

int max(int a, int b)


{
    return (a > b) ? a : b;
}
  
// Driver Code
int main()
{
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
  
    int m = strlen(X);
    int n = strlen(Y);
  
    printf("Length of LCS is %dn", lcs(X, Y, m, n));
  
    return 0;
}

Output:

Length of LCS is 4n

Output:

Length of LCS is 4

Considering the above implementation, the following is a partial recursion tree for input
strings “AXYT” and “AYZX”

lcs("AXYT", "AYZX")
/ \
lcs("AXY", "AYZX") lcs("AXYT", "AYZ")
/ \ / \
lcs("AX", "AYZX") lcs("AXY", "AYZ") lcs("AXY", "AYZ") lcs("AXYT", "AY")

In the above partial recursion tree, lcs(“AXY”, “AYZ”) is being solved twice. On
drawing the complete recursion tree, it has been observed that there are many subproblems
which are solved again and again. So this problem has Overlapping Substructure property
and recomputation of same subproblems can be avoided by either using Memoization or
Tabulation. The tabulation method has been discussed here.
A common point of observation to use memoization in the recursive code will be the two
non-constant arguments M and N in every function call. The function has 4 arguments,
but 2 arguments are constant which do not affect the Memoization. The repetitive calls occur

1856
Chapter 253. Memoization (1D, 2D and 3D)

for N and M which have been called previously. So use a 2-D array to store the computed
lcs(m, n) value at arr[m-1][n-1] as the string index starts from 0. Whenever the function
with the same argument m and n are called again, we do not perform any further recursive
call and return arr[m-1][n-1] as the previous computation of the lcs(m, n) has already been
stored in arr[m-1][n-1], hence reducing the recursive calls that happen more then once.
Below is the implementation of the Memoization approach of the recursive code.

C++

// C++ program to memoize


// recursive implementation of LCS problem
#include <bits/stdc++.h>
int arr[1000][1000];
int max(int a, int b);
  
// Returns length of LCS for X[0..m-1], Y[0..n-1] */
// memoization applied in recursive solution
int lcs(char* X, char* Y, int m, int n)
{
    // base case
    if (m == 0 || n == 0)
        return 0;
  
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1] != -1)
        return arr[m - 1][n - 1];
  
    // if equal, then we store the value of the
    // function call
    if (X[m - 1] == Y[n - 1]) {
  
        // store it in arr to avoid further repetitive 
        // work in future function calls
        arr[m - 1][n - 1] = 1 + lcs(X, Y, m - 1, n - 1);
        return arr[m - 1][n - 1];
    }
    else {
        // store it in arr to avoid further repetitive 
        // work in future function calls
        arr[m - 1][n - 1] = max(lcs(X, Y, m, n - 1),
                                lcs(X, Y, m - 1, n));
        return arr[m - 1][n - 1];
    }
}
  
// Utility function to get max of 2 integers

1857
Chapter 253. Memoization (1D, 2D and 3D)

int max(int a, int b)


{
    return (a > b) ? a : b;
}
  
// Driver Code
int main()
{
    memset(arr, -1, sizeof(arr));
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
  
    int m = strlen(X);
    int n = strlen(Y);
  
    printf("Length of LCS is %d", lcs(X, Y, m, n));
  
    return 0;
}

Output:

Length of LCS is 4

3-D Memoization
In the above program, the recursive function had only two arguments whose value were not
constant after every function call. Below, an implementation where the recursive program
has three non-constant arguments is done.
For e.g., Program to solve the standard Dynamic Problem LCS problem for three strings.
The general recursive solution of the problem is to generate all subsequences of both given
sequences and find the longest matching subsequence. Total possible combinations will be
3n . Hence recursive solution will take O(3n ).
Given below is the recursive solution to the LCS problem:

C++

// A recursive implementation of LCS problem


// of three strings
#include <bits/stdc++.h>
int max(int a, int b);
  
// Returns length of LCS for X[0..m-1], Y[0..n-1]
int lcs(char* X, char* Y, char* Z, int m, int n, int o)
{
    // base case

1858
Chapter 253. Memoization (1D, 2D and 3D)

    if (m == 0 || n == 0 || o == 0)
        return 0;
  
    // if equal, then check for next combination
    if (X[m - 1] == Y[n - 1] and Y[n - 1] == Z[o - 1]) {
  
        // recursive call
        return 1 + lcs(X, Y, Z, m - 1, n - 1, o - 1);
    }
    else {
  
        // return the maximum of the three other
        // possible states in recursion
        return max(lcs(X, Y, Z, m, n - 1, o),
                   max(lcs(X, Y, Z, m - 1, n, o),
                       lcs(X, Y, Z, m, n, o - 1)));
    }
}
  
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
  
// Driver Code
int main()
{
  
    char X[] = "geeks";
    char Y[] = "geeksfor";
    char Z[] = "geeksforge";
    int m = strlen(X);
    int n = strlen(Y);
    int o = strlen(Z);
    printf("Length of LCS is %d", lcs(X, Y, Z, m, n, o));
  
    return 0;
}

Output:

Length of LCS is 5

The tabulation method has been shown here. On drawing the recursion tree completely, it
has been noticed that there are many overlapping sub-problems which are been calculated

1859
Chapter 253. Memoization (1D, 2D and 3D)

multiple times. Since the function parameter has three non-constant parameters, hence a
3-D array will be used to memoize the value that was returned when lcs(x, y, z, m, n,
o) for any value of m, n and o was called so that if lcs(x, y, z, m, n, o) is again called
for the same value of m, n and o then the function will return the already stored value as
it has been computed previously in the recursive call. arr[m][n][o] stores the value returned
by the lcs(x, y, z, m, n, o) function call. The only modification that needs to be done in
the recursive program is to store the return value of (m, n, o) state of the recursive function.
The rest remains the same in the above recursive program.
Below is the implementation of the Memoization approach of the recursive code:

C++

// A memoize recursive implementation of LCS problem


#include <bits/stdc++.h>
int arr[100][100][100];
int max(int a, int b);
  
// Returns length of LCS for X[0..m-1], Y[0..n-1] */
// memoization applied in recursive solution
int lcs(char* X, char* Y, char* Z, int m, int n, int o)
{
    // base case
    if (m == 0 || n == 0 || o == 0)
        return 0;
  
    // if the same state has already been
    // computed
    if (arr[m - 1][n - 1][o - 1] != -1)
        return arr[m - 1][n - 1][o - 1];
  
    // if equal, then we store the value of the
    // fucntion call
    if (X[m - 1] == Y[n - 1] and Y[n - 1] == Z[o - 1]) {
  
        // store it in arr to avoid further repetitive work
        // in future function calls
        arr[m - 1][n - 1][o - 1] = 1 + lcs(X, Y, Z, m - 1,
                                            n - 1, o - 1);
        return arr[m - 1][n - 1][o - 1];
    }
    else {
  
        // store it in arr to avoid further repetitive work
        // in future function calls
        arr[m - 1][n - 1][o - 1] =
                               max(lcs(X, Y, Z, m, n - 1, o),
                                 max(lcs(X, Y, Z, m - 1, n, o),

1860
Chapter 253. Memoization (1D, 2D and 3D)

                                    lcs(X, Y, Z, m, n, o - 1)));
        return arr[m - 1][n - 1][o - 1];
    }
}
  
// Utility function to get max of 2 integers
int max(int a, int b)
{
    return (a > b) ? a : b;
}
  
// Driver Code
int main()
{
    memset(arr, -1, sizeof(arr));
    char X[] = "geeks";
    char Y[] = "geeksfor";
    char Z[] = "geeksforgeeks";
    int m = strlen(X);
    int n = strlen(Y);
    int o = strlen(Z);
    printf("Length of LCS is %d", lcs(X, Y, Z, m, n, o));
  
    return 0;
}

Output:

Length of LCS is 5

Note: The array used to Memoize is initialized to some value (say -1) before the function
call to mark if the function with the same parameters has been previously called or not.
Improved By : jit_t

Source

https://www.geeksforgeeks.org/memoization-1d-2d-and-3d/

1861
Chapter 254

Minimal moves to form a string


by adding characters or
appending string itself

Minimal moves to form a string by adding characters or appending string itself - Geeks-
forGeeks
Given a string S, we need to write a program to check if it is possible to construct the given
string S by performing any of the below operations any number of times. In each step, we
can:

• Add any character at the end of the string.


• or, append the string to the string itself.

The above steps can be applied any number of times. We need to write a program to print
the minimum steps required to form the string.
Examples:

Input : aaaaaaaa
Output : 4
Explanation: move 1: add 'a' to form "a"
move 2: add 'a' to form "aa"
move 3: append "aa" to form "aaaa"
move 4: append "aaaa" to form "aaaaaaaa"

Input: aaaaaa
Output: 4
Explanation: move 1: add 'a' to form "a"
move 2: add 'a' to form "aa"

1862
Chapter 254. Minimal moves to form a string by adding characters or appending string
itself

move 3: add 'a' to form "aaa"


move 4: append "aaa" to form "aaaaaa"

Input: abcabca
Output: 5

The idea to solve this problem is to use Dynamic Programming to count the minimum
number of moves. Create an array named dp of size n, where n is the length of the input
string. dp[i] stores the minimum number of moves that are required to make substring (0…i).
According to the question there are two moves that are possible:

1. dp[i] = min(dp[i], dp[i-1] + 1) which signifies addition of characters.


2. dp[i*2+1] = min(dp[i]+1, dp[i*2+1]), appending of string is done if
s[0…i]==s[i+1..i*2+1]

Source

https://www.geeksforgeeks.org/minimal-moves-form-string-adding-characters-appending-string/

1863
Chapter 255

Minimum Cost Path with Left,


Right, Bottom and Up moves
allowed

Minimum Cost Path with Left, Right, Bottom and Up moves allowed - GeeksforGeeks
Given a two dimensional grid, each cell of which contains integer cost which represents a
cost to traverse through that cell, we need to find a path from top left cell to bottom right
cell by which total cost incurred is minimum.
Note : It is assumed that negative cost cycles do not exist in input matrix.
This problem is extension of below problem.
Min Cost Path with right and bottom moves allowed.
In previous problem only going right and bottom was allowed but in this problem we are
allowed to go bottom, up, right and left i.e. in all 4 direction.
Examples:

A cost grid is given in below diagram, minimum


cost to reach bottom right from top left
is 327 (= 31 + 10 + 13 + 47 + 65 + 12 + 18 +
6 + 33 + 11 + 20 + 41 + 20)

The chosen least cost path is shown in green.

It is not possible to solve this problem using dynamic programming similar to previous
problem because here current state depends not only on right and bottom cells but also on

1864
Chapter 255. Minimum Cost Path with Left, Right, Bottom and Up moves allowed

left and upper cells. We solve this problem using dijkstra’s algorithm. Each cell of grid
represents a vertex and neighbor cells adjacent vertices. We do not make an explicit graph
from these cells instead we will use matrix as it is in our dijkstra’s algorithm.
In below code Dijkstra’ algorithm’s implementation using C++ STL is used. The code
implemented below is changed to cope with matrix represented implicit graph. Please also
see use of dx and dy arrays in below code, these arrays are taken for simplifying the process
of visiting neighbor vertices of each cell.

// C++ program to get least cost path in a grid from


// top-left to bottom-right
#include <bits/stdc++.h>
using namespace std;
  
#define ROW 5
#define COL 5
  
// structure for information of each cell
struct cell
{
    int x, y;
    int distance;
    cell(int x, int y, int distance) :
        x(x), y(y), distance(distance) {}
};
  
// Utility method for comparing two cells
bool operator<(const cell& a, const cell& b)
{
    if (a.distance == b.distance)
    {
        if (a.x != b.x)
            return (a.x < b.x);
        else
            return (a.y < b.y);
    }
    return (a.distance < b.distance);
}
  
// Utility method to check whether a point is
// inside the grid or not
bool isInsideGrid(int i, int j)
{
    return (i >= 0 && i < COL && j >= 0 && j < ROW);
}
  
// Method returns minimum cost to reach bottom
// right from top left
int shortest(int grid[ROW][COL], int row, int col)

1865
Chapter 255. Minimum Cost Path with Left, Right, Bottom and Up moves allowed

{
    int dis[row][col];
  
    // initializing distance array by INT_MAX
    for (int i = 0; i < row; i++)
        for (int j = 0; j < col; j++)
            dis[i][j] = INT_MAX;
  
    // direction arrays for simplification of getting
    // neighbour
    int dx[] = {-1, 0, 1, 0};
    int dy[] = {0, 1, 0, -1};
  
    set<cell> st;
  
    // insert (0, 0) cell with 0 distance
    st.insert(cell(0, 0, 0));
  
    // initialize distance of (0, 0) with its grid value
    dis[0][0] = grid[0][0];
  
    // loop for standard dijkstra's algorithm
    while (!st.empty())
    {
        // get the cell with minimum distance and delete
        // it from the set
        cell k = *st.begin();
        st.erase(st.begin());
  
        // looping through all neighbours
        for (int i = 0; i < 4; i++)
        {
            int x = k.x + dx[i];
            int y = k.y + dy[i];
  
            // if not inside boundry, ignore them
            if (!isInsideGrid(x, y))
                continue;
  
            // If distance from current cell is smaller, then
            // update distance of neighbour cell
            if (dis[x][y] > dis[k.x][k.y] + grid[x][y])
            {
                // If cell is already there in set, then
                // remove its previous entry
                if (dis[x][y] != INT_MAX)
                    st.erase(st.find(cell(x, y, dis[x][y])));
  

1866
Chapter 255. Minimum Cost Path with Left, Right, Bottom and Up moves allowed

                // update the distance and insert new updated


                // cell in set
                dis[x][y] = dis[k.x][k.y] + grid[x][y];
                st.insert(cell(x, y, dis[x][y]));
            }
        }
    }
  
    // uncomment below code to print distance
    // of each cell from (0, 0)
    /*
    for (int i = 0; i < row; i++, cout << endl)
        for (int j = 0; j < col; j++)
            cout << dis[i][j] << " ";
    */
    // dis[row - 1][col - 1] will represent final
    // distance of bottom right cell from top left cell
    return dis[row - 1][col - 1];
}
  
// Driver code to test above methods
int main()
{
    int grid[ROW][COL] =
    {
        31, 100, 65, 12, 18,
        10, 13, 47, 157, 6,
        100, 113, 174, 11, 33,
        88, 124, 41, 20, 140,
        99, 32, 111, 41, 20
    };
  
    cout << shortest(grid, ROW, COL) << endl;
    return 0;
}

Output:

327

Source

https://www.geeksforgeeks.org/minimum-cost-path-left-right-bottom-moves-allowed/

1867
Chapter 256

Minimum Cost Polygon


Triangulation

Minimum Cost Polygon Triangulation - GeeksforGeeks


A triangulation of a convex polygon is formed by drawing diagonals between non-adjacent
vertices (corners) such that the diagonals never intersect. The problem is to find the cost
of triangulation with the minimum cost. The cost of a triangulation is sum of the weights
of its component triangles. Weight of each triangle is its perimeter (sum of lengths of all
sides)
See following example taken from thissource.

Two triangulations of the same convex pentagon. The triangulation on the left has a cost
of 8 + 2√2 + 2√5 (approximately 15.30), the one on the right has a cost of 4 + 2√2 + 4√5
(approximately 15.77).
This problem has recursive substructure. The idea is to divide the polygon into three parts:
a single triangle, the sub-polygon to the left, and the sub-polygon to the right. We try all
possible divisions like this and find the one that minimizes the cost of the triangle plus the
cost of the triangulation of the two sub-polygons.

Let Minimum Cost of triangulation of vertices from i to j be minCost(i, j)


If j <= i + 2 Then

1868
Chapter 256. Minimum Cost Polygon Triangulation

minCost(i, j) = 0
Else
minCost(i, j) = Min { minCost(i, k) + minCost(k, j) + cost(i, k, j) }
Here k varies from 'i+1' to 'j-1'

Cost of a triangle formed by edges (i, j), (j, k) and (k, j) is


cost(i, j, k) = dist(i, j) + dist(j, k) + dist(k, j)

Following is C++ implementation of above naive recursive formula.

// Recursive implementation for minimum cost convex polygon triangulation


#include <iostream>
#include <cmath>
#define MAX 1000000.0
using namespace std;
  
// Structure of a point in 2D plane
struct Point
{
    int x, y;
};
  
// Utility function to find minimum of two double values
double min(double x, double y)
{
    return (x <= y)? x : y;
}
  
// A utility function to find distance between two points in a plane
double dist(Point p1, Point p2)
{
    return sqrt((p1.x - p2.x)*(p1.x - p2.x) +
                (p1.y - p2.y)*(p1.y - p2.y));
}
  
// A utility function to find cost of a triangle. The cost is considered
// as perimeter (sum of lengths of all edges) of the triangle
double cost(Point points[], int i, int j, int k)
{
    Point p1 = points[i], p2 = points[j], p3 = points[k];
    return dist(p1, p2) + dist(p2, p3) + dist(p3, p1);
}
  
// A recursive function to find minimum cost of polygon triangulation
// The polygon is represented by points[i..j].
double mTC(Point points[], int i, int j)
{
   // There must be at least three points between i and j

1869
Chapter 256. Minimum Cost Polygon Triangulation

   // (including i and j)


   if (j < i+2)
      return 0;
  
   // Initialize result as infinite
   double res = MAX;
  
   // Find minimum triangulation by considering all
   for (int k=i+1; k<j; k++)
        res = min(res, (mTC(points, i, k) + mTC(points, k, j) +
                        cost(points, i, k, j)));
   return  res;
}
  
// Driver program to test above functions
int main()
{
    Point points[] = {{0, 0}, {1, 0}, {2, 1}, {1, 2}, {0, 2}};
    int n = sizeof(points)/sizeof(points[0]);
    cout << mTC(points, 0, n-1);
    return 0;
}

Output:

15.3006

The above problem is similar to Matrix Chain Multiplication. The following is recursion
tree for mTC(points[], 0, 4).

1870
Chapter 256. Minimum Cost Polygon Triangulation

It can be easily seen in the above recursion tree that the problem has many overlapping sub-
problems. Since the problem has both properties: Optimal Substructure and Overlapping
Subproblems, it can be efficiently solved using dynamic programming.
Following is C++ implementation of dynamic programming solution.

// A Dynamic Programming based program to find minimum cost of convex


// polygon triangulation
#include <iostream>
#include <cmath>
#define MAX 1000000.0
using namespace std;
  
// Structure of a point in 2D plane
struct Point
{
    int x, y;
};
  
// Utility function to find minimum of two double values
double min(double x, double y)
{
    return (x <= y)? x : y;
}
  
// A utility function to find distance between two points in a plane
double dist(Point p1, Point p2)
{
    return sqrt((p1.x - p2.x)*(p1.x - p2.x) +
                (p1.y - p2.y)*(p1.y - p2.y));
}
  
// A utility function to find cost of a triangle. The cost is considered
// as perimeter (sum of lengths of all edges) of the triangle
double cost(Point points[], int i, int j, int k)
{
    Point p1 = points[i], p2 = points[j], p3 = points[k];
    return dist(p1, p2) + dist(p2, p3) + dist(p3, p1);
}
  
// A Dynamic programming based function to find minimum cost for convex
// polygon triangulation.
double mTCDP(Point points[], int n)
{
   // There must be at least 3 points to form a triangle
   if (n < 3)
      return 0;
  
   // table to store results of subproblems.  table[i][j] stores cost of

1871
Chapter 256. Minimum Cost Polygon Triangulation

   // triangulation of points from i to j.  The entry table[0][n-1] stores


   // the final result.
   double table[n][n];
  
   // Fill table using above recursive formula. Note that the table
   // is filled in diagonal fashion i.e., from diagonal elements to
   // table[0][n-1] which is the result.
   for (int gap = 0; gap < n; gap++)
   {
      for (int i = 0, j = gap; j < n; i++, j++)
      {
          if (j < i+2)
             table[i][j] = 0.0;
          else
          {
              table[i][j] = MAX;
              for (int k = i+1; k < j; k++)
              {
                double val = table[i][k] + table[k][j] + cost(points,i,j,k);
                if (table[i][j] > val)
                     table[i][j] = val;
              }
          }
      }
   }
   return  table[0][n-1];
}
  
// Driver program to test above functions
int main()
{
    Point points[] = {{0, 0}, {1, 0}, {2, 1}, {1, 2}, {0, 2}};
    int n = sizeof(points)/sizeof(points[0]);
    cout << mTCDP(points, n);
    return 0;
}

Output:

15.3006

Time complexity of the above dynamic programming solution is O(n3 ).


Please note that the above implementations assume that the points of covnvex polygon are
given in order (either clockwise or anticlockwise)
Exercise:
Extend the above solution to print triangulation also. For the above example, the optimal
triangulation is 0 3 4, 0 1 3, and 1 2 3.

1872
Chapter 256. Minimum Cost Polygon Triangulation

Sources:
http://www.cs.utexas.edu/users/djimenez/utsa/cs3343/lecture12.html
http://www.cs.utoronto.ca/~heap/Courses/270F02/A4/chains/node2.html

Source

https://www.geeksforgeeks.org/minimum-cost-polygon-triangulation/

1873
Chapter 257

Minimum Cost To Make Two


Strings Identical

Minimum Cost To Make Two Strings Identical - GeeksforGeeks


Given two strings X and Y, and two values costX and costY. We need to find minimum cost
required to make the given two strings identical. We can delete characters from both the
strings. The cost of deleting a character from string X is costX and from Y is costY. Cost
of removing all characters from a string is same.
Examples :

Input : X = "abcd", Y = "acdb", costX = 10, costY = 20.


Output: 30
For Making both strings identical we have to delete
character 'b' from both the string, hence cost will
be = 10 + 20 = 30.

Input : X = "ef", Y = "gh", costX = 10, costY = 20.


Output: 60
For making both strings identical, we have to delete 2-2
characters from both the strings, hence cost will be =
10 + 10 + 20 + 20 = 60.

This problem is a variation of Longest Common Subsequence ( LCS ). The idea is simple,
we first find the length of longest common subsequence of strings X and Y. Now subtracting
len_LCS with lengths of individual strings gives us number of characters to be removed to
make them identical.

// Cost of making two strings identical is SUM of following two

1874
Chapter 257. Minimum Cost To Make Two Strings Identical

// 1) Cost of removing extra characters (other than LCS)


// from X[]
// 2) Cost of removing extra characters (other than LCS)
// from Y[]
Minimum Cost to make strings identical = costX * (m - len_LCS) +
costY * (n - len_LCS).

m ==> Length of string X


m ==> Length of string Y
len_LCS ==> Length of LCS Of X and Y.
costX ==> Cost of removing a character from X[]
costY ==> Cost of removing a character from Y[]

Note that cost of removing all characters from a string


is same.

Below is the implementation of above idea.

C++

/* C++ code to find minimum cost to make two strings


   identical */
#include<bits/stdc++.h>
using namespace std;
  
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int lcs(char *X, char *Y, int m, int n)
{
    int L[m+1][n+1];
  
    /* Following steps build L[m+1][n+1] in bottom
       up fashion. Note that L[i][j] contains length
       of LCS of X[0..i-1] and Y[0..j-1] */
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
  
            else if (X[i-1] == Y[j-1])
                L[i][j] = L[i-1][j-1] + 1;
  
            else
                L[i][j] = max(L[i-1][j], L[i][j-1]);
        }
    }

1875
Chapter 257. Minimum Cost To Make Two Strings Identical

  
    /* L[m][n] contains length of LCS for X[0..n-1] and
       Y[0..m-1] */
    return L[m][n];
}
  
// Returns cost of making X[] and Y[] identical.  costX is
// cost of removing a character from X[] and costY is cost
// of removing a character from Y[]/
int findMinCost(char X[], char Y[], int costX, int costY)
{
    // Find LCS of X[] and Y[]
    int m = strlen(X), n = strlen(Y);
    int len_LCS = lcs(X, Y, m, n);
  
    // Cost of making two strings identical is SUM of
    // following two
    //   1) Cost of removing extra characters
    //      from first string
    //   2) Cost of removing extra characters from
    //      second string
    return costX * (m - len_LCS) +
           costY * (n - len_LCS);
}
  
/* Driver program to test above function */
int main()
{
    char X[] = "ef";
    char Y[] = "gh";
    cout << "Minimum Cost to make two strings "
         << " identical is = " << findMinCost(X, Y, 10, 20);
    return 0;
}

Java

// Java code to find minimum cost to


// make two strings identical 
import java.io.*;
  
class GFG {
      
    // Returns length of LCS for X[0..m-1], Y[0..n-1] 
    static int lcs(String X, String Y, int m, int n)
    {
        int L[][]=new int[m + 1][n + 1];
      

1876
Chapter 257. Minimum Cost To Make Two Strings Identical

        /* Following steps build L[m+1][n+1] in bottom


        up fashion. Note that L[i][j] contains length
        of LCS of X[0..i-1] and Y[0..j-1] */
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    L[i][j] = 0;
      
                else if (X.charAt(i - 1) == Y.charAt(j - 1))
                    L[i][j] = L[i - 1][j - 1] + 1;
      
                else
                    L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]);
            }
        }
      
        // L[m][n] contains length of LCS 
        // for X[0..n-1] and Y[0..m-1] 
        return L[m][n];
    }
      
    // Returns cost of making X[] and Y[] identical. 
    // costX is cost of removing a character from X[] 
    // and costY is cost of removing a character from Y[]/
    static int findMinCost(String X, String Y, int costX, int costY)
    {
        // Find LCS of X[] and Y[]
        int m = X.length();
        int n = Y.length();
        int len_LCS;
        len_LCS = lcs(X, Y, m, n);
      
        // Cost of making two strings identical
        //  is SUM of following two
        // 1) Cost of removing extra characters
        // from first string
        // 2) Cost of removing extra characters
        // from second string
        return costX * (m - len_LCS) +
               costY * (n - len_LCS);
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        String X = "ef";

1877
Chapter 257. Minimum Cost To Make Two Strings Identical

        String Y = "gh";
        System.out.println( "Minimum Cost to make two strings "
                            + " identical is = " 
                            + findMinCost(X, Y, 10, 20));
          
    }
}
  
// This code is contributed by vt_m

C#

// C# code to find minimum cost to


// make two strings identical 
using System; 
  
class GFG {
      
    // Returns length of LCS for X[0..m-1], Y[0..n-1] 
    static int lcs(String X, String Y, int m, int n)
    {
        int [,]L = new int[m + 1, n + 1];
      
        /* Following steps build L[m+1][n+1] in bottom
           up fashion. Note that L[i][j] contains length
           of LCS of X[0..i-1] and Y[0..j-1] */
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    L[i,j] = 0;
      
                else if (X[i - 1] == Y[j - 1])
                    L[i,j] = L[i - 1,j - 1] + 1;
      
                else
                    L[i,j] = Math.Max(L[i - 1,j], L[i,j - 1]);
            }
        }
      
        // L[m][n] contains length of LCS 
        // for X[0..n-1] and Y[0..m-1] 
        return L[m,n];
    }
      
    // Returns cost of making X[] and Y[] identical.
    // costX is cost of removing a character from X[] 

1878
Chapter 257. Minimum Cost To Make Two Strings Identical

    // and costY is cost of removing a character from Y[]


    static int findMinCost(String X, String Y, 
                           int costX, int costY)
    {
        // Find LCS of X[] and Y[]
        int m = X.Length;
        int n = Y.Length;
        int len_LCS;
        len_LCS = lcs(X, Y, m, n);
      
        // Cost of making two strings identical
        // is SUM of following two
        // 1) Cost of removing extra characters
        // from first string
        // 2) Cost of removing extra characters
        // from second string
        return costX * (m - len_LCS) +
               costY * (n - len_LCS);
    }
      
    // Driver code
    public static void Main () 
    {
        String X = "ef";
        String Y = "gh";
        Console.Write( "Minimum Cost to make two strings " +
                       " identical is = " +
                       findMinCost(X, Y, 10, 20));
    }
}
  
// This code is contributed by nitin mittal.

Output:

Minimum Cost to make two strings identical is = 60

This article is contributed by Shashank Mishra ( Gullu ). This article is reviwed by


team geeksforgeeks.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
Improved By : nitin mittal

Source
https://www.geeksforgeeks.org/minimum-cost-make-two-strings-identical/

1879
Chapter 258

Minimum Initial Points to


Reach Destination

Minimum Initial Points to Reach Destination - GeeksforGeeks


Given a grid with each cell consisting of positive, negative or no points i.e, zero points. We
can move across a cell only if we have positive points ( > 0 ). Whenever we pass through
a cell, points in that cell are added to our overall points. We need to find minimum initial
points to reach cell (m-1, n-1) from (0, 0).
Constraints :

• From a cell (i, j) we can move to (i+1, j) or (i, j+1).


• We cannot move from (i, j) if your overall points at (i, j) is <= 0.
• We have to reach at (n-1, m-1) with minimum positive points i.e., > 0.

Input: points[m][n] = { {-2, -3, 3},


{-5, -10, 1},
{10, 30, -5}
};
Output: 7
Explanation:
7 is the minimum value to reach destination with
positive throughout the path. Below is the path.

(0,0) -> (0,1) -> (0,2) -> (1, 2) -> (2, 2)

We start from (0, 0) with 7, we reach(0, 1)


with 5, (0, 2) with 2, (1, 2) with 5, (2, 2)
with and finally we have 1 point (we needed
greater than 0 points at the end).

1880
Chapter 258. Minimum Initial Points to Reach Destination

At the first look, this problem looks similar Max/Min Cost Path, but maximum overall
points gained will not guarantee the minimum initial points. Also, it is compulsory in
the current problem that the points never drops to zero or below. For instance, Suppose
following two paths exists from source to destination cell.
We can solve this problem through bottom-up table filling dynamic programing technique.

• To begin with, we should maintain a 2D array dp of the same size as the grid, where
dp[i][j] represents the minimum points that guarantees the continuation of the journey
to destination before entering the cell (i, j). It’s but obvious that dp[0][0] is our final
solution. Hence, for this problem, we need to fill the table from the bottom right
corner to left top.
• Now, let us decide minimum points needed to leave cell (i, j) (remember we are
moving from bottom to up). There are only two paths to choose: (i+1, j) and (i,
j+1). Of course we will choose the cell that the player can finish the rest of his
journey with a smaller initial points. Therefore we have: min_Points_on_exit =
min(dp[i+1][j], dp[i][j+1])

Now we know how to compute min_Points_on_exit, but we need to fill the table dp[][] to
get the solution in dp[0][0].
How to compute dp[i][j]?
The value of dp[i][j] can be written as below.

dp[i][j] = max(min_Points_on_exit – points[i][j], 1)


Let us see how above expression covers all cases.

• If points[i][j] == 0, then nothing is gained in this cell; the player can leave the cell
with the same points as he enters the room with, i.e. dp[i][j] = min_Points_on_exit.
• If dp[i][j] < 0, then the player must have points greater than min_Points_on_exit be-
fore entering (i, j) in order to compensate for the points lost in this cell. The minimum
amount of compensation is ” – points[i][j] ”, so we have dp[i][j] = min_Points_on_exit
– points[i][j].
• If dp[i][j] > 0, then the player could enter (i, j) with points as little as
min_Points_on_exit – points[i][j]. since he could gain “points[i][j]” points in
this cell. However, the value of min_Points_on_exit – points[i][j] might drop to 0 or
below in this situation. When this happens, we must clip the value to 1 in order to
make sure dp[i][j] stays positive:
dp[i][j] = max(min_Points_on_exit – points[i][j], 1).

Finally return dp[0][0] which is our answer.


Below is the implementation of above algorithm.

C++

1881
Chapter 258. Minimum Initial Points to Reach Destination

// C++ program to find minimum initial points to reach destination


#include<bits/stdc++.h>
#define R 3
#define C 3
  
using namespace std;
  
int minInitialPoints(int points[][C])
{
    // dp[i][j] represents the minimum initial points player
    // should have so that when starts with cell(i, j) successfully
    // reaches the destination cell(m-1, n-1)
    int dp[R][C];
    int m = R, n = C;
  
    // Base case
    dp[m-1][n-1] = points[m-1][n-1] > 0? 1:
                   abs(points[m-1][n-1]) + 1;
  
    // Fill last row and last column as base to fill
    // entire table
    for (int i = m-2; i >= 0; i--)
         dp[i][n-1] = max(dp[i+1][n-1] - points[i][n-1], 1);
    for (int j = n-2; j >= 0; j--)
         dp[m-1][j] = max(dp[m-1][j+1] - points[m-1][j], 1);
  
    // fill the table in bottom-up fashion
    for (int i=m-2; i>=0; i--)
    {
        for (int j=n-2; j>=0; j--)
        {
            int min_points_on_exit = min(dp[i+1][j], dp[i][j+1]);
            dp[i][j] = max(min_points_on_exit - points[i][j], 1);
        }
     }
  
     return dp[0][0];
}
  
// Driver Program
int main()
{
  
    int points[R][C] = { {-2,-3,3},
                      {-5,-10,1},
                      {10,30,-5}
                    };
    cout << "Minimum Initial Points Required: "

1882
Chapter 258. Minimum Initial Points to Reach Destination

         << minInitialPoints(points);
    return 0;
}

Java

class min_steps
{
    static int minInitialPoints(int points[][],int R,int C)
    {
        // dp[i][j] represents the minimum initial points player
        // should have so that when starts with cell(i, j) successfully
        // reaches the destination cell(m-1, n-1)
        int dp[][] = new int[R][C];
        int m = R, n = C;
       
        // Base case
        dp[m-1][n-1] = points[m-1][n-1] > 0? 1:
                       Math.abs(points[m-1][n-1]) + 1;
       
        // Fill last row and last column as base to fill
        // entire table
        for (int i = m-2; i >= 0; i--)
             dp[i][n-1] = Math.max(dp[i+1][n-1] - points[i][n-1], 1);
        for (int j = n-2; j >= 0; j--)
             dp[m-1][j] = Math.max(dp[m-1][j+1] - points[m-1][j], 1);
       
        // fill the table in bottom-up fashion
        for (int i=m-2; i>=0; i--)
        {
            for (int j=n-2; j>=0; j--)
            {
                int min_points_on_exit = Math.min(dp[i+1][j], dp[i][j+1]);
                dp[i][j] = Math.max(min_points_on_exit - points[i][j], 1);
            }
         }
       
         return dp[0][0];
    }
  
    /* Driver program to test above function */ 
    public static void main (String args[])
    {
          int points[][] = { {-2,-3,3},
                      {-5,-10,1},
                      {10,30,-5}
                    };
          int R = 3,C = 3;

1883
Chapter 258. Minimum Initial Points to Reach Destination

          System.out.println("Minimum Initial Points Required: "+


                                            minInitialPoints(points,R,C) );
    }
}/* This code is contributed by Rajat Mishra */

C#

// C# program Minimum Initial Points


// to Reach Destination
using System;
class GFG {
      
    static int minInitialPoints(int [,]points, 
                                 int R, int C)
    {
          
        // dp[i][j] represents the 
        // minimum initial points 
        // player should have so 
        // that when starts with 
        // cell(i, j) successfully
        // reaches the destination
        // cell(m-1, n-1)
        int [,]dp = new int[R,C];
        int m = R, n = C;
      
        // Base case
        dp[m - 1,n - 1] = points[m - 1, n - 1] > 0 ? 1:
                     Math.Abs(points[m - 1,n - 1]) + 1;
      
        // Fill last row and last 
        // column as base to fill
        // entire table
        for (int i = m-2; i >= 0; i--)
            dp[i, n - 1] = Math.Max(dp[i + 1, n - 1] - 
                                points[i, n - 1], 1);
        for (int j = n - 2; j >= 0; j--)
            dp[m - 1, j] = Math.Max(dp[m - 1, j + 1] - 
                                points[m - 1, j], 1);
      
        // fill the table in 
        // bottom-up fashion
        for(int i = m - 2; i >= 0; i--)
        {
            for (int j = n - 2; j >= 0; j--)
            {
                int min_points_on_exit = Math.Min(dp[i + 1, j], 
                                                  dp[i, j + 1]);

1884
Chapter 258. Minimum Initial Points to Reach Destination

                dp[i, j] = Math.Max(min_points_on_exit - 
                                      points[i, j], 1);
            }
        }
      
        return dp[0, 0];
    }
  
    // Driver Code
    public static void Main ()
    {
        int [,]points = {{-2,-3,3},
                         {-5,-10,1},
                           {10,30,-5}};
        int R = 3,C = 3;
        Console.Write("Minimum Initial Points Required: "+
                           minInitialPoints(points, R, C));
    }
}
  
// This code is contributed by nitin mittal.

Output:

Minimum Initial Points Required: 7

This article is contributed by Gaurav Ahirwar. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : nitin mittal, PrathamKohli

Source

https://www.geeksforgeeks.org/minimum-positive-points-to-reach-destination/

1885
Chapter 259

Minimum Sum Path In 3-D


Array

Minimum Sum Path In 3-D Array - GeeksforGeeks


Given a 3-D array arr[l][m][n], the task is to find the minimum path sum from the first cell
of array to the last cell of array. We can only traverse to adjacent element, i.e., from a given
cell (i, j, k), cells (i+1, j, k), (i, j+1, k) and (i, j, k+1) can be traversed, diagonal traversing
is not allowed, We may assume that all costs are positive integers.
Examples:

Input : arr[][][]= { {{1, 2}, {3, 4}},


{{4, 8}, {5, 2}} };
Output : 9
Explanation : arr[0][0][0] + arr[0][0][1] +
arr[0][1][1] + arr[1][1][1]

Input : { { {1, 2}, {4, 3}},


{ {3, 4}, {2, 1}} };
Output : 7
Explanation : arr[0][0][0] + arr[0][0][1] +
arr[0][1][1] + arr[1][1][1]

Let us consider a 3-D array arr[2][2][2] represented by a cuboid having values as:

arr[][][] = {{{1, 2}, {3, 4}},


{ {4, 8}, {5, 2}}};
Result = 9 is calculated as:

1886
Chapter 259. Minimum Sum Path In 3-D Array

This problem is similar to Min cost path. and can be solved using Dynamic Programming/

// Array for storing result


int tSum[l][m][n];

tSum[0][0][0] = arr[0][0][0];

/* Initialize first row of tSum array */


for (i = 1; i < l; i++)
tSum[i][0][0] = tSum[i-1][0][0] + arr[i][0][0];

/* Initialize first column of tSum array */


for (j = 1; j < m; j++)
tSum[0][j][0] = tSum[0][j-1][0] + arr[0][j][0];

/* Initialize first width of tSum array */


for (k = 1; k < n; k++)
tSum[0][0][k] = tSum[0][0][k-1] + arr[0][0][k];

/* Initialize first row- First column of tSum


array */
for (i = 1; i < l; i++)
for (j = 1; j < m; j++)
tSum[i][j][0] = min(tSum[i-1][j][0],
tSum[i][j-1][0],
INT_MAX)
+ arr[i][j][0];

/* Initialize first row- First width of tSum


array */
for (i = 1; i < l; i++)
for (k = 1; k < n; k++)
tSum[i][0][k] = min(tSum[i-1][0][k],
tSum[i][0][k-1],
INT_MAX)
+ arr[i][0][k];

/* Initialize first width- First column of


tSum array */
for (k = 1; k < n; k++)
for (j = 1; j < m; j++)
tSum[0][j][k] = min(tSum[0][j][k-1],
tSum[0][j-1][k],
INT_MAX)
+ arr[0][j][k];

1887
Chapter 259. Minimum Sum Path In 3-D Array

/* Construct rest of the tSum array */


for (i = 1; i < l; i++)
for (j = 1; j < m; j++)
for (k = 1; k < n; k++)
tSum[i][j][k] = min(tSum[i-1][j][k],
tSum[i][j-1][k],
tSum[i][j][k-1])
+ arr[i][j][k];

return tSum[l-1][m-1][n-1];

C++

// C++ program for Min path sum of 3D-array


#include<bits/stdc++.h>
using namespace std;
#define l 3
#define m 3
#define n 3
  
// A utility function that returns minimum
// of 3 integers
int min(int x, int y, int z)
{
  return (x < y)? ((x < z)? x : z) :
          ((y < z)? y : z);
}
  
// function to calculate MIN path sum of 3D array
int minPathSum(int arr[][m][n])
{
  int i, j, k;
  int tSum[l][m][n];
  
  tSum[0][0][0] = arr[0][0][0];
  
  /* Initialize first row of tSum array */
  for (i = 1; i < l; i++)
    tSum[i][0][0] = tSum[i-1][0][0] + arr[i][0][0];
  
  /* Initialize first column of tSum array */
  for (j = 1; j < m; j++)
    tSum[0][j][0] = tSum[0][j-1][0] + arr[0][j][0];
  
  /* Initialize first width of tSum array */
  for (k = 1; k < n; k++)
    tSum[0][0][k] = tSum[0][0][k-1] + arr[0][0][k];

1888
Chapter 259. Minimum Sum Path In 3-D Array

  
  /* Initialize first row- First column of
     tSum array */
  for (i = 1; i < l; i++)
    for (j = 1; j < m; j++)
      tSum[i][j][0] = min(tSum[i-1][j][0],
                          tSum[i][j-1][0],
                          INT_MAX)
                    + arr[i][j][0];
  
  
  /* Initialize first row- First width of
     tSum array */
  for (i = 1; i < l; i++)
    for (k = 1; k < n; k++)
      tSum[i][0][k] = min(tSum[i-1][0][k],
                          tSum[i][0][k-1],
                          INT_MAX)
                    + arr[i][0][k];
  
  
  /* Initialize first width- First column of
     tSum array */
  for (k = 1; k < n; k++)
    for (j = 1; j < m; j++)
      tSum[0][j][k] = min(tSum[0][j][k-1],
                          tSum[0][j-1][k],
                          INT_MAX)
                    + arr[0][j][k];
  
  /* Construct rest of the tSum array */
  for (i = 1; i < l; i++)
    for (j = 1; j < m; j++)
      for (k = 1; k < n; k++)
        tSum[i][j][k] = min(tSum[i-1][j][k],
                            tSum[i][j-1][k],
                            tSum[i][j][k-1])
                        + arr[i][j][k];
  
  return tSum[l-1][m-1][n-1];
  
}
  
// Driver program
int main()
{
  int arr[l][m][n] = { { {1, 2, 4}, {3, 4, 5}, {5, 2, 1}},
    { {4, 8, 3}, {5, 2, 1}, {3, 4, 2}},

1889
Chapter 259. Minimum Sum Path In 3-D Array

    { {2, 4, 1}, {3, 1, 4}, {6, 3, 8}}


  };
  cout << minPathSum(arr);
  return 0;
}

Java

// Java program for Min path sum of 3D-array


import java.io.*;
  
class GFG {
      
    static int l =3;
    static int m =3;
    static int n =3;
      
    // A utility function that returns minimum
    // of 3 integers
    static int min(int x, int y, int z)
    {
         return (x < y)? ((x < z)? x : z) :
                ((y < z)? y : z);
    }
      
    // function to calculate MIN path sum of 3D array
    static int minPathSum(int arr[][][])
    {
        int i, j, k;
        int tSum[][][] =new int[l][m][n];
          
        tSum[0][0][0] = arr[0][0][0];
          
        /* Initialize first row of tSum array */
        for (i = 1; i < l; i++)
            tSum[i][0][0] = tSum[i-1][0][0] + arr[i][0][0];
          
        /* Initialize first column of tSum array */
        for (j = 1; j < m; j++)
            tSum[0][j][0] = tSum[0][j-1][0] + arr[0][j][0];
          
        /* Initialize first width of tSum array */
        for (k = 1; k < n; k++)
            tSum[0][0][k] = tSum[0][0][k-1] + arr[0][0][k];
          
        /* Initialize first row- First column of
            tSum array */
        for (i = 1; i < l; i++)

1890
Chapter 259. Minimum Sum Path In 3-D Array

            for (j = 1; j < m; j++)


            tSum[i][j][0] = min(tSum[i-1][j][0],
                                tSum[i][j-1][0],
                                Integer.MAX_VALUE)
                            + arr[i][j][0];
          
          
        /* Initialize first row- First width of
            tSum array */
        for (i = 1; i < l; i++)
            for (k = 1; k < n; k++)
            tSum[i][0][k] = min(tSum[i-1][0][k],
                                tSum[i][0][k-1],
                                Integer.MAX_VALUE)
                            + arr[i][0][k];
          
          
        /* Initialize first width- First column of
            tSum array */
        for (k = 1; k < n; k++)
            for (j = 1; j < m; j++)
            tSum[0][j][k] = min(tSum[0][j][k-1],
                                tSum[0][j-1][k],
                                Integer.MAX_VALUE)
                            + arr[0][j][k];
          
        /* Construct rest of the tSum array */
        for (i = 1; i < l; i++)
            for (j = 1; j < m; j++)
            for (k = 1; k < n; k++)
                tSum[i][j][k] = min(tSum[i-1][j][k],
                                    tSum[i][j-1][k],
                                    tSum[i][j][k-1])
                                + arr[i][j][k];
          
        return tSum[l-1][m-1][n-1];
          
    }
      
    // Driver program
    public static void main (String[] args)
    {
        int arr[][][] = { { {1, 2, 4}, {3, 4, 5}, {5, 2, 1}},
                          { {4, 8, 3}, {5, 2, 1}, {3, 4, 2}},
                          { {2, 4, 1}, {3, 1, 4}, {6, 3, 8}}
                        };
        System.out.println ( minPathSum(arr));
              

1891
Chapter 259. Minimum Sum Path In 3-D Array

    }
}
  
// This code is contributed by vt_m

C#

// C# program for Min 


// path sum of 3D-array
using System;
  
class GFG
{
      
    static int l = 3;
    static int m = 3;
    static int n = 3;
      
    // A utility function 
    // that returns minimum
    // of 3 integers
    static int min(int x, int y, int z)
    {
        return (x < y) ? ((x < z) ? x : z) :
              ((y < z) ? y : z);
    }
      
    // function to calculate MIN 
    // path sum of 3D array
    static int minPathSum(int [,,]arr)
    {
        int i, j, k;
        int [ , , ]tSum = new int[l, m, n];
          
        tSum[0, 0, 0] = arr[0, 0, 0];
          
        /* Initialize first
        row of tSum array */
        for (i = 1; i < l; i++)
            tSum[i, 0, 0] = tSum[i - 1, 0, 0] + 
                             arr[i, 0, 0];
          
        /* Initialize first column 
        of tSum array */
        for (j = 1; j < m; j++)
            tSum[0, j, 0] = tSum[0, j - 1, 0] + 
                             arr[0, j, 0];
          

1892
Chapter 259. Minimum Sum Path In 3-D Array

        /* Initialize first


        width of tSum array */
        for (k = 1; k < n; k++)
            tSum[0, 0, k] = tSum[0, 0, k - 1] + 
                             arr[0, 0, k];
          
        /* Initialize first 
        row- First column of
        tSum array */
        for (i = 1; i < l; i++)
            for (j = 1; j < m; j++)
            tSum[i, j, 0] = min(tSum[i - 1, j, 0],
                                tSum[i, j - 1, 0],
                                int.MaxValue) +
                                arr[i, j, 0];
          
          
        /* Initialize first 
        row- First width of
        tSum array */
        for (i = 1; i < l; i++)
            for (k = 1; k < n; k++)
            tSum[i, 0, k] = min(tSum[i - 1, 0, k],
                                tSum[i, 0, k - 1],
                                int.MaxValue) + 
                                arr[i, 0, k];
          
          
        /* Initialize first 
        width- First column of
        tSum array */
        for (k = 1; k < n; k++)
            for (j = 1; j < m; j++)
            tSum[0, j, k] = min(tSum[0, j, k - 1],
                                tSum[0, j - 1, k],
                                int.MaxValue) + 
                                arr[0, j, k];
          
        /* Construct rest of
        the tSum array */
        for (i = 1; i < l; i++)
            for (j = 1; j < m; j++)
            for (k = 1; k < n; k++)
                tSum[i, j, k] = min(tSum[i - 1, j, k],
                                    tSum[i, j - 1, k],
                                    tSum[i, j, k - 1]) +
                                    arr[i, j, k];
          

1893
Chapter 259. Minimum Sum Path In 3-D Array

        return tSum[l-1,m-1,n-1];
          
    }
      
    // Driver Code
    static public void Main ()
    {
        int [, , ]arr= {{{1, 2, 4}, {3, 4, 5}, {5, 2, 1}},
                        {{4, 8, 3}, {5, 2, 1}, {3, 4, 2}},
                        {{2, 4, 1}, {3, 1, 4}, {6, 3, 8}}};
        Console.WriteLine(minPathSum(arr));
              
    }
}
  
// This code is contributed by ajit

Output :

20

Time Complexity : O(l*m*n)


Auxiliary Space : O(l*m*n)
Improved By : jit_t

Source

https://www.geeksforgeeks.org/minimum-sum-path-3-d-array/

1894
Chapter 260

Minimum Sum Path in a


Triangle

Minimum Sum Path in a Triangle - GeeksforGeeks


Given a triangular structure of numbers, find the minimum path sum from top to bottom.
Each step you may move to adjacent numbers on the row below.
Examples :

Input :
2
3 7
8 5 6
6 1 9 3
Output : 11
Explanation : 2 + 3 + 5 + 1 = 11

Input :
3
6 4
5 2 7
9 1 8 6
Output : 10
Explanation : 3 + 4 + 2 + 1 = 10

Naive Approach : Going through the Naive approach by traversing every possible path.
But, this is costly. So, use Dynamic Programming here in order to reduce the time com-
plexity.
There are two ways to reach the solution :
1. Memoization – Starting from the top node, traverse recursively with each node, till the

1895
Chapter 260. Minimum Sum Path in a Triangle

pathsum of that node is calculated. And then store the result in an array. But this will
take O(N^2) space to maintain the array.
2. Bottom up – Start from the nodes on the bottom row; the min pathsum for these nodes
are the values of the nodes themselves. And after that, minimum pathsum at the ith node
of kth row would be the minimum of the pathsum of its two children + the node’s value,
i.e.:

memo[k][i] = min( memo[k+1][i], memo[k+1][i+1]) + A[k][i];

OR
Simply set memo as a 1D array, and update it
this will be space efficient also :
For the row k :

memo[i] = min( memo[i], memo[i+1]) + A[k][i];

Below is the implementation of above dynamic programming approach :

C++

// C++ program for Dynamic


// Programming implementation of
// Min Sum Path in a Triangle
#include <bits/stdc++.h>
using namespace std;
  
// Util function to find minimum sum for a path
int minSumPath(vector<vector<int> >& A)
{
    // For storing the result in a 1-D array,
    // and simultaneously updating the result.
    int memo[A.size()];
    int n = A.size() - 1;
  
    // For the bottom row
    for (int i = 0; i < A[n].size(); i++) 
        memo[i] = A[n][i];    
  
    // Calculation of the remaining rows,
    // in bottom up manner.
    for (int i = A.size() - 2; i >= 0; i--) 
        for (int j = 0; j < A[i + 1].size() - 1; j++) 
            memo[j] = A[i][j] + min(memo[j],

1896
Chapter 260. Minimum Sum Path in a Triangle

                                    memo[j + 1]);
  
    // return the top element
    return memo[0];
}
  
/* Driver program to test above functions */
int main()
{
    vector<vector<int> > A{ { 2 },
                            { 3, 9 },
                            { 1, 6, 7 } };
    cout << minSumPath(A);
    return 0;
}

Java

// Java program for Dynamic


// Programming implementation of
// Min Sum Path in a Triangle
import java.io.*;
import java.util.*;
  
class GFG
{
    static int A[][] = {{2}, 
                        {3, 9}, 
                        {1, 6, 7}};
                          
    // Util function to find 
    // minimum sum for a path
    static int minSumPath()
    {
        // For storing the result
        // in a 1-D array, and 
        // simultaneously updating 
        // the result.
        int []memo = new int[A.length];
        int n = A.length - 1;
      
        // For the bottom row
        for (int i = 0; 
                 i < A[n].length; i++) 
            memo[i] = A[n][i];
      
        // Calculation of the 
        // remaining rows, in

1897
Chapter 260. Minimum Sum Path in a Triangle

        // bottom up manner.


        for (int i = A.length - 2; 
                 i >= 0; i--) 
            for (int j = 0; 
                     j < A[i + 1].length - 1; j++) 
                memo[j] = A[i][j] + 
                          (int)Math.min(memo[j], 
                                   memo[j + 1]);
      
        // return the 
        // top element
        return memo[0];
    }
      
    // Driver Code
    public static void main(String args[])
    {
        System.out.print(minSumPath());
    }
}
  
// This code is contributed by 
// Manish Shaw (manishshaw1)

Python 3

# Python 3 program for Dynamic


# Programming implementation of
# Min Sum Path in a Triangle
  
# Util function to find 
# minimum sum for a path
def minSumPath(A):
      
    # For storing the result in 
    # a 1-D array, and simultaneously 
    # updating the result.
    memo = [None] * len(A)
    n = len(A) - 1
      
    # For the bottom row
    for i in range(len(A[n])): 
        memo[i] = A[n][i] 
  
    # Calculation of the
    # remaining rows,
    # in bottom up manner.
    for i in range(len(A) - 2, -1,-1): 

1898
Chapter 260. Minimum Sum Path in a Triangle

        for j in range( len(A[i + 1]) - 1): 


            memo[j] = A[i][j] + min(memo[j],
                                    memo[j + 1]);
  
    # return the top element
    return memo[0]
  
# Driver Code
A = [[ 2 ],
    [3, 9 ],
    [1, 6, 7 ]]
print(minSumPath(A))
  
# This code is contributed
# by ChitraNayal

C#

// C# program for Dynamic


// Programming implementation of
// Min Sum Path in a Triangle
using System;
using System.Collections.Generic;
using System.Linq;
  
class GFG {
      
    // Util function to find 
    // minimum sum for a path
    static int minSumPath(ref List<List<int>> A)
    {
          
        // For storing the result in a 1-D array,
        // and simultaneously updating the result.
        int []memo = new int[A.Count];
        int n = A.Count - 1;
      
        // For the bottom row
        for (int i = 0; i < A[n].Count; i++) 
            memo[i] = A[n][i]; 
      
        // Calculation of the remaining rows,
        // in bottom up manner.
        for (int i = A.Count - 2; i >= 0; i--) 
            for (int j = 0; j < A[i + 1].Count - 1; j++) 
                memo[j] = A[i][j] + 
                          (int)Math.Min(memo[j], 
                                   memo[j + 1]);

1899
Chapter 260. Minimum Sum Path in a Triangle

      
        // return the top element
        return memo[0];
    }
      
    // Driver Code
    public static void Main()
    {
        List<List<int>> A = new List<List<int>>();
        A.Add(new List<int> {2});
        A.Add(new List<int> {3, 9});
        A.Add(new List<int> {1, 6, 7});
        Console.WriteLine(minSumPath(ref A));
    }
}
  
// This code is contributed by 
// Manish Shaw (manishshaw1)

PHP

<?php
// PHP program for Dynamic
// Programming implementation of
// Min Sum Path in a Triangle
  
// Util function to find
// minimum sum for a path
function minSumPath(&$A)
{
    // For storing the result 
    // in a 1-D array, and
    // simultaneously updating 
    // the result.
    $memo = array();
    for ($i = 0; $i < count($A); $i++) 
        $memo[$i] = 0;
  
    $n = count($A) - 1;
  
    // For the bottom row
    for ($i = 0; 
         $i < count($A[$n]); $i++) 
        $memo[$i] = $A[$n][$i]; 
  
    // Calculation of 
    // the remaining rows,
    // in bottom up manner.

1900
Chapter 260. Minimum Sum Path in a Triangle

    for ($i = count($A) - 2; $i >= 0; $i--) 


        for ($j = 0; 
             $j < count($A[$i + 1]) - 1; $j++) 
            $memo[$j] = $A[$i][$j] + 
                        min($memo[$j],
                        $memo[$j + 1]);
  
    // return the 
    // top element
    return $memo[0];
}
  
// Driver Code
$A = array(array(2),
           array(3, 9),
           array(1, 6, 7));
echo (minSumPath($A)); 
  
// This code is contributed 
// by Manish Shaw(manishshaw1)
?>

Output:

Improved By : manishshaw1, ChitraNayal

Source

https://www.geeksforgeeks.org/minimum-sum-path-triangle/

1901
Chapter 261

Minimum and Maximum values


of an expression with * and +

Minimum and Maximum values of an expression with * and + - GeeksforGeeks


Given an expression which contains numbers and two operators ‘+’ and ‘*’, we need to
find maximum and minimum value which can be obtained by evaluating this expression by
different parenthesization.
Examples:

Input : expr = “1+2*3+4*5”


Output : Minimum Value = 27, Maximum Value = 105
Explanation:
Minimum evaluated value = 1 + (2*3) + (4*5) = 27
Maximum evaluated value = (1 + 2)*(3 + 4)*5 = 105

We can solve this problem by dynamic programming method, we can see that this problem
is similar to matrix chain multiplication, here we are trying different parenthesization to
maximize and minimize expression value instead of number of matrix multiplication.
In below code first we have separated the operators and numbers from given expression then
two 2D arrays are taken for storing the intermediate result which are updated similar to
matrix chain multiplication and different parenthesization are tried among the numbers but
according to operators occurring in between them. At the end last cell of first row will store
the final result in both the 2D arrays.

// C++ program to get maximum and minimum


// values of an expression
#include <bits/stdc++.h>
using namespace std;
  
// Utility method to check whether a character

1902
Chapter 261. Minimum and Maximum values of an expression with * and +

// is operator or not
bool isOperator(char op)
{
    return (op == '+' || op == '*');
}
  
// method prints minimum and maximum value
// obtainable from an expression
void printMinAndMaxValueOfExp(string exp)
{
    vector<int> num;
    vector<char> opr;
    string tmp = "";
  
    //  store operator and numbers in different vectors
    for (int i = 0; i < exp.length(); i++)
    {
        if (isOperator(exp[i]))
        {
            opr.push_back(exp[i]);
            num.push_back(atoi(tmp.c_str()));
            tmp = "";
        }
        else
        {
            tmp += exp[i];
        }
    }
    //  storing last number in vector
    num.push_back(atoi(tmp.c_str()));
  
    int len = num.size();
    int minVal[len][len];
    int maxVal[len][len];
  
    //  initializing minval and maxval 2D array
    for (int i = 0; i < len; i++)
    {
        for (int j = 0; j < len; j++)
        {
            minVal[i][j] = INT_MAX;
            maxVal[i][j] = 0;
  
            //  initializing main diagonal by num values
            if (i == j)
                minVal[i][j] = maxVal[i][j] = num[i];
        }
    }

1903
Chapter 261. Minimum and Maximum values of an expression with * and +

  
    // looping similar to matrix chain multiplication
    // and updating both 2D arrays
    for (int L = 2; L <= len; L++)
    {
        for (int i = 0; i < len - L + 1; i++)
        {
            int j = i + L - 1;
            for (int k = i; k < j; k++)
            {
                int minTmp = 0, maxTmp = 0;
  
                // if current operator is '+', updating tmp
                // variable by addition
                if(opr[k] == '+')
                {
                    minTmp = minVal[i][k] + minVal[k + 1][j];
                    maxTmp = maxVal[i][k] + maxVal[k + 1][j];
                }
  
                // if current operator is '*', updating tmp
                // variable by multiplication
                else if(opr[k] == '*')
                {
                    minTmp = minVal[i][k] * minVal[k + 1][j];
                    maxTmp = maxVal[i][k] * maxVal[k + 1][j];
                }
  
                //  updating array values by tmp variables
                if (minTmp < minVal[i][j])
                    minVal[i][j] = minTmp;
                if (maxTmp > maxVal[i][j])
                    maxVal[i][j] = maxTmp;
            }
        }
    }
  
    //  last element of first row will store the result
    cout << "Minimum value : " << minVal[0][len - 1]
         << ", Maximum value : " << maxVal[0][len - 1];
}
  
//  Driver code to test above methods
int main()
{
    string expression = "1+2*3+4*5";
    printMinAndMaxValueOfExp(expression);
    return 0;

1904
Chapter 261. Minimum and Maximum values of an expression with * and +

Output:

Minimum value : 27, Maximum value : 105

Source

https://www.geeksforgeeks.org/minimum-maximum-values-expression/

1905
Chapter 262

Minimum cells required to


reach destination with jumps
equal to cell values

Minimum cells required to reach destination with jumps equal to cell values - GeeksforGeeks
Given a m x n matrix mat[][] containing positive integers. The problem is to reach to the
cell (m-1, n-1) from the cell (0, 0) by following the given constraints. From a cell (i, j) one
can move ‘exactly’ a distance of ‘mat[i][j]’ to the right (in the same row) or to below (in the
same column) only if the movement takes to a cell within matrix boundaries.
For example: Given mat[1][1] = 4, then one can move to cells mat[1][5] and mat[5][1] only if
these cells exists in the matrix. Following the constraints check whether one can reach cell
(m-1, n-1) from (0, 0). 1If one can reach then print the minimum number of cells required
to be covered during the movement else print “-1”.
Examples:

Input : mat[][] = { {2, 3, 2, 1, 4},


{3, 2, 5, 8, 2},
{1, 1, 2, 2, 1} }
Output : 4
The movement and cells covered are as follows:
(0, 0)->(0, 2)
|
(2, 2)->(2, 4)

Input : mat[][] = { {2, 4, 2},


{5, 3, 8},
{1, 1, 1} }
Output : 3

1906
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

Source: Asked in Directi


Algorithm: A dynamic programming approach is given below:

C++

// C++ implementation to count minimum cells required


// to be covered to reach destination
#include <bits/stdc++.h>
  
using namespace std;
  
#define SIZE 100
  
// function to count minimum cells required
// to be covered to reach destination
int minCells(int mat[SIZE][SIZE], int m, int n)
{
    // to store min cells required to be
    // covered to reach a particular cell
    int dp[m][n];
  
    // initially no cells can be reached
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            dp[i][j] = INT_MAX;
  
    // base case
    dp[0][0] = 1;
  

1907
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

    // building up the dp[][] matrix


    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
  
            // dp[i][j] != INT_MAX denotes that cell (i, j)
            // can be reached from cell (0, 0) and the other
            // half of the condition finds the cell on the
            // right that can be reached from (i, j)
            if (dp[i][j] != INT_MAX && (j + mat[i][j]) < n
                && (dp[i][j] + 1) < dp[i][j + mat[i][j]])
                dp[i][j + mat[i][j]] = dp[i][j] + 1;
  
            // the other half of the condition finds the cell
            // right below that can be reached from (i, j)
            if (dp[i][j] != INT_MAX && (i + mat[i][j]) < m
                && (dp[i][j] + 1) < dp[i + mat[i][j]][j])
                dp[i + mat[i][j]][j] = dp[i][j] + 1;
        }
    }
  
    // it true then cell (m-1, n-1) can be reached
    // from cell (0, 0) and returns the minimum
    // number of cells covered
    if (dp[m - 1][n - 1] != INT_MAX)
        return dp[m - 1][n - 1];
  
    // cell (m-1, n-1) cannot be reached from
    // cell (0, 0)
    return -1;
}
  
// Driver program to test above
int main()
{
    int mat[SIZE][SIZE] = { { 2, 3, 2, 1, 4 },
                            { 3, 2, 5, 8, 2 },
                            { 1, 1, 2, 2, 1 } };
  
    int m = 3, n = 5;
    cout << "Minimum number of cells = "
         << minCells(mat, m, n);
  
    return 0;
}

Java

// Java implementation to count minimum

1908
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

// cells required to be covered to reach


// destination
class MinCellsDestination
{
    static final int SIZE=100;
     
    // function to count minimum cells required
    // to be covered to reach destination
    static int minCells(int mat[][], int m, int n)
    {
        // to store min cells required to be
        // covered to reach a particular cell
        int dp[][] = new int[m][n];
        
        // initially no cells can be reached
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                dp[i][j] = Integer.MAX_VALUE;
        
        // base case
        dp[0][0] = 1;
        
        // building up the dp[][] matrix
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
        
                // dp[i][j] != INT_MAX denotes that cell
                // (i, j) can be reached from cell (0, 0)
                // and the other half of the condition
                // finds the cell on the right that can
                // be reached from (i, j)
                if (dp[i][j] != Integer.MAX_VALUE && 
                   (j + mat[i][j]) < n && (dp[i][j] + 1)
                   < dp[i][j + mat[i][j]])
                    dp[i][j + mat[i][j]] = dp[i][j] + 1;
        
                // the other half of the condition finds
                // the cell right below that can be 
                // reached from (i, j)
                if (dp[i][j] != Integer.MAX_VALUE && 
                   (i + mat[i][j]) < m && (dp[i][j] + 1)
                   < dp[i + mat[i][j]][j])
                    dp[i + mat[i][j]][j] = dp[i][j] + 1;
            }
        }
        
        // it true then cell (m-1, n-1) can be reached
        // from cell (0, 0) and returns the minimum

1909
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

        // number of cells covered


        if (dp[m - 1][n - 1] != Integer.MAX_VALUE)
            return dp[m - 1][n - 1];
        
        // cell (m-1, n-1) cannot be reached from
        // cell (0, 0)
        return -1;
    }
      
    // Driver code
    public static void main(String args[])
    {
         int mat[][] = { { 2, 3, 2, 1, 4 },
                         { 3, 2, 5, 8, 2 },
                         { 1, 1, 2, 2, 1 }};
    
        int m = 3, n = 5;
        System.out.println("Minimum number of cells" +
                          " = " + minCells(mat, m, n));
    }
}
/* This code is contributed by Danish Kaleem */

C#

// C# implementation to count minimum


// cells required to be covered to reach
// destination
using System;
  
class GFG {
      
    //static int SIZE=100;
      
    // function to count minimum cells required
    // to be covered to reach destination
    static int minCells(int [,]mat, int m, int n)
    {
          
        // to store min cells required to be
        // covered to reach a particular cell
        int [,]dp = new int[m,n];
      
        // initially no cells can be reached
        for (int i = 0; i < m; i++)
            for (int j = 0; j < n; j++)
                dp[i,j] = int.MaxValue;
      

1910
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

        // base case


        dp[0,0] = 1;
      
        // building up the dp[][] matrix
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
      
                // dp[i][j] != INT_MAX denotes that
                // cell (i, j) can be reached from
                // cell (0, 0) and the other half
                // of the condition finds the cell
                // on the right that can be reached
                // from (i, j)
                if (dp[i,j] != int.MaxValue && 
                (j + mat[i,j]) < n && (dp[i,j] + 1)
                < dp[i,j + mat[i,j]])
                    dp[i,j + mat[i,j]] = dp[i,j] + 1;
      
                // the other half of the condition
                // finds the cell right below that
                // can be reached from (i, j)
                if (dp[i,j] != int.MaxValue && 
                (i + mat[i,j]) < m && (dp[i,j] + 1)
                < dp[i + mat[i,j],j])
                    dp[i + mat[i,j],j] = dp[i,j] + 1;
            }
        }
      
        // it true then cell (m-1, n-1) can be
        // reached from cell (0, 0) and returns
        // the minimum number of cells covered
        if (dp[m - 1,n - 1] != int.MaxValue)
            return dp[m - 1,n - 1];
      
        // cell (m-1, n-1) cannot be reached from
        // cell (0, 0)
        return -1;
    }
      
    // Driver code
    public static void Main()
    {
        int [,]mat = { { 2, 3, 2, 1, 4 },
                       { 3, 2, 5, 8, 2 },
                       { 1, 1, 2, 2, 1 } };
  
        int m = 3, n = 5;
        Console.WriteLine("Minimum number of "

1911
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

            + "cells = " + minCells(mat, m, n));


    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP implementation to count
// minimum cells required to be 
// covered to reach destination
  
// function to count minimum
// cells required to be 
// covered to reach destination
function minCells( $mat, $m, $n)
{
      
    // to store min cells
    // required to be
    // covered to reach 
    // a particular cell
    $dp =array(array());
  
    // initially no cells 
    // can be reached
    for($i = 0; $i < $m; $i++)
        for($j = 0; $j < $n; $j++)
            $dp[$i][$j] = PHP_INT_MAX;
  
    // base case
    $dp[0][0] = 1;
  
    // building up the dp[][] matrix
    for($i = 0; $i < $m; $i++)
    {
        for($j = 0; $j < $n; $j++) 
        {
  
            // dp[i][j] != INT_MAX
            // denotes that cell (i, j)
            // can be reached from cell
            // (0, 0) and the other half 
            // of the condition finds the
            // cell on the right that can 
            // be reached from (i, j)
            if ($dp[$i][$j] != PHP_INT_MAX and

1912
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

                        ($j + $mat[$i][$j]) <$n


                         and ($dp[$i][$j] + 1) < 
                     $dp[$i][$j + $mat[$i][$j]])
                       
                $dp[$i][$j + $mat[$i][$j]] = 
                           $dp[$i][$j] + 1;
  
            // the other half of the 
            // condition finds the cell
            // right below that can be
            // reached from (i, j)
            if ($dp[$i][$j] != PHP_INT_MAX and 
                      ($i + $mat[$i][$j]) < $m
                      and ($dp[$i][$j] + 1) < 
                      $dp[$i +$mat[$i][$j]][$j])
                        
                $dp[$i + $mat[$i][$j]][$j] = $dp[$i][$j] + 1;
        }
    }
  
    // it true then cell 
    // (m-1, n-1) can be reached
    // from cell (0, 0) and 
    // returns the minimum
    // number of cells covered
    if ($dp[$m - 1][$n - 1] != PHP_INT_MAX)
        return $dp[$m - 1][$n - 1];
  
    // cell (m-1, n-1) cannot 
    // be reached from
    // cell (0, 0)
    return -1;
}
  
    // Driver Code
    $mat = array(array(2, 3, 2, 1, 4),
                 array(3, 2, 5, 8, 2),
                 array(1, 1, 2, 2, 1));
  
    $m = 3; $n = 5;
    echo "Minimum number of cells = "
        , minCells($mat, $m, $n);
  
// This code is contributed by anuj_67.
?>

Output:

1913
Chapter 262. Minimum cells required to reach destination with jumps equal to cell values

Minimum number of cells = 4

Time Complexity: O(m*n)


Auxiliary Space: O(m*n)
Improved By : vt_m

Source

https://www.geeksforgeeks.org/minimum-cells-required-reach-destination-jumps-equal-cell-values/

1914
Chapter 263

Minimum cost to fill given


weight in a bag

Minimum cost to fill given weight in a bag - GeeksforGeeks


You are given a bag of size W kg and you are provided costs of packets different weights
of oranges in array cost[] where cost[i] is basically cost of ‘i’ kg packet of oranges. Where
cost[i] = -1 means that ‘i’ kg packet of orange is unavailable
Find the minimum total cost to buy exactly W kg oranges and if it is not possible to buy
exactly W kg oranges then print -1. It may be assumed that there is infinite supply of all
available packet types.
Note : array starts from index 1.
Examples:

Input : W = 5, cost[] = {20, 10, 4, 50, 100}


Output : 14
We can choose two oranges to minimize cost. First
orange of 2Kg and cost 10. Second orange of 3Kg
and cost 4.

Input : W = 5, cost[] = {1, 10, 4, 50, 100}


Output : 5
We can choose five oranges of weight 1 kg.

Input : W = 5, cost[] = {1, 2, 3, 4, 5}


Output : 5
Costs of 1, 2, 3, 4 and 5 kg packets are 1, 2, 3,
4 and 5 Rs respectively.
We choose packet of 5kg having cost 5 for minimum
cost to get 5Kg oranges.

1915
Chapter 263. Minimum cost to fill given weight in a bag

Input : W = 5, cost[] = {-1, -1, 4, 5, -1}


Output : -1
Packets of size 1, 2 and 5 kg are unavailable
because they have cost -1. Cost of 3 kg packet
is 4 Rs and of 4 kg is 5 Rs. Here we have only
weights 3 and 4 so by using these two we can
not make exactly W kg weight, therefore answer
is -1.

This problem is can be reduced to 0-1 Knapsack Problem. So in cost array, we first ignore
those packets which are not available i.e; cost is -1 and then traverse the cost array and
create two array val[] for storing cost of ‘i’ kg packet of orange and wt[] for storing weight
of corresponding packet. Suppose cost[i] = 50 so weight of packet will be i and cost will be
50.
Algorithm :

• Create matrix min_cost[n+1][W+1], where n is number of distinct weighted packets


of orange and W is maximum capacity of bag.
• Initialize 0th row with INF (infinity) and 0th Column with 0.
• Now fill the matrix
– if wt[i-1] > j then min_cost[i][j] = min_cost[i-1][j] ;
– if wt[i-1] >= j then min_cost[i][j] = min(min_cost[i-1][j], val[i-1] + min_cost[i][j-
wt[i-1]]);
• If min_cost[n][W]==INF then output will be -1 because this means that we cant not
make make weight W by using these weights else output will be min_cost[n][W].

C++

// C++ program to find minimum cost to get exactly


// W Kg with given packets
#include<bits/stdc++.h>
#define INF 1000000
using namespace std;
  
// cost[] initial cost array including unavailable packet
// W capacity of bag
int MinimumCost(int cost[], int n, int W)
{
    // val[] and wt[] arrays
    // val[] array to store cost of 'i' kg packet of orange
    // wt[] array weight of packet of orange
    vector<int> val, wt;
  
    // traverse the original cost[] array and skip
    // unavailable packets and make val[] and wt[]
    // array. size variable tells the available number

1916
Chapter 263. Minimum cost to fill given weight in a bag

    // of distinct weighted packets


    int size = 0;
    for (int i=0; i<n; i++)
    {
        if (cost[i]!= -1)
        {
            val.push_back(cost[i]);
            wt.push_back(i+1);
            size++;
        }
    }
  
    n = size;
    int min_cost[n+1][W+1];
  
    // fill 0th row with infinity
    for (int i=0; i<=W; i++)
        min_cost[0][i] = INF;
  
    // fill 0'th column with 0
    for (int i=1; i<=n; i++)
        min_cost[i][0] = 0;
  
    // now check for each weight one by one and fill the
    // matrix according to the condition
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=W; j++)
        {
            // wt[i-1]>j means capacity of bag is
            // less then weight of item
            if (wt[i-1] > j)
                min_cost[i][j] = min_cost[i-1][j];
  
            // here we check we get minimum cost either
            // by including it or excluding it
            else
                min_cost[i][j] = min(min_cost[i-1][j],
                     min_cost[i][j-wt[i-1]] + val[i-1]);
        }
    }
  
    // exactly weight W can not be made by given weights
    return (min_cost[n][W]==INF)? -1: min_cost[n][W];
}
  
// Driver program to run the test case
int main()

1917
Chapter 263. Minimum cost to fill given weight in a bag

{
    int cost[] = {1, 2, 3, 4, 5}, W = 5;
    int n = sizeof(cost)/sizeof(cost[0]);
  
    cout << MinimumCost(cost, n, W);
    return 0;
}

Java

// JAVA Code for Minimum cost to


// fill given weight in a bag
import java.util.*;
  
class GFG {
      
    // cost[] initial cost array including 
    // unavailable packet W capacity of bag
    public static int MinimumCost(int cost[], int n, 
                                             int W)
    {
        // val[] and wt[] arrays
        // val[] array to store cost of 'i' kg 
        // packet of orange wt[] array weight of 
        // packet of orange
        Vector<Integer> val = new Vector<Integer>();
        Vector<Integer> wt = new Vector<Integer>();
       
        // traverse the original cost[] array and skip
        // unavailable packets and make val[] and wt[]
        // array. size variable tells the available 
        // number of distinct weighted packets
        int size = 0;
        for (int i = 0; i < n; i++)
        {
            if (cost[i] != -1)
            {
                val.add(cost[i]);
                wt.add(i + 1);
                size++;
            }
        }
       
        n = size;
        int min_cost[][] = new int[n+1][W+1];
       
        // fill 0th row with infinity
        for (int i = 0; i <= W; i++)

1918
Chapter 263. Minimum cost to fill given weight in a bag

            min_cost[0][i] = Integer.MAX_VALUE;
       
        // fill 0'th column with 0
        for (int i = 1; i <= n; i++)
            min_cost[i][0] = 0;
       
        // now check for each weight one by one and
        // fill the matrix according to the condition
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= W; j++)
            {
                // wt[i-1]>j means capacity of bag is
                // less then weight of item
                if (wt.get(i-1) > j)
                    min_cost[i][j] = min_cost[i-1][j];
       
                // here we check we get minimum cost 
                // either by including it or excluding
                // it
                else
                    min_cost[i][j] = Math.min(min_cost[i-1][j],
                                  min_cost[i][j-wt.get(i-1)] + 
                                              val.get(i-1));
            }
        }
       
        // exactly weight W can not be made by 
        // given weights
        return (min_cost[n][W] == Integer.MAX_VALUE)? -1: 
                                        min_cost[n][W];
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
         int cost[] = {1, 2, 3, 4, 5}, W = 5;
            int n = cost.length;
           
        System.out.println(MinimumCost(cost, n, W));
    }
}
// This code is contributed by Arnav Kr. Mandal.

Python 3

# Python program to find minimum cost to get exactly


# W Kg with given packets

1919
Chapter 263. Minimum cost to fill given weight in a bag

  
INF = 1000000
  
# cost[] initial cost array including unavailable packet
# W capacity of bag
def MinimumCost(cost, n, W):
  
    # val[] and wt[] arrays
    # val[] array to store cost of 'i' kg packet of orange 
    # wt[] array weight of packet of orange
    val = list()
    wt= list()
  
    # traverse the original cost[] array and skip
    # unavailable packets and make val[] and wt[]
    # array. size variable tells the available number
    # of distinct weighted packets.
    size = 0
    for i in range(n):
        if (cost[i] != -1):
            val.append(cost[i])
            wt.append(i+1)
            size += 1
  
    n = size
    min_cost = [[0 for i in range(W+1)] for j in range(n+1)]
  
    # fill 0th row with infinity
    for i in range(W+1):
        min_cost[0][i] = INF
  
    # fill 0th column with 0
    for i in range(1, n+1):
        min_cost[i][0] = 0
  
    # now check for each weight one by one and fill the
    # matrix according to the condition
    for i in range(1, n+1):
        for j in range(1, W+1):
            # wt[i-1]>j means capacity of bag is
            # less than weight of item
            if (wt[i-1] > j):
                min_cost[i][j] = min_cost[i-1][j]
  
            # here we check we get minimum cost either
            # by including it or excluding it
            else:
                min_cost[i][j] = min(min_cost[i-1][j],

1920
Chapter 263. Minimum cost to fill given weight in a bag

                    min_cost[i][j-wt[i-1]] + val[i-1])
  
    # exactly weight W can not be made by given weights
    if(min_cost[n][W] == INF):
        return -1
    else:
        return min_cost[n][W]
  
# Driver program to run the test case
cost = [1, 2, 3, 4, 5]
W = 5
n = len(cost)
  
print(MinimumCost(cost, n, W))
  
# This code is contributed by Soumen Ghosh.

Output:

This article is contributed by Shashank Mishra ( Gullu ).This article is reviewed by


team GeeksForGeeks.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.

Source

https://www.geeksforgeeks.org/minimum-cost-to-fill-given-weight-in-a-bag/

1921
Chapter 264

Minimum cost to make Longest


Common Subsequence of length
k

Minimum cost to make Longest Common Subsequence of length k - GeeksforGeeks


Given two string X, Y and an integer k. Now the task is to convert string X with minimum
cost such that the Longest Common Subsequence of X and Y after conversion is of length k.
The cost of conversion is calculated as XOR of old character value and new character value.
Character value of ‘a’ is 0, ‘b’ is 1 and so on.
Examples:

Input : X = "abble",
Y = "pie",
k = 2
Output : 25

If you changed 'a' to 'z', it will cost 0 XOR 25.

The problem can be solved by slight change in Dynamic Programming problem of Longest
Increasing Subsequence. Instead of two states, we maintain three states.
Note, that if k > min(n, m) then it’s impossible to attain LCS of atleast k length, else it’s
always possible.
Let dp[i][j][p] stores the minimum cost to achieve LCS of length p in x[0…i] and y[0….j].
With base step as dp[i][j][0] = 0 because we can achieve LCS of 0 legth without any cost
and for i < 0 or j 0 in such case).
Else there are 3 cases:
1. Convert x[i] to y[j].
2. Skip ith character from x.
3. Skip jth character from y.

1922
Chapter 264. Minimum cost to make Longest Common Subsequence of length k

If we convert x[i] to y[j], then cost = f(x[i]) XOR f(y[j]) will be added and LCS will decrease
by 1. f(x) will return the character value of x.
Note that the minimum cost to convert a charcater ‘a’ to any character ‘c’ is always f(a)
XOR f(c) because f(a) XOR f(c) <= (f(a) XOR f(b) + f(b) XOR f(c)) for all a, b, c.
If you skip ith character from x then i will be decreased by 1, no cost will be added and LCS
will remain the same.
If you skip jth character from x then j will be decreased by 1, no cost will be added and LCS
will remain the same.
Therefore,

dp[i][j][k] = min(cost + dp[i - 1][j - 1][k - 1],


dp[i - 1][j][k],
dp[i][j - 1][k])
The minimum cost to make the length of their
LCS atleast k is dp[n - 1][m - 1][k]

#include <bits/stdc++.h>
using namespace std;
const int N = 30;
  
// Return Minimum cost to make LCS of length k
int solve(char X[], char Y[], int l, int r, 
                     int k, int dp[][N][N])
{
    // If k is 0.
    if (!k)
        return 0;
  
    // If length become less than 0, return
    // big number.
    if (l < 0 | r < 0)
        return 1e9;
  
    // If state already calculated.
    if (dp[l][r][k] != -1)
        return dp[l][r][k];
  
    // Finding the cost
    int cost = (X[l] - 'a') ^ (Y[r] - 'a');
  
    // Finding minimum cost and saving the state value
    return dp[l][r][k] = min({cost +
                      solve(X, Y, l - 1, r - 1, k - 1, dp),
                             solve(X, Y, l - 1, r, k, dp), 

1923
Chapter 264. Minimum cost to make Longest Common Subsequence of length k

                             solve(X, Y, l, r - 1, k, dp)});
}
  
// Driven Program
int main()
{
    char X[] = "abble";
    char Y[] = "pie";
    int n = strlen(X);
    int m = strlen(Y);
    int k = 2;
  
    int dp[N][N][N];
    memset(dp, -1, sizeof dp);
    int ans = solve(X, Y, n - 1, m - 1, k, dp);
  
    cout << (ans == 1e9 ? -1 : ans) << endl;
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/minimum-cost-make-longest-common-subsequence-length-k/

1924
Chapter 265

Minimum cost to make two


strings identical by deleting the
digits

Minimum cost to make two strings identical by deleting the digits - GeeksforGeeks
Given two strings X and Y consisting of only digits ‘0’ to ‘9’. Find minimum cost required
to make the given two strings identical. Only operation allowed is to delete characters from
any of the string. The cost of operation of deleting the digit ‘d’ is d units.

Input: X = 3759, Y = 9350


Output: 23
Explanation
For making both string identical, delete
characters 3, 7, 5 from first string and
delete characters 3, 5, 0 from second
string. Total cost of operation is
3 + 7 + 5 + 3 + 5 + 0 = 23

Input: X = 3198, Y = 98
Output: 4

This problem is a variation of Longest Common Subsequence( LCS ) and this one. The idea
is simple, instead of finding the length of longest common subsequence, find the maximum
cost by adding identical characters from both the string.
Now to find the minimum cost, subtract the above result from total cost of both strings i.e.,

costX = Cost of removing all characters

1925
Chapter 265. Minimum cost to make two strings identical by deleting the digits

from string 'X'


CostY = Cost of removing all characters
from string 'Y'
cost_Id = Cost of removing identical characters
from both strings

Minimum cost to make both string identical =


costX + costY - cost_Id

C++

/* C++ code to find minimum cost to make two strings


   identical */
#include <bits/stdc++.h>
using namespace std;
  
/* Function to returns cost of removing the identical
   characters in LCS for X[0..m-1], Y[0..n-1] */
int lcs(char* X, char* Y, int m, int n)
{
    int L[m + 1][n + 1];
  
    /* Following steps build L[m+1][n+1] in bottom
       up fashion. Note that L[i][j] contains cost
       of removing identical characters in LCS of
       X[0..i-1] and Y[0..j-1] */
    for (int i = 0; i <= m; ++i) {
        for (int j = 0; j <= n; j++) {
  
            if (i == 0 || j == 0)
                L[i][j] = 0;
  
            // If both characters are same, add both
            // of them
            else if (X[i - 1] == Y[j - 1])
                L[i][j] = L[i - 1][j - 1] + 
                          2 * (X[i - 1] - '0');
  
            // Otherwise find the maximum cost among them
            else
                L[i][j] = max(L[i - 1][j], L[i][j - 1]);
        }
    }
  
    return L[m][n];
}
  
// Returns cost of making X[] and Y[] identical

1926
Chapter 265. Minimum cost to make two strings identical by deleting the digits

int findMinCost(char X[], char Y[])


{
    // Find LCS of X[] and Y[]
    int m = strlen(X), n = strlen(Y);
  
    // Initialize the cost variable
    int cost = 0;
  
    // Find cost of all characters in
    // both strings
    for (int i = 0; i < m; ++i)
        cost += X[i] - '0';
  
    for (int i = 0; i < n; ++i)
        cost += Y[i] - '0';
  
    return cost - lcs(X, Y, m, n);
}
  
/* Driver program to test above function */
int main()
{
    char X[] = "3759";
    char Y[] = "9350";
    cout << "Minimum Cost to make two strings "
         << "identical is = " << findMinCost(X, Y);
    return 0;
}

Java

// Java code to find minimum cost to 


// make two strings identical
import java.util.*;
import java.lang.*;
  
public class GfG{
      
/* Function to returns cost of removing the identical
characters in LCS for X[0..m-1], Y[0..n-1] */
static int lcs(char[] X, char[] Y, int m, int n)
{
    int[][] L=new int[m + 1][n + 1];
  
    /* Following steps build L[m+1][n+1] in 
    bottom up fashion. Note that L[i][j] contains 
    cost of removing identical characters in 
    LCS of X[0..i-1] and Y[0..j-1] */

1927
Chapter 265. Minimum cost to make two strings identical by deleting the digits

    for (int i = 0; i <= m; ++i) {


        for (int j = 0; j <= n; j++) {
  
            if (i == 0 || j == 0)
                L[i][j] = 0;
  
            // If both characters are same, 
            // add both of them
            else if (X[i - 1] == Y[j - 1])
                L[i][j] = L[i - 1][j - 1] + 
                        2 * (X[i - 1] - '0');
  
            // Otherwise find the maximum 
            // cost among them
            else
                L[i][j] = L[i - 1][j] > L[i][j - 1] ? 
                          L[i - 1][j] : L[i][j - 1];
        }
    }
  
    return L[m][n];
}
  
// Returns cost of making X[] and Y[] identical
static int findMinCost(char X[], char Y[])
{
    // Find LCS of X[] and Y[]
    int m = X.length, n = Y.length;
  
    // Initialize the cost variable
    int cost = 0;
  
    // Find cost of all characters in
    // both strings
    for (int i = 0; i < m; ++i)
        cost += X[i] - '0';
  
    for (int i = 0; i < n; ++i)
        cost += Y[i] - '0';
  
    return cost - lcs(X, Y, m, n);
}
  
// driver function
    public static void main(String argc[]){
  
    char X[] = ("3759").toCharArray();
    char Y[] = ("9350").toCharArray();

1928
Chapter 265. Minimum cost to make two strings identical by deleting the digits

      
    System.out.println("Minimum Cost to make two strings"+
                 " identical is = " +findMinCost(X, Y));
    }
}
  
// This code is contributed by Prerna Saini

C#

// C# code to find minimum cost to 


// make two strings identical
using System;
  
public class GfG{
      
    /* Function to returns cost of removing the identical
    characters in LCS for X[0..m-1], Y[0..n-1] */
    static int lcs(string X, string Y, int m, int n)
    {
        int [,]L=new int[m + 1,n + 1];
      
        /* Following steps build L[m+1][n+1] in 
        bottom up fashion. Note that L[i][j] contains 
        cost of removing identical characters in 
        LCS of X[0..i-1] and Y[0..j-1] */
        for (int i = 0; i <= m; ++i) {
            for (int j = 0; j <= n; j++) {
      
                if (i == 0 || j == 0)
                    L[i,j] = 0;
      
                // If both characters are same, 
                // add both of them
                else if (X[i - 1] == Y[j - 1])
                    L[i,j] = L[i - 1,j - 1] + 
                            2 * (X[i - 1] - '0');
      
                // Otherwise find the maximum 
                // cost among them
                else
                    L[i,j] = L[i - 1,j] > L[i,j - 1] ? 
                            L[i - 1,j] : L[i,j - 1];
            }
        }
      
        return L[m,n];
    }

1929
Chapter 265. Minimum cost to make two strings identical by deleting the digits

      
    // Returns cost of making X[] and Y[] identical
    static int findMinCost( string X, string Y)
    {
        // Find LCS of X[] and Y[]
        int m = X.Length, n = Y.Length;
      
        // Initialize the cost variable
        int cost = 0;
      
        // Find cost of all characters in
        // both strings
        for (int i = 0; i < m; ++i)
            cost += X[i] - '0';
      
        for (int i = 0; i < n; ++i)
            cost += Y[i] - '0';
      
        return cost - lcs(X, Y, m, n);
    }
      
    // Driver function
    public static void Main()
    {
        string X = "3759";
        string Y= "9350";
          
        Console.WriteLine("Minimum Cost to make two strings"+
                    " identical is = " +findMinCost(X, Y));
    }
}
  
// This code is contributed by vt_m

Output:

Minimum Cost to make two strings identical is = 23

Time complexity: O(m*n)


Auxiliary space: O(m*n)

Source

https://www.geeksforgeeks.org/minimum-cost-make-two-strings-identical-deleting-digits/

1930
Chapter 266

Minimum cost to reach the top


of the floor by climbing stairs

Minimum cost to reach the top of the floor by climbing stairs - GeeksforGeeks
Given N non-negative integers which signifies the cost of the moving from each stair. Paying
the cost at i-th step, you can either climb one or two steps. Given that one can start from
the 0-the step or 1-the step, the task is to find the minimum cost to reach the top of the
floor(N+1) by climbing N stairs.
Examples:

Input: a[] = { 16, 19, 10, 12, 18 }


Output: 31
Start from 19 and then move to 12.

Input: a[] = {2, 5, 3, 1, 7, 3, 4}


Output: 9
2->3->1->3

Approach: Let dp[i] be the cost to climb the i-th staircase to from 0-th or 1-th step.
Hence dp[i] = cost[i] + min(dp[i-1], dp[i-2]). Since dp[i-1] and dp[i-2] is needed to
compute the cost of travelling from i-th step, a bottom-up approach can be used to solve
the problem. The answer will be the minimum of cost of reaching n-1th stair and n-2th
stair. Compute the dp[] array in bottom-up manner.
Below is the implementation of the above approach.

C++

// C++ program to find the minimum


// cost required to reach the n-th floor
#include <bits/stdc++.h>

1931
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

using namespace std;


  
// function to find the minimum cost
// to reach N-th floor
int minimumCost(int cost[], int n)
{
    // declare an array
    int dp[n];
  
    // base case
    if (n == 1)
        return cost[0];
  
    // initially to climb till 0-th
    // or 1th stair
    dp[0] = cost[0];
    dp[1] = cost[1];
  
    // iterate for finding the cost
    for (int i = 2; i < n; i++) {
        dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i];
    }
  
    // return the minimum
    return min(dp[n - 2], dp[n - 1]);
}
  
// Driver Code
int main()
{
    int a[] = { 16, 19, 10, 12, 18 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << minimumCost(a, n);
    return 0;
}

Java

// Java program to find the 


// minimum cost required to
// reach the n-th floor
import java.io.*;
import java.util.*;
  
class GFG
{
// function to find 
// the minimum cost

1932
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

// to reach N-th floor


static int minimumCost(int cost[], 
                       int n)
{
    // declare an array
    int dp[] = new int[n];
  
    // base case
    if (n == 1)
        return cost[0];
  
    // initially to 
    // climb till 0-th
    // or 1th stair
    dp[0] = cost[0];
    dp[1] = cost[1];
  
    // iterate for finding the cost
    for (int i = 2; i < n; i++)
    {
        dp[i] = Math.min(dp[i - 1], 
                         dp[i - 2]) + cost[i];
    }
  
    // return the minimum
    return Math.min(dp[n - 2], 
                    dp[n - 1]);
}
  
// Driver Code
public static void main(String args[])
{
    int a[] = { 16, 19, 10, 12, 18 };
    int n = a.length;
    System.out.print(minimumCost(a, n));
}
}

Python 3

# Python 3 program to find 


# the minimum cost required 
# to reach the n-th floor
  
# function to find the minimum 
# cost to reach N-th floor
def minimumCost(cost, n):
  

1933
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

    # declare an array


    dp = [None]*n
  
    # base case
    if n == 1:
        return cost[0]
  
    # initially to climb 
    # till 0-th or 1th stair
    dp[0] = cost[0]
    dp[1] = cost[1]
  
    # iterate for finding the cost
    for i in range(2, n): 
        dp[i] = min(dp[i - 1], 
                    dp[i - 2]) + cost[i]
  
    # return the minimum
    return min(dp[n - 2], dp[n - 1])
  
# Driver Code
if __name__ == "__main__":
    a = [16, 19, 10, 12, 18 ]
    n = len(a)
    print(minimumCost(a, n))
  
# This code is contributed 
# by ChitraNayal

C#

// C# program to find the 


// minimum cost required to
// reach the n-th floor
using System;
  
class GFG
{
// function to find 
// the minimum cost
// to reach N-th floor
static int minimumCost(int[] cost, 
                       int n)
{
    // declare an array
    int []dp = new int[n];
  
    // base case

1934
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

    if (n == 1)
        return cost[0];
  
    // initially to 
    // climb till 0-th
    // or 1th stair
    dp[0] = cost[0];
    dp[1] = cost[1];
  
    // iterate for finding the cost
    for (int i = 2; i < n; i++)
    {
        dp[i] = Math.Min(dp[i - 1], 
                         dp[i - 2]) + cost[i];
    }
  
    // return the minimum
    return Math.Min(dp[n - 2], 
                    dp[n - 1]);
}
  
// Driver Code
public static void Main()
{
    int []a = { 16, 19, 10, 12, 18 };
    int n = a.Length;
    Console.WriteLine(minimumCost(a, n));
}
}
  
// This code is contributed
// by Subhadeep

PHP

<?php
// PHP program to find the 
// minimum cost required 
// to reach the n-th floor
  
// function to find the minimum 
// cost to reach N-th floor
function minimumCost(&$cost, $n)
{
    // declare an array
  
    // base case
    if ($n == 1)

1935
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

        return $cost[0];
  
    // initially to climb 
    // till 0-th or 1th stair
    $dp[0] = $cost[0];
    $dp[1] = $cost[1];
  
    // iterate for finding 
    // the cost
    for ($i = 2; $i < $n; $i++) 
    {
        $dp[$i] = min($dp[$i - 1], 
                      $dp[$i - 2]) + 
                      $cost[$i];
    }
  
    // return the minimum
    return min($dp[$n - 2], 
               $dp[$n - 1]);
}
  
// Driver Code
$a = array(16, 19, 10, 12, 18);
$n = sizeof($a);
echo(minimumCost($a, $n));
      
// This code is contributed
// by Shivi_Aggarwal
?>

Output:

31

Time Complexity: O(N)


Auxiliary Space: O(N)
Space-optimized Approach: Instead of using dp[] array for memoizing the cost, use two
variable dp1 and dp2. Since the cost of reaching the last two stairs are required only, use
two variables and update them by swapping when one stair is climbed.
Below is the implementation of the above approach:

C++

// C++ program to find the minimum


// cost required to reach the n-th floor

1936
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

// space-optimized solution
#include <bits/stdc++.h>
using namespace std;
  
// function to find the minimum cost
// to reach N-th floor
int minimumCost(int cost[], int n)
{
    int dp1 = 0, dp2 = 0;
  
    // traverse till N-th stair
    for (int i = 0; i < n; i++) {
        int dp0 = cost[i] + min(dp1, dp2);
  
        // update the last two stairs value
        dp2 = dp1;
        dp1 = dp0;
    }
    return min(dp1, dp2);
}
// Driver Code
int main()
{
    int a[] = { 2, 5, 3, 1, 7, 3, 4 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << minimumCost(a, n);
    return 0;
}

Java

// Java program to find the 


// minimum cost required to 
// reach the n-th floor 
// space-optimized solution
import java.io.*;
import java.util.*;
  
class GFG
{
// function to find 
// the minimum cost
// to reach N-th floor
static int minimumCost(int cost[], int n)
{
    int dp1 = 0, dp2 = 0;
  
    // traverse till N-th stair

1937
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

    for (int i = 0; i < n; i++) 


    {
        int dp0 = cost[i] + 
                  Math.min(dp1, dp2);
  
        // update the last 
        // two stairs value
        dp2 = dp1;
        dp1 = dp0;
    }
    return Math.min(dp1, dp2);
}
  
// Driver Code
public static void main(String args[])
{
    int a[] = { 2, 5, 3, 1, 7, 3, 4 };
    int n = a.length;
    System.out.print(minimumCost(a, n));
}
}

Python 3

# Python 3 program to find 


# the minimum cost required 
# to reach the n-th floor
# space-optimized solution
  
# function to find the minimum 
# cost to reach N-th floor
def minimumCost(cost, n):
  
    dp1 = 0
    dp2 = 0
  
    # traverse till N-th stair
    for i in range(n):
        dp0 = cost[i] + min(dp1, dp2)
  
        # update the last
        # two stairs value
        dp2 = dp1
        dp1 = dp0
    return min(dp1, dp2)
  
# Driver Code
if __name__ == "__main__":

1938
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

    a = [ 2, 5, 3, 1, 7, 3, 4 ]
    n = len(a)
    print(minimumCost(a, n))
      
# This code is contributed
# by ChitraNayal

C#

// C# program to find the 


// minimum cost required to 
// reach the n-th floor 
// space-optimized solution
using System;
  
class GFG
{
// function to find 
// the minimum cost
// to reach N-th floor
static int minimumCost(int[] cost,
                       int n)
{
    int dp1 = 0, dp2 = 0;
  
    // traverse till N-th stair
    for (int i = 0; i < n; i++) 
    {
        int dp0 = cost[i] + 
                  Math.Min(dp1, dp2);
  
        // update the last 
        // two stairs value
        dp2 = dp1;
        dp1 = dp0;
    }
    return Math.Min(dp1, dp2);
}
  
// Driver Code
public static void Main()
{
    int[] a = { 2, 5, 3, 1, 7, 3, 4 };
    int n = a.Length;
    Console.Write(minimumCost(a, n));
}
}
  

1939
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

// This code is contributed


// by ChitraNayal

PHP

<?php
// PHP program to find the 
// minimum cost required to 
// reach the n-th floor 
// space-optimized solution
  
// function to find the minimum 
// cost to reach N-th floor
function minimumCost(&$cost, $n)
{
    $dp1 = 0;
    $dp2 = 0;
  
    // traverse till N-th stair
    for ($i = 0; $i < $n; $i++) 
    {
        $dp0 = $cost[$i] +
               min($dp1, $dp2);
  
        // update the last 
        // two stairs value
        $dp2 = $dp1;
        $dp1 = $dp0;
    }
    return min($dp1, $dp2);
}
// Driver Code
$a = array(2, 5, 3, 1, 7, 3, 4);
$n = sizeof($a);
echo (minimumCost($a, $n));
  
// This code is contributed
// by Shivi_Aggarwal
?>

Output:

Time Complexity: O(N)


Auxiliary Space: O(1)

1940
Chapter 266. Minimum cost to reach the top of the floor by climbing stairs

The following problem can be solved using top-down approach. In that case the recurrence
will be dp[i] = cost[i] + min(dp[i+1], dp[i+2]).
Improved By : Shivi_Aggarwal, tufan_gupta2000, ChitraNayal

Source

https://www.geeksforgeeks.org/minimum-cost-to-reach-the-top-of-the-floor-by-climbing-stairs/

1941
Chapter 267

Minimum cost to sort strings


using reversal operations of
different costs

Minimum cost to sort strings using reversal operations of different costs - GeeksforGeeks
Given an array of strings and costs of reversing all strings, we need to sort the array. We
cannot move strings in array, only string reversal is allowed. We need to reverse some of the
strings in such a way that all strings make a lexicographic order and cost is also minimized.
If it is not possible to sort strings in any way, output not possible.
Examples:

Input : arr[] = {“aa”, “ba”, “ac”},


reverseCost[] = {1, 3, 1}
Output : Minimum cost of sorting = 1
Explanation : We can make above string array sorted
by reversing one of 2nd or 3rd string, but reversing
2nd string cost 3, so we will reverse 3rd string to
make string array sorted with a cost 1 which is
minimum.

We can solve this problem using dynamic programming. We make a 2D array for storing
the minimum cost of sorting.

dp[i][j] represents the minimum cost to make first i


strings sorted.
j = 1 means i'th string is reversed.
j = 0 means i'th string is not reversed.

1942
Chapter 267. Minimum cost to sort strings using reversal operations of different costs

Value of dp[i][j] is computed using dp[i-1][1] and


dp[i-1][0].

Computation of dp[i][0]
If arr[i] is greater than str[i-1], we update dp[i][0]
by dp[i-1][0]
If arr[i] is greater than reversal of previous string
we update dp[i][0] by dp[i-1][1]

Same procedure is applied to compute dp[i][1], we


reverse str[i] before applying the procedure.

At the end we will choose minimum of dp[N-1][0] and


dp[N-1][1] as our final answer if both of them not
updated yet even once, we will flag that sorting is
not possible.

Below is the implementation of above idea.

C/C++

// C++ program to get minimum cost to sort


// strings by reversal operation
#include <bits/stdc++.h>
using namespace std;
  
// Returns minimum cost for sorting arr[]
// using reverse operation. This function
// returns -1 if it is not possible to sort.
int minCost(string arr[], int cost[], int N)
{
    // dp[i][j] represents the minimum cost to
    // make first i strings sorted.
    // j = 1 means i'th string is reversed.
    // j = 0 means i'th string is not reversed.
    int dp[N][2];
  
    //  initializing dp array for first string
    dp[0][0] = 0;
    dp[0][1] = cost[0];
  
    //  getting array of reversed strings
    string revStr[N];
    for (int i = 0; i < N; i++)
    {
        revStr[i] = arr[i];
        reverse(revStr[i].begin(), revStr[i].end());

1943
Chapter 267. Minimum cost to sort strings using reversal operations of different costs

    }
  
    string curStr;
    int curCost;
  
    //  looping for all strings
    for (int i = 1; i < N; i++)
    {
        // Looping twice, once for string and once
        // for reversed string
        for (int j = 0; j < 2; j++)
        {
            dp[i][j] = INT_MAX;
  
            // getting current string and current
            // cost according to j
            curStr = (j == 0) ? arr[i] : revStr[i];
            curCost = (j == 0) ? 0 : cost[i];
  
            // Update dp value only if current string
            // is lexicographically larger
            if (curStr >= arr[i - 1])
                dp[i][j] = min(dp[i][j], dp[i-1][0] + curCost);
            if (curStr >= revStr[i - 1])
                dp[i][j] = min(dp[i][j], dp[i-1][1] + curCost);
        }
    }
  
    //  getting minimum from both entries of last index
    int res = min(dp[N-1][0], dp[N-1][1]);
  
    return (res == INT_MAX)? -1 : res;
}
  
//  Driver code to test above methods
int main()
{
    string arr[] = {"aa", "ba", "ac"};
    int cost[] = {1, 3, 1};
    int N = sizeof(arr) / sizeof(arr[0]);
  
    int res = minCost(arr, cost, N);
    if (res == -1)
        cout << "Sorting not possible\n";
    else
        cout << "Minimum cost to sort strings is "
             << res;
}

1944
Chapter 267. Minimum cost to sort strings using reversal operations of different costs

Python

# Python program to get minimum cost to sort


# strings by reversal operation
  
# Returns minimum cost for sorting arr[]
# using reverse operation. This function
# returns -1 if it is not possible to sort.
def ReverseStringMin(arr, reverseCost, n):
      
    # dp[i][j] represents the minimum cost to
    # make first i strings sorted.
    # j = 1 means i'th string is reversed.
    # j = 0 means i'th string is not reversed.
     
    dp = [[float("Inf")] * 2  for i in range(n)]
  
    # initializing dp array for first string
    dp[0][0] = 0
  
    dp[0][1] = reverseCost[0]
  
    # getting array of reversed strings
    rev_arr = [i[::-1] for i in arr]
  
    # looping for all strings
    for i in range(1, n):
  
        # Looping twice, once for string and once
        # for reversed string
        for j in range(2):
  
            # getting current string and current
            # cost according to j
            curStr = arr[i] if j==0 else rev_arr[i]
  
            curCost = 0 if j==0 else reverseCost[i]
  
            # Update dp value only if current string
            # is lexicographically larger
            if (curStr >= arr[i - 1]):
  
                dp[i][j] = min(dp[i][j], dp[i-1][0] + curCost)
  
            if (curStr >= rev_arr[i - 1]):
  
                dp[i][j] = min(dp[i][j], dp[i-1][1] + curCost)
  

1945
Chapter 267. Minimum cost to sort strings using reversal operations of different costs

    #  getting minimum from both entries of last index


    res = min(dp[n-1][0], dp[n-1][1])
  
    return res if  res != float("Inf") else -1
  
  
#  Driver code 
def main():
  
  
    arr = ["aa", "ba", "ac"]
  
    reverseCost = [1, 3, 1]
  
    n = len(arr)
  
    dp = [float("Inf")] * n
  
    res = ReverseStringMin(arr, reverseCost,n)
  
    if res != -1 :
  
        print "Minimum cost to sort sorting is" , res
  
    else :
        print "Sorting not possible"
  
  
if __name__ == '__main__':
    main()
  
#This code is contributed by Neelam Yadav

Output:

Minimum cost to sort strings is 1

Source

https://www.geeksforgeeks.org/minimum-cost-sort-strings-using-reversal-operations-different-costs/

1946
Chapter 268

Minimum insertions to sort an


array

Minimum insertions to sort an array - GeeksforGeeks


Given an array of integer numbers, we need to sort this array in a minimum number of steps
where in one step we can insert any array element from its position to any other position.
Examples :

Input : arr[] = [2, 3, 5, 1, 4, 7, 6]


Output : 3
We can sort above array in 3 insertion
steps as shown below,
1 before array value 2
4 before array value 5
6 before array value 7

Input : arr[] = {4, 6, 5, 1}


Output : 2

We can solve this problem using dynamic programming. The main thing to observe is that
moving an element doesn’t change the relative order of elements other than the element
which is being moved. Now consider longest increasing subsequenc (LIS)e in which equal
element are also taken as part of the increasing sequence, now if keep the element of this
increasing sequence as it is and move all other elements then it will take the least number of
steps because we have taken longest subsequence which does not need to be moved. Finally,
the answer will be the size of the array minus the size of the longest increasing subsequence.
As LIS problem can be solved in O(N^2) with O(N) extra space using Dynamic Program-
ming.
Below is the implementation of above idea.
C++

1947
Chapter 268. Minimum insertions to sort an array

// C++ program to get minimum number of insertion


// steps to sort an array
#include <bits/stdc++.h>
using namespace std;
  
//  method returns min steps of insertion we need
// to perform to sort array 'arr'
int minInsertionStepToSortArray(int arr[], int N)
{
    // lis[i] is going to store length of lis
    // that ends with i.
    int lis[N];
  
    /* Initialize lis values for all indexes */
    for (int i = 0; i < N; i++)
        lis[i] = 1;
  
    /* Compute optimized lis values in bottom up manner */
    for (int i = 1; i < N; i++)
        for (int j = 0; j < i; j++)
            if (arr[i] >= arr[j] && lis[i] < lis[j] + 1)
                lis[i] = lis[j] + 1;
  
    /* The overall LIS must end with of of the array
       elements. Pick maximum of all lis values */
    int max = 0;
    for (int i = 0; i < N; i++)
        if (max < lis[i])
            max = lis[i];
  
    // return size of array minus length of LIS
    // as final result
    return (N - max);
}
  
// Driver code to test above methods
int main()
{
    int arr[] = {2, 3, 5, 1, 4, 7, 6};
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << minInsertionStepToSortArray(arr, N);
    return 0;
}

Java

// Java program to get minimum number of insertion


// steps to sort an array

1948
Chapter 268. Minimum insertions to sort an array

class Main
{
  
    //  method returns min steps of insertion we need
    // to perform to sort array 'arr'
    static int minInsertionStepToSortArray(int arr[], int N)
    {
        // lis[i] is going to store length of lis
        // that ends with i.
        int[] lis = new int[N];
       
        /* Initialize lis values for all indexes */
        for (int i = 0; i < N; i++)
            lis[i] = 1;
       
        /* Compute optimized lis values in bottom up manner */
        for (int i = 1; i < N; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] >= arr[j] && lis[i] < lis[j] + 1)
                    lis[i] = lis[j] + 1;
       
        /* The overall LIS must end with of of the array
           elements. Pick maximum of all lis values */
        int max = 0;
        for (int i = 0; i < N; i++)
            if (max < lis[i])
                max = lis[i];
       
        // return size of array minus length of LIS
        // as final result
        return (N - max);
    }
       
    // Driver code to test above methods
    public static void main (String[] args)
    {
        int arr[] = {2, 3, 5, 1, 4, 7, 6};
        int N = arr.length;
        System.out.println(minInsertionStepToSortArray(arr, N));
    }
}
  
/* This code is contributed by Harsh Agarwal */

C#

// C# program to get minimum number of


// insertion steps to sort an array

1949
Chapter 268. Minimum insertions to sort an array

using System;
  
class GfG {
      
    // method returns min steps of insertion
    // we need to perform to sort array 'arr'
    static int minInsertionStepToSortArray(
                             int []arr, int N)
    {
          
        // lis[i] is going to store length
        // of lis that ends with i.
        int[] lis = new int[N];
      
        /* Initialize lis values for all
        indexes */
        for (int i = 0; i < N; i++)
            lis[i] = 1;
      
        /* Compute optimized lis values in
        bottom up manner */
        for (int i = 1; i < N; i++)
            for (int j = 0; j < i; j++)
                if (arr[i] >= arr[j] && 
                        lis[i] < lis[j] + 1)
                    lis[i] = lis[j] + 1;
      
        /* The overall LIS must end with of
        of the array elements. Pick maximum
        of all lis values */
        int max = 0;
          
        for (int i = 0; i < N; i++)
            if (max < lis[i])
                max = lis[i];
      
        // return size of array minus length
        // of LIS as final result
        return (N - max);
    }
      
    // Driver code to test above methods
    public static void Main (String[] args)
    {
        int []arr = {2, 3, 5, 1, 4, 7, 6};
        int N = arr.Length;
          
        Console.Write(

1950
Chapter 268. Minimum insertions to sort an array

          minInsertionStepToSortArray(arr, N));
    }
}
  
// This code is contributed by parashar.

PHP

<?php
// PHP program to get minimum 
// number of insertion steps
// to sort an array
  
// method returns min steps of 
// insertion we need to perform 
// to sort array 'arr'
function minInsertionStepToSortArray($arr, $N)
{
    // lis[i] is going to store
    // length of lis that ends with i.
    $lis[$N] = 0;
  
    /* Initialize lis values
    for all indexes */
    for ($i = 0; $i < $N; $i++)
        $lis[$i] = 1;
  
    /* Compute optimized lis values
       in bottom up manner */
    for ($i = 1; $i < $N; $i++)
        for ($j = 0; $j < $i; $j++)
            if ($arr[$i] >= $arr[$j] && 
                $lis[$i] < $lis[$j] + 1)
                  
                $lis[$i] = $lis[$j] + 1;
  
    /* The overall LIS must end with 
    of of the array elements. Pick 
    maximum of all lis values */
    $max = 0;
    for ($i = 0; $i < $N; $i++)
        if ($max < $lis[$i])
            $max = $lis[$i];
  
    // return size of array minus 
    // length of LIS as final result
    return ($N - $max);
}

1951
Chapter 268. Minimum insertions to sort an array

  
// Driver code 
$arr = array(2, 3, 5, 1, 4, 7, 6);
$N = sizeof($arr) / sizeof($arr[0]);
echo minInsertionStepToSortArray($arr, $N);
      
// This code is contributed by nitin mittal
?>

Output :

Improved By : parashar, nitin mittal

Source

https://www.geeksforgeeks.org/minimum-insertions-sort-array/

1952
Chapter 269

Minimum jumps to reach last


building in a matrix

Minimum jumps to reach last building in a matrix - GeeksforGeeks


Given a matrix containing an integer value, In which each cell of the matrix represents
height of building. Find minimum jumps needed reach from First building (0, 0) to last
(n-1, m-1). Jump from a cell to next cell is absolute difference between two building heights.
Examples :

Input : int height[][] = {{ 5, 4, 2 },


{ 9, 2, 1 },
{ 2, 5, 9 },
{ 1, 3, 11}};
Output : 12
The minimum jump path is 5 -> 2 -> 5
-> 11. Total jumps is 3 + 3 + 6 = 12.

Naive Recursive Solution:


The above problem can be solve easily by using recursion. The path to reach (m, n) must
be through one of the 3 cells: (m-1, n-1) or (m-1, n) or (m, n-1). So minimum jump to
reach (m, n) can be written as “minimum jump of the 3 cells plus current jump.
Below is the implementation of the approach.
C++

// Recursive CPP program to find minimum jumps


// to reach last building from first.
#include <bits/stdc++.h>
using namespace std;
  

1953
Chapter 269. Minimum jumps to reach last building in a matrix

# define R 4
# define C 3
  
bool isSafe(int x, int y)
{
    return (x < R && y < C);
}
  
/* Returns minimum jump path from (0, 0) to 
  (m, n) in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
    // base case
    if (x == R - 1 && y == C - 1)
        return 0;
  
    // Find minimum jumps if we go through diagonal
    int diag = INT_MAX;
    if (isSafe(x + 1, y + 1))
        diag = minJump(height, x + 1, y + 1) +
           abs(height[x][y] - height[x + 1][y + 1]);
  
    // Find minimum jumps if we go through down
    int down = INT_MAX;
    if (isSafe(x + 1, y))
        down = minJump(height, x + 1, y) + 
             abs(height[x][y] - height[x + 1][y]);
  
    // Find minimum jumps if we go through right
    int right = INT_MAX;
    if (isSafe(x, y + 1))
        right = minJump(height, x, y + 1) + 
              abs(height[x][y] - height[x][y + 1]);
  
    // return minimum jumps
    return min({down, right, diag});
}
  
/* Driver program to test above functions */
int main()
{
    int height[][C] = { { 5, 4, 2 },
                       { 9, 2, 1 },
                       { 2, 5, 9 },
                       { 1, 3, 11 } };
  
    cout << minJump(height, 0, 0);
    return 0;

1954
Chapter 269. Minimum jumps to reach last building in a matrix

Java

// Recursive Java program


// to find minimum jumps
// to reach last building 
// from first.
class GFG {
      
    static boolean isSafe(int x, int y)
    {
        return (x < 4 && y < 3);
    }
      
    // Returns minimum jump
    // path from (0, 0) to 
    // (m, n) in hight[R][C]
    static int minJump(int height[][], int x,
                                       int y)
    {
        // base case
        if (x == 4 - 1 && y == 3 - 1)
            return 0;
      
        // Find minimum jumps 
        // if we go through 
        // diagonal
        int diag = Integer.MAX_VALUE;
          
        if (isSafe(x + 1, y + 1))
            diag = minJump(height, x + 1, y + 1) +
                   Math.abs(height[x][y] - height[x + 1][y + 1]);
      
        // Find minimum jumps
        // if we go through
        // down
        int down = Integer.MAX_VALUE;
          
        if (isSafe(x + 1, y))
            down = minJump(height, x + 1, y) +
                   Math.abs(height[x][y] - height[x + 1][y]);
      
        // Find minimum jumps
        // if we go through right
        int right = Integer.MAX_VALUE;
          
        if (isSafe(x, y + 1))

1955
Chapter 269. Minimum jumps to reach last building in a matrix

            right = minJump(height, x, y + 1) +
                    Math.abs(height[x][y] - height[x][y + 1]);
      
        // return minimum jumps
        return Math.min(down, Math.min(right, diag));
    }
      
    // Driver program 
    public static void main(String[] args)
    {
        int height[][] = { { 5, 4, 2 },
                           { 9, 2, 1 },
                           { 2, 5, 9 },
                           { 1, 3, 11} };
      
        System.out.println(minJump(height, 0, 0));
    }
}
  
// This article is contributed by Prerna Saini.

C#

// Recursive C# program
// to find minimum jumps
// to reach last building 
// from first.
using System;
  
class GFG {
      
    static bool isSafe(int x, int y)
    {
        return (x < 4 && y < 3);
    }
      
    // Returns minimum jump
    // path from (0, 0) to 
    // (m, n) in hight[R][C]
    static int minJump(int [,]height, 
                       int x, int y)
    {
          
        // base case
        if (x == 4 - 1 && y == 3 - 1)
            return 0;
      
        // Find minimum jumps 

1956
Chapter 269. Minimum jumps to reach last building in a matrix

        // if we go through 
        // diagonal
        int diag = int.MaxValue;
          
        if (isSafe(x + 1, y + 1))
            diag = minJump(height, x + 1, y + 1) +
                   Math.Abs(height[x,y] - 
                   height[x + 1,y + 1]);
      
        // Find minimum jumps
        // if we go through
        // down
        int down = int.MaxValue;
          
        if (isSafe(x + 1, y))
            down = minJump(height, x + 1, y) +
                   Math.Abs(height[x,y] - 
                   height[x + 1,y]);
      
        // Find minimum jumps
        // if we go through right
        int right = int.MaxValue;
          
        if (isSafe(x, y + 1))
            right = minJump(height, x, y + 1) +
                    Math.Abs(height[x,y] - 
                    height[x,y + 1]);
      
        // return minimum jumps
        return Math.Min(down, Math.Min(right, diag));
    }
      
    // Driver code
    public static void Main()
    {
        int [,]height = {{5, 4, 2},
                        {9, 2, 1},
                        {2, 5, 9},
                        {1, 3, 11}};
      
        Console.Write(minJump(height, 0, 0));
    }
}
  
// This code is contributed by nitin mittal

PHP

1957
Chapter 269. Minimum jumps to reach last building in a matrix

<?php
  
// Recursive PHP program to 
// find minimum jumps to 
// reach last building from first.
$R = 4;
$C = 3;
  
function isSafe($x, $y)
{
    global $R, $C;
    return ($x < $R and $y < $C);
}
  
// Returns minimum jump
// path from (0, 0) to 
// (m, n) in hight[R][C]
function minJump($height, $x, $y)
{
    global $R, $C;
      
    // base case
    if ($x == $R - 1 and $y == $C - 1)
        return 0;
  
    // Find minimum jumps if
    // we go through diagonal
    $diag = PHP_INT_MAX;
    if (isSafe($x + 1, $y + 1))
        $diag = minJump($height, $x + 1, $y + 1) +
                             abs($height[$x][$y] - 
                         $height[$x + 1][$y + 1]);
  
    // Find minimum jumps
    // if we go through down
    $down = PHP_INT_MAX;
    if (isSafe($x + 1, $y))
        $down = minJump($height, $x + 1, $y) + 
                         abs($height[$x][$y] - 
                         $height[$x + 1][$y]);
  
    // Find minimum jumps if
    // we go through right
    $right = PHP_INT_MAX;
    if (isSafe($x, $y + 1))
        $right = minJump($height, $x, $y + 1) + 
                          abs($height[$x][$y] - 
                          $height[$x][$y + 1]);

1958
Chapter 269. Minimum jumps to reach last building in a matrix

  
    // return minimum jumps
    return min($down, min($right, $diag));
}
  
// Driver Code
$height = array(array( 5, 4, 2 ),
                array( 9, 2, 1 ),
                array( 2, 5, 9 ),
                array( 1, 3, 11 ));
  
echo minJump($height, 0, 0);
  
// This code is contributed by anuj_67.
?>

Output :

12

Time complexity of this solution is exponential.


Dynamic Programming Solution:
If we draw recursion tree of above recursive solution, we can observe overlapping subprob-
lems. Since the problem has overlapping subproblems, we can solve it efficiently using
Dynamic Programming. Below is Dynamic Programming based solution.

// A Dynamic Programming based CPP program to find


// minimum jumps to reach last building from first.
#include <bits/stdc++.h>
using namespace std;
  
#define R 4
#define C 3
  
bool isSafe(int x, int y)
{
    return (x < R && y < C);
}
  
// Lookup table used for memoization.
int dp[R][C];
  
/* Returns minimum jump path from (0, 0) to (m, n)
   in hight[R][C]*/
int minJump(int height[R][C], int x, int y)
{
    // if we visited it before

1959
Chapter 269. Minimum jumps to reach last building in a matrix

    if (dp[x][y] != -1)


        return dp[x][y];
  
    if (x == R - 1 && y == C - 1)
        return (dp[x][y] = 0);
  
    // Find minimum jumps if we go through diagonal
    int diag = INT_MAX;
    if (isSafe(x + 1, y + 1))
        diag = minJump(height, x + 1, y + 1) +
           abs(height[x][y] - height[x + 1][y + 1]);
  
    // Find minimum jumps if we go through down
    int down = INT_MAX;
    if (isSafe(x + 1, y))
        down = minJump(height, x + 1, y) + 
             abs(height[x][y] - height[x + 1][y]);
  
    // Find minimum jumps if we go through right
    int right = INT_MAX;
    if (isSafe(x, y + 1))
        right = minJump(height, x, y + 1) + 
              abs(height[x][y] - height[x][y + 1]);
  
    // return minimum jump
    dp[x][y] = min({down, right, diag});
    return dp[x][y];
}
  
/* Driver program to test above functions */
int main()
{
    int height[][C] = { { 5, 4, 2 },
                       { 9, 2, 1 },
                       { 2, 5, 9 },
                       { 1, 3, 11 } };
    memset(dp, -1, sizeof(dp));
    cout << minJump(height, 0, 0);
    return 0;
}

Output:

12

Time complexity: (R*C)


Improved By : nitin mittal, vt_m

1960
Chapter 269. Minimum jumps to reach last building in a matrix

Source

https://www.geeksforgeeks.org/minimum-jumps-to-reach-last-building-in-a-matrix/

1961
Chapter 270

Minimum number of deletions


and insertions to transform one
string into another

Minimum number of deletions and insertions to transform one string into another - Geeks-
forGeeks
Given two strings ‘str1’ and ‘str2’ of size m and n respectively. The task is to remove/delete
and insert minimum number of characters from/in str1 so as to transform it into str2. It
could be possible that the same character needs to be removed/deleted from one point of
str1 and inserted to some another point.
Examples:

Input : str1 = "heap", str2 = "pea"


Output : Minimum Deletion = 2 and
Minimum Insertion = 1
p and h deleted from heap
Then, p is inserted at the beginning
One thing to note, though p was required yet
it was removed/deleted first from its position and
then it is inserted to some other position.
Thus, p contributes one to the deletion_count
and one to the insertion_count.

Input : str1 = "geeksforgeeks", str2 = "geeks"


Output : Minimum Deletion = 8
Minimum Insertion = 0

A simple solution is to consider all subsequences of str1 and for each subsequence calculate

1962
Chapter 270. Minimum number of deletions and insertions to transform one string into
another

minimum deletions and insertions so as to transform it into str2. A very complex method
and the time complexity of this solution is exponential.
An efficient approach uses the concept of finding the length of the longest common sub-
sequence of the given two sequences.
Algorithm:

-->str1 and str2 be the given strings.


-->m and n be their lengths respectively.
-->len be the length of the longest
common subsequence of str1 and str2
-->// minimum number of deletions
minDel = m - len
-->// minimum number of Insertions
minInsert = n - len

C++

// Dynamic Programming C++ implementation to find 


// minimum number of deletions and insertions
#include <bits/stdc++.h>
    
using namespace std;  
    
// Returns length of length common subsequence
// for str1[0..m-1], str2[0..n-1]
int lcs(string str1, string str2, int m, int n )
{
   int L[m+1][n+1];
   int i, j;
    
   // Following steps build L[m+1][n+1] in bottom
   // up fashion. Note that L[i][j] contains 
   // length of LCS of str1[0..i-1] and str2[0..j-1] 
   for (i=0; i<=m; i++)
   {
     for (j=0; j<=n; j++)
     {
       if (i == 0 || j == 0)
         L[i][j] = 0;
    
       else if (str1.at(i-1) == str2.at(j-1))
         L[i][j] = L[i-1][j-1] + 1;
    
       else
         L[i][j] = max(L[i-1][j], L[i][j-1]);

1963
Chapter 270. Minimum number of deletions and insertions to transform one string into
another

     }
   }
      
   // L[m][n] contains length of LCS 
   // for X[0..n-1] and Y[0..m-1] 
   return L[m][n];
}
    
// function to find minimum number 
// of deletions and insertions 
void printMinDelAndInsert(string str1, string str2)  
{
    int m = str1.size();
    int n = str2.size();
      
    int len = lcs(str1, str2, m, n);
      
    cout << "Minimum number of deletions = "
         << (m - len) << endl;
        
    cout << "Minimum number of insertions = "   
         << (n - len) << endl;  
}
    
// Driver program to test above
int main()
{
  string str1 = "heap";
  string str2 = "pea";  
  printMinDelAndInsert(str1, str2); 
  return 0;

Java

// Dynamic Programming Java implementation 


// to find minimum number of deletions and 
// insertions
import java.io.*;
  
class GFG {
      
    // Returns length of length common 
    // subsequence for str1[0..m-1], 
    // str2[0..n-1]
    static int lcs(String str1, String str2,
                           int m, int n )
    {

1964
Chapter 270. Minimum number of deletions and insertions to transform one string into
another

        int L[][] = new int[m+1][n+1];


        int i, j;
  
    // Following steps build L[m+1][n+1] in
    // bottom up fashion. Note that L[i][j]
    // contains length of LCS of str1[0..i-1]
    // and str2[0..j-1] 
    for (i = 0; i <= m; i++)
    {
        for (j = 0; j <= n; j++)
        {
            if (i == 0 || j == 0)
            L[i][j] = 0;
  
        else if (str1.charAt(i-1) == str2.charAt(
                                       j-1))
            L[i][j] = L[i-1][j-1] + 1;
  
        else
            L[i][j] = Math.max(L[i-1][j], 
                               L[i][j-1]);
        }
    }
      
    // L[m][n] contains length of LCS 
    // for X[0..n-1] and Y[0..m-1] 
    return L[m][n];
    }
  
    // function to find minimum number 
    // of deletions and insertions 
    static void printMinDelAndInsert(String str1, 
                                    String str2) 
    {
        int m = str1.length();
        int n = str2.length();
      
        int len = lcs(str1, str2, m, n);
      
        System.out.println("Minimum number of "+
                           "deletions = ");
        System.out.println(m - len);
      
        System.out.println("Minimum number of "+
                           "insertions = "); 
        System.out.println(n - len); 
    }
  

1965
Chapter 270. Minimum number of deletions and insertions to transform one string into
another

    // Driver program to test above


    public static void main(String[] args)
    {
    String str1 = new String("heap");
    String str2 = new String("pea"); 
    printMinDelAndInsert(str1, str2); 
    } 
}
// This code is contributed by Prerna Saini

C#

// Dynamic Programming C# implementation 


// to find minimum number of deletions and 
// insertions
using System;
  
class GFG {
      
    // Returns length of length common 
    // subsequence for str1[0..m-1], 
    // str2[0..n-1]
    static int lcs(string str1, string str2,
                              int m, int n )
    {
        int [,]L = new int[m+1,n+1];
        int i, j;
  
        // Following steps build L[m+1][n+1] in
        // bottom up fashion. Note that L[i][j]
        // contains length of LCS of str1[0..i-1]
        // and str2[0..j-1] 
        for (i = 0; i <= m; i++)
        {
            for (j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    L[i,j] = 0;
      
                else if (str1[i-1] == str2[j-1])
                    L[i,j] = L[i-1,j-1] + 1;
      
                else
                    L[i,j] = Math.Max(L[i-1,j], 
                                       L[i,j-1]);
            }
        }
          

1966
Chapter 270. Minimum number of deletions and insertions to transform one string into
another

        // L[m][n] contains length of LCS 


        // for X[0..n-1] and Y[0..m-1] 
        return L[m,n];
    }
  
    // function to find minimum number 
    // of deletions and insertions 
    static void printMinDelAndInsert(string str1, 
                                     string str2) 
    {
        int m = str1.Length;
        int n = str2.Length;
      
        int len = lcs(str1, str2, m, n);
      
        Console.Write("Minimum number of "+
                                "deletions = ");
        Console.WriteLine(m - len);
      
        Console.Write("Minimum number of "+
                               "insertions = "); 
        Console.Write(n - len); 
    }
  
    // Driver program to test above
    public static void Main()
    {
        string str1 = new string("heap");
        string str2 = new string("pea"); 
        printMinDelAndInsert(str1, str2); 
    } 
}
  
// This code is contributed by nitin mittal.

Output:

Minimum number of deletions = 2


Minimum number of insertions = 1

Time Complexity: O(m * n)


Improved By : nitin mittal

Source
https://www.geeksforgeeks.org/minimum-number-deletions-insertions-transform-one-string-another/

1967
Chapter 271

Minimum number of deletions


to make a sorted sequence

Minimum number of deletions to make a sorted sequence - GeeksforGeeks


Given an array of n integers. The task is to remove or delete minimum number of elements
from the array so that when the remaining elements are placed in the same sequence order
form a sorted sequence.
Examples :

Input : {5, 6, 1, 7, 4}
Output : 2
Removing 1 and 4
leaves the remaining sequence order as
5 6 7 which is a sorted sequence.

Input : {30, 40, 2, 5, 1, 7, 45, 50, 8}


Output : 4

A simple solution is to remove all subsequences one by one and check if remaining set of
elements are in sorted order or not. Time complexity of this solution is exponential.
An efficient approach uses the concept of finding the length of the longest increasing
subsequence of a given sequence.
Algorithm:

-->arr be the given array.


-->n number of elements in arr.
-->len be the length of longest
increasing subsequence in arr.

1968
Chapter 271. Minimum number of deletions to make a sorted sequence

-->// minimum number of deletions


min = n - len

C++

// C++ implementation to find 


// minimum number of deletions 
// to make a sorted sequence
#include <bits/stdc++.h>
using namespace std;
  
/* lis() returns the length
   of the longest increasing 
   subsequence in arr[] of size n */
int lis( int arr[], int n )
{
    int result = 0;
    int lis[n];
  
    /* Initialize LIS values
    for all indexes */
    for (int i = 0; i < n; i++ )
        lis[i] = 1;
  
    /* Compute optimized LIS 
       values in bottom up manner */
    for (int i = 1; i < n; i++ )
        for (int j = 0; j < i; j++ )
            if ( arr[i] > arr[j] &&
                 lis[i] < lis[j] + 1)
            lis[i] = lis[j] + 1;
  
    /* Pick resultimum 
    of all LIS values */
    for (int i = 0; i < n; i++ )
        if (result < lis[i])
            result = lis[i];
  
    return result;
}
  
// function to calculate minimum
// number of deletions
int minimumNumberOfDeletions(int arr[], 
                             int n)
{
    // Find longest increasing 
    // subsequence

1969
Chapter 271. Minimum number of deletions to make a sorted sequence

    int len = lis(arr, n);


  
    // After removing elements 
    // other than the lis, we 
    // get sorted sequence.
    return (n - len);
}
  
// Driver Code
int main()
{
    int arr[] = {30, 40, 2, 5, 1,
                   7, 45, 50, 8};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Minimum number of deletions = "
         << minimumNumberOfDeletions(arr, n);
    return 0;
}

Java

// Java implementation to find


// minimum number of deletions 
// to make a sorted sequence
  
class GFG
{
    /* lis() returns the length 
    of the longest increasing 
    subsequence in arr[] of size n */
    static int lis( int arr[], int n )
    {
        int result = 0;
        int[] lis = new int[n];
      
        /* Initialize LIS values 
        for all indexes */
        for (int i = 0; i < n; i++ )
            lis[i] = 1;
      
        /* Compute optimized LIS 
           values in bottom up manner */
        for (int i = 1; i < n; i++ )
            for (int j = 0; j < i; j++ )
                if ( arr[i] > arr[j] &&
                    lis[i] < lis[j] + 1)
                    lis[i] = lis[j] + 1;
      

1970
Chapter 271. Minimum number of deletions to make a sorted sequence

        /* Pick resultimum of


        all LIS values */
        for (int i = 0; i < n; i++ )
            if (result < lis[i])
                result = lis[i];
      
        return result;
    }
      
    // function to calculate minimum
    // number of deletions
    static int minimumNumberOfDeletions(int arr[], 
                                        int n)
    {
        // Find longest 
        // increasing subsequence
        int len = lis(arr, n);
      
        // After removing elements 
        // other than the lis, we get
        // sorted sequence.
        return (n - len);
    }
  
    // Driver Code
    public static void main (String[] args) 
    {
        int arr[] = {30, 40, 2, 5, 1,
                       7, 45, 50, 8};
        int n = arr.length;
        System.out.println("Minimum number of" +
                               " deletions = " +
              minimumNumberOfDeletions(arr, n));
    }
}
  
/* This code is contributed by Harsh Agarwal */

Python3

# Python3 implementation to find 


# minimum number of deletions to
# make a sorted sequence
  
# lis() returns the length 
# of the longest increasing
# subsequence in arr[] of size n
def lis(arr, n):

1971
Chapter 271. Minimum number of deletions to make a sorted sequence

  
    result = 0
    lis = [0 for i in range(n)]
  
    # Initialize LIS values
    # for all indexes 
    for i in range(n):
        lis[i] = 1
  
    # Compute optimized LIS values 
    # in bottom up manner 
    for i in range(1, n):
        for j in range(i):
            if ( arr[i] > arr[j] and
                lis[i] < lis[j] + 1):
                lis[i] = lis[j] + 1
  
    # Pick resultimum 
    # of all LIS values 
    for i in range(n):
        if (result < lis[i]):
            result = lis[i]
  
    return result
  
# Function to calculate minimum
# number of deletions
def minimumNumberOfDeletions(arr, n):
  
    # Find longest increasing 
    # subsequence
    len = lis(arr, n)
  
    # After removing elements 
    # other than the lis, we 
    # get sorted sequence.
    return (n - len)
  
  
# Driver Code
arr = [30, 40, 2, 5, 1, 
          7, 45, 50, 8]
n = len(arr)
print("Minimum number of deletions = ",
      minimumNumberOfDeletions(arr, n))
          
# This code is contributed by Anant Agarwal.

1972
Chapter 271. Minimum number of deletions to make a sorted sequence

C#

// C# implementation to find
// minimum number of deletions 
// to make a sorted sequence
using System;
  
class GfG 
{
      
    /* lis() returns the length of
    the longest increasing subsequence
    in arr[] of size n */
    static int lis( int []arr, int n )
    {
        int result = 0;
        int[] lis = new int[n];
      
        /* Initialize LIS values for
        all indexes */
        for (int i = 0; i < n; i++ )
            lis[i] = 1;
      
        /* Compute optimized LIS values
        in bottom up manner */
        for (int i = 1; i < n; i++ )
            for (int j = 0; j < i; j++ )
                if ( arr[i] > arr[j] &&
                     lis[i] < lis[j] + 1)
                  lis[i] = lis[j] + 1;
      
        /* Pick resultimum of all LIS
        values */
        for (int i = 0; i < n; i++ )
            if (result < lis[i])
                result = lis[i];
      
        return result;
    }
      
    // function to calculate minimum
    // number of deletions
    static int minimumNumberOfDeletions(
                        int []arr, int n)
    {
          
        // Find longest increasing
        // subsequence

1973
Chapter 271. Minimum number of deletions to make a sorted sequence

        int len = lis(arr, n);


      
        // After removing elements other
        // than the lis, we get sorted
        // sequence.
        return (n - len);
    }
  
    // Driver Code
    public static void Main (String[] args) 
    {
        int []arr = {30, 40, 2, 5, 1, 
                       7, 45, 50, 8};
        int n = arr.Length;
        Console.Write("Minimum number of" + 
                          " deletions = " + 
         minimumNumberOfDeletions(arr, n));
    }
}
  
// This code is contributed by parashar.

PHP

<?php
// PHP implementation to find 
// minimum number of deletions 
// to make a sorted sequence
  
  
/* lis() returns the length of 
   the longest increasing subsequence
   in arr[] of size n */
function lis( $arr, $n )
{
    $result = 0;
    $lis[$n] = 0;
  
    /* Initialize LIS values
       for all indexes */
    for ($i = 0; $i < $n; $i++ )
        $lis[$i] = 1;
  
    /* Compute optimized LIS 
       values in bottom up manner */
    for ($i = 1; $i < $n; $i++ )
        for ($j = 0; $j < $i; $j++ )
            if ( $arr[$i] > $arr[$j] &&

1974
Chapter 271. Minimum number of deletions to make a sorted sequence

                $lis[$i] < $lis[$j] + 1)


                $lis[$i] = $lis[$j] + 1;
  
    /* Pick resultimum of 
    all LIS values */
    for ($i = 0; $i < $n; $i++ )
        if ($result < $lis[$i])
            $result = $lis[$i];
  
    return $result;
}
  
// function to calculate minimum
// number of deletions
function minimumNumberOfDeletions($arr, $n)
{
    // Find longest increasing
    // subsequence
    $len = lis($arr, $n);
  
    // After removing elements 
    // other than the lis, we
    // get sorted sequence.
    return ($n - $len);
}
  
// Driver Code
$arr = array(30, 40, 2, 5, 1, 
               7, 45, 50, 8);
$n = sizeof($arr) / sizeof($arr[0]);
echo "Minimum number of deletions = " , 
    minimumNumberOfDeletions($arr, $n);
  
// This code is contributed by nitin mittal.
?>

Output :

Minimum number of deletions = 4

Time Complexity : O(n2 )


Time Complexity can be decreased to O(nlogn) by finding the Longest Increasing Subse-
quence Size(N Log N)
Improved By : parashar, nitin mittal

1975
Chapter 271. Minimum number of deletions to make a sorted sequence

Source

https://www.geeksforgeeks.org/minimum-number-deletions-make-sorted-sequence/

1976
Chapter 272

Minimum number of deletions


to make a string palindrome

Minimum number of deletions to make a string palindrome - GeeksforGeeks


Given a string of size ‘n’. The task is to remove or delete minimum number of characters
from the string so that the resultant string is palindrome.
Note: The order of characters should be maintained.

Examples :

Input : aebcbda
Output : 2
Remove characters 'e' and 'd'
Resultant string will be 'abcba'
which is a palindromic string

Input : geeksforgeeks
Output : 8

A simple solution is to remove all subsequences one by one and check if remaining string
is palindrome or not. Time complexity of this solution is exponential.
An efficient approach uses the concept of finding the length of the longest palindromic
subsequence of a given sequence.
Algorithm:

-->str is the given string.


-->n length of str
-->len be the length of the longest

1977
Chapter 272. Minimum number of deletions to make a string palindrome

palindromic subsequence of str


-->// minimum number of deletions
min = n - len

C++

// C++ implementation to find 


// minimum number of deletions
// to make a string palindromic
#include <bits/stdc++.h>
using namespace std;
  
// Returns the length of 
// the longest palindromic 
// subsequence in 'str'
int lps(string str)
{
    int n = str.size();
  
    // Create a table to store
    // results of subproblems
    int L[n][n];
  
    // Strings of length 1
    // are palindrome of length 1
    for (int i = 0; i < n; i++)
        L[i][i] = 1;
  
    // Build the table. Note that 
    // the lower diagonal values 
    // of table are useless and 
    // not filled in the process. 
    // c1 is length of substring
    for (int cl = 2; cl <= n; cl++)
    {
        for (int i = 0; 
                 i < n - cl + 1; i++)
        {
            int j = i + cl - 1;
            if (str[i] == str[j] &&
                        cl == 2)
                L[i][j] = 2;
            else if (str[i] == str[j])
                L[i][j] = L[i + 1][j - 1] + 2;
            else
                L[i][j] = max(L[i][j - 1], 
                            L[i + 1][j]);
        }

1978
Chapter 272. Minimum number of deletions to make a string palindrome

    }
  
    // length of longest
    // palindromic subseq
    return L[0][n - 1];
}
  
// function to calculate 
// minimum number of deletions
int minimumNumberOfDeletions(string str)
{
    int n = str.size();
  
    // Find longest palindromic 
    // subsequence
    int len = lps(str);
  
    // After removing characters 
    // other than the lps, we 
    // get palindrome.
    return (n - len);
}
  
// Driver Code
int main()
{
    string str = "geeksforgeeks";
    cout << "Minimum number of deletions = "
         << minimumNumberOfDeletions(str);
    return 0;
}

Java

// Java implementation to 


// find minimum number of 
// deletions to make a 
// string palindromic
class GFG
{
    // Returns the length of
    // the longest palindromic
    // subsequence in 'str'
    static int lps(String str)
    {
        int n = str.length();
  
        // Create a table to store

1979
Chapter 272. Minimum number of deletions to make a string palindrome

        // results of subproblems


        int L[][] = new int[n][n];
  
        // Strings of length 1
        // are palindrome of length 1
        for (int i = 0; i < n; i++)
            L[i][i] = 1;
  
        // Build the table. Note 
        // that the lower diagonal 
        // values of table are useless 
        // and not filled in the process.
        // c1 is length of substring
        for (int cl = 2; cl <= n; cl++)
        {
            for (int i = 0; i < n - cl + 1; i++)
            {
                int j = i + cl - 1;
                if (str.charAt(i) == 
                        str.charAt(j) && cl == 2)
                    L[i][j] = 2;
                else if (str.charAt(i) == 
                              str.charAt(j))
                    L[i][j] = L[i + 1][j - 1] + 2;
                else
                    L[i][j] = Integer.max(L[i][j - 1],
                                         L[i + 1][j]);
            }
        }
  
        // length of longest 
        // palindromic subsequence
        return L[0][n - 1];
    }
  
    // function to calculate minimum
    // number of deletions
    static int minimumNumberOfDeletions(String str)
    {
        int n = str.length();
  
        // Find longest palindromic
        // subsequence
        int len = lps(str);
  
        // After removing characters
        // other than the lps, we get
        // palindrome.

1980
Chapter 272. Minimum number of deletions to make a string palindrome

        return (n - len);
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        String str = "geeksforgeeks";
        System.out.println("Minimum number " + 
                            "of deletions = "+ 
               minimumNumberOfDeletions(str));
    }
}
  
// This code is contributed by Sumit Ghosh

C#

// C# implementation to find 
// minimum number of deletions
// to make a string palindromic
using System;
  
class GFG
{
    // Returns the length of 
    // the longest palindromic
    // subsequence in 'str'
    static int lps(String str)
    {
        int n = str.Length;
  
        // Create a table to store
        // results of subproblems
        int [,]L = new int[n, n];
  
        // Strings of length 1
        // are palindrome of length 1
        for (int i = 0; i < n; i++)
            L[i, i] = 1;
  
        // Build the table. Note 
        // that the lower diagonal 
        // values of table are useless 
        // and not filled in the process.
        // c1 is length of substring
        for (int cl = 2; cl <= n; cl++)
        {
            for (int i = 0; i < n - cl + 1; i++)

1981
Chapter 272. Minimum number of deletions to make a string palindrome

            {
                int j = i + cl - 1;
                if (str[i] == str[j] && cl == 2)
                    L[i, j] = 2;
                else if (str[i] == str[j])
                    L[i, j] = L[i + 1, j - 1] + 2;
                else
                    L[i, j] = Math.Max(L[i, j - 1], 
                                      L[i + 1, j]);
            }
        }
  
        // length of longest 
        // palindromic subsequence
        return L[0, n - 1];
    }
  
    // function to calculate minimum
    // number of deletions
    static int minimumNumberOfDeletions(string str)
    {
        int n = str.Length;
  
        // Find longest palindromic
        // subsequence
        int len = lps(str);
  
        // After removing characters 
        // other than the lps, we get
        // palindrome.
        return (n - len);
    }
  
    // Driver Code
    public static void Main()
    {
        string str = "geeksforgeeks";
        Console.Write("Minimum number of" +
                          " deletions = " + 
            minimumNumberOfDeletions(str));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php

1982
Chapter 272. Minimum number of deletions to make a string palindrome

// PHP implementation to find 


// minimum number of deletions
// to make a string palindromic
  
// Returns the length of
// the longest palindromic
// subsequence in 'str'
function lps($str)
{
    $n = strlen($str);
  
    // Create a table to store
    // results of subproblems
    $L;
  
    // Strings of length 1
    // are palindrome of length 1
    for ($i = 0; $i < $n; $i++)
        $L[$i][$i] = 1;
  
    // Build the table. Note that
    // the lower diagonal values 
    // of table are useless and 
    // not filled in the process.
    // c1 is length of substring
    for ($cl = 2; $cl <= $n; $cl++)
    {
        for ( $i = 0;
              $i < $n -$cl + 1; 
              $i++)
        {
            $j = $i + $cl - 1;
            if ($str[$i] == $str[$j] && 
                            $cl == 2)
                $L[$i][$j] = 2;
            else if ($str[$i] == $str[$j])
                $L[$i][$j] = 
                        $L[$i + 1][$j - 1] + 2;
              
            else
                $L[$i][$j] = max($L[$i][$j - 1], 
                                $L[$i + 1][$j]);
        }
    }
  
    // length of longest 
    // palindromic subseq
    return $L[0][$n - 1];

1983
Chapter 272. Minimum number of deletions to make a string palindrome

}
  
// function to calculate minimum
// number of deletions
function minimumNumberOfDeletions($str)
{
    $n = strlen($str);
  
    // Find longest 
    // palindromic subsequence
    $len = lps($str);
  
    // After removing characters 
    // other than the lps, we get
    // palindrome.
    return ($n - $len);
}
  
// Driver Code
{
    $str = "geeksforgeeks";
    echo "Minimum number of deletions = ", 
           minimumNumberOfDeletions($str);
    return 0;
}
  
// This code is contributed by nitin mittal.
?>

Output :

Minimum number of deletions = 8

Time Complexity : O(n2 )


Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/minimum-number-deletions-make-string-palindrome/

1984
Chapter 273

Minimum number of deletions


to make a string palindrome |
Set 2

Minimum number of deletions to make a string palindrome | Set 2 - GeeksforGeeks


Given a string A, compute the minimum number of characters you need to delete to make
resulting string a palindrome.
Examples:

Input : baca
Output : 1

Input : geek
Output : 2

We have discussed one approach in below post.


Minimum number of deletions to make a string palindrome
Below approach will use modified Levenshtein distance. We consider modified Levensthein
(considering only deletions) both original string and its reverse.

// CPP program to find minimum deletions to make


// palindrome.
#include <bits/stdc++.h>
using namespace std;
  
int getLevenstein(string const& input)
{
    // Find reverse of input string

1985
Chapter 273. Minimum number of deletions to make a string palindrome | Set 2

    string revInput(input.rbegin(), input.rend());


  
    // Create a DP table for storing edit distance
    // of string and reverse.
    int n = input.size();
    vector<vector<int> > dp(n + 1, vector<int>(n + 1, -1));
    for (int i = 0; i <= n; ++i) {
        dp[0][i] = i;
        dp[i][0] = i;
    }
  
    // Find edit distance between input and revInput 
    // considering only delete operation.
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            if (input[i - 1] == revInput[j - 1]) 
                dp[i][j] = dp[i - 1][j - 1];            
            else 
                dp[i][j] = 1 + min({ dp[i - 1][j], dp[i][j - 1] });            
        }
    }
  
    /*Go from bottom left to top right and find the minimum*/
    int res = numeric_limits<int>::max();
    for (int i = n, j = 0; i >= 0; --i, ++j) {
        res = min(res, dp[i][j]);
        if (i < n) 
            res = min(res, dp[i + 1][j]);        
        if (i > 0) 
            res = min(res, dp[i - 1][j]);        
    }
    return res;
}
  
// Driver code
int main()
{
    string input("myfirstgeekarticle");
    cout << getLevenstein(input);
    return 0;
}

Output:

12

Time complexity: O( )

1986
Chapter 273. Minimum number of deletions to make a string palindrome | Set 2

Space complexity: O( )
where is length of string
Why is it working?
To understand it we need to start from the very beginning of how we create dp[][], for
example for word “geek”, it initially looks like this:

Both 1st row and 1st column are filled with number 1..4 as this is the number of modifications
needed to create empty string, i.e:
[0][1] == 1, to create empty string from letter ‘g’ remove this one letter
[0][2] == 2, to create empty string from letters “ge”, remove both those letters, etc.
The same story for first column:
[1][0] == 1, to create empty string from letter ‘k’ remove this one letter
[2][0] == 2, to create empty string from letters “ke”, remove both those letters, etc.
Now, we are using dynamic programming approach to get the minimum number of modifi-
cations to get every other substring to become second substring, and at the end out dp[][]
looks like this:

So for example minimum number of modifications to get substring ‘gee’ from ‘kee’ is 2. So
far so good but this algorithm is doing two things, it is both inserting and deleting characters,
and we are only interested in number of removals. So let’s one more time take a look at our
resulting array, for example at entry [4][1], this entry states:
[4][1] – to make string ‘g’ from string “keeg” we need to perform 3 modifications(which is
just delete chars “kee”)

1987
Chapter 273. Minimum number of deletions to make a string palindrome | Set 2

[3][2] – to make string “ge” from “kee” we need to perform 3 modifications also by removing
from first string ‘g’ and from second ‘ke’
So basically every time we will be moving diagonally up, from left corner we will get number
of removals to get the same substring backwards. Thing to notice here is that it is like having
on string two pointers, one moving from beginning and other from end. Very important spot
is that strings do not necessary has to have even number of characters, so this is the reason
we also has to check upper and lower values in dp[][].

Source

https://www.geeksforgeeks.org/minimum-number-deletions-make-string-palindrome-set-2/

1988
Chapter 274

Minimum number of elements


which are not part of Increasing
or decreasing subsequence in
array

Minimum number of elements which are not part of Increasing or decreasing subsequence
in array - GeeksforGeeks
Given an array of n elements. Make strictly increasing and strictly decreasing subsequences
from the array such that each array element belongs to increasing subsequence or decreasing
subsequence, but not both, or can be part of none of the subsequence. Minimize the number
of elements which are not part of any of the subsequences and find the count of such elements.
Examples:

Input : arr[] = { 7, 8, 1, 2, 4, 6, 3, 5, 2, 1, 8, 7 }
Output : 2
Increasing sequence can be { 1, 2, 4, 5, 8 }.
Decreasing sequence can be { 7, 6, 3, 2, 1 }.
So, only 2 (8, 7) element is left which are not part of
either of the subsequences.

Input : arr[] = { 1, 4, 2, 3, 3, 2, 4, 1 }
Output : 0
Increasing sequence can be { 1, 2, 3, 4 }.
Decreasing sequence can be { 4, 3, 2, 1 }.
So, no element is left which is not part of either of
the subsequences.

1989
Chapter 274. Minimum number of elements which are not part of Increasing or decreasing
subsequence in array

The idea is to make a decision on each index, starting from index 0, one by one. For each
index there can be three possibilities, first, it can belong to increasing sequence, second, it
can belong to decreasing sequence, third, it does not belong to any of these sequences.
So, for each index, check for the optimal answer (minimum element which is not part of any
of the subsequences) by considering it once as a part of increasing subsequence or as a part
of decreasing subsequence. If the optimal answer cannot be achieved by them then leave it
as the element which is not part of any of the sequence.
To decrease the complexity (using Dynamic Programming), we can store the number of
elements which are not part of any of the subsequences using 3D array dp[x][y][z], where x
indicates the decision index, y indicates the last index of decreasing sequence, z indicates
the last index of increasing sequence.
Below is C++ implementation of this approach:

// C++ program to return minimum number of elements which


// are not part of increasing or decreasing subsequences.
#include<bits/stdc++.h>
#define MAX 102
using namespace std;
  
// Return minimum number of elements which is not part of
// any of the sequence.
int countMin(int arr[], int dp[MAX][MAX][MAX], int n, int dec,
                                            int inc, int i)
{
    // If already calculated, return value.
    if (dp[dec][inc][i] != -1)
        return dp[dec][inc][i];
  
    // If whole array is traversed.
    if (i == n)
        return 0;
  
    // calculating by considering element as part of
    // decreasing sequence.
    if (arr[i] < arr[dec])
        dp[dec][inc][i] = countMin(arr, dp, n, i, inc, i + 1);
  
    // calculating by considering element as part of
    // increasing sequence.
    if (arr[i] > arr[inc])
    {
        // If cannot be calculated for decreasing sequence.
        if (dp[dec][inc][i] == -1)
            dp[dec][inc][i] = countMin(arr, dp, n, dec, i, i + 1);
  
        // After considering once by decreasing sequence, now try
        // for increasing sequence.

1990
Chapter 274. Minimum number of elements which are not part of Increasing or decreasing
subsequence in array

        else
            dp[dec][inc][i] = min(countMin(arr, dp, n, dec, i, i + 1),
                                                  dp[dec][inc][i]);
    }
  
    // If element cannot be part of any of the sequence.
    if (dp[dec][inc][i] == -1)
        dp[dec][inc][i] = 1 + countMin(arr, dp, n, dec, inc, i + 1);
  
    // After considering element as part of increasing and
    // decreasing sequence trying as not part of any of the
    // sequence.
    else
        dp[dec][inc][i] = min(1 + countMin(arr, dp, n, dec, inc, i + 1),
                                                    dp[dec][inc][i]);
  
    return dp[dec][inc][i];
}
  
// Wrapper Function
int wrapper(int arr[], int n)
{
    // Adding two number at the end of array, so that
    // increasing and decreasing sequence can be made.
    // MAX - 2 index is assigned INT_MAX for decreasing sequence
    // because/ next number of sequence must be less than it.
    // Similarly, for Increasing sequence INT_MIN is assigned to
    // MAX - 1 index.
    arr[MAX - 2] = INT_MAX;
    arr[MAX - 1] = INT_MIN;
  
    int dp[MAX][MAX][MAX];
    memset(dp, -1, sizeof dp);
  
    return countMin(arr, dp, n, MAX - 2, MAX - 1, 0);
}
  
// Driven Program
int main()
{
    int n = 12;
    int arr[MAX] = { 7, 8, 1, 2, 4, 6, 3, 5, 2, 1, 8, 7 };
  
    cout << wrapper(arr, n) << endl;
    return 0;
}

Output:

1991
Chapter 274. Minimum number of elements which are not part of Increasing or decreasing
subsequence in array

Time Complexity : O(n3 )

Source

https://www.geeksforgeeks.org/minimum-number-of-elements-which-are-not-part-of-increasing-or-decreasing-subse

1992
Chapter 275

Minimum number of jumps to


reach end

Minimum number of jumps to reach end - GeeksforGeeks


Given an array of integers where each element represents the max number of steps that can
be made forward from that element. Write a function to return the minimum number of
jumps to reach the end of the array (starting from the first element). If an element is 0,
then cannot move through that element.
Example:

Input: arr[] = {1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9}


Output: 3 (1-> 3 -> 8 ->9)

First element is 1, so can only go to 3. Second element is 3, so can make at most 3 steps eg
to 5 or 8 or 9.
Method 1 (Naive Recursive Approach)
A naive approach is to start from the first element and recursively call for all the elements
reachable from first element. The minimum number of jumps to reach end from first can be
calculated using minimum number of jumps needed to reach end from the elements reachable
from first.
minJumps(start, end) = Min ( minJumps(k, end) ) for all k reachable from start
C

#include <stdio.h>
#include <limits.h>
  
// Returns minimum number of jumps to reach arr[h] from arr[l]
int minJumps(int arr[], int l, int h)

1993
Chapter 275. Minimum number of jumps to reach end

{
   // Base case: when source and destination are same
   if (h == l)
     return 0;
  
   // When nothing is reachable from the given source
   if (arr[l] == 0)
     return INT_MAX;
  
   // Traverse through all the points reachable from arr[l]. Recursively
   // get the minimum number of jumps needed to reach arr[h] from these
   // reachable points.
   int min = INT_MAX;
   for (int i = l+1; i <= h && i <= l + arr[l]; i++)
   {
       int jumps = minJumps(arr, i, h);
       if(jumps != INT_MAX && jumps + 1 < min)
           min = jumps + 1;
   }
  
   return min;
}
  
// Driver program to test above function
int main()
{
  int arr[] = {1, 3, 6, 3, 2, 3, 6, 8, 9, 5};
  int n = sizeof(arr)/sizeof(arr[0]);
  printf("Minimum number of jumps to reach end is %d ", minJumps(arr, 0, n-1));
  return 0;
}

Java

// Javaprogram to find Minimum 


// number of jumps to reach end
import java.util.*;
import java.io.*;
  
class GFG
{
    // Returns minimum number of 
    // jumps to reach arr[h] from arr[l]
   static int minJumps(int arr[], int l, int h)
   {
        // Base case: when source 
        // and destination are same
        if (h == l)

1994
Chapter 275. Minimum number of jumps to reach end

        return 0;
  
        // When nothing is reachable 
        // from the given source
        if (arr[l] == 0)
        return Integer.MAX_VALUE;
  
        // Traverse through all the points 
        // reachable from arr[l]. Recursively
        // get the minimum number of jumps 
        // needed to reach arr[h] from these
        // reachable points.
        int min = Integer.MAX_VALUE;
        for (int i = l+1; i <= h && i <= l + arr[l]; i++)
        {
            int jumps = minJumps(arr, i, h);
            if(jumps != Integer.MAX_VALUE &&
               jumps + 1 < min)
              min = jumps + 1;
              
        }
        return min;
         
   }
  
   // Driver code
   public static void main(String args[])
   {
        int arr[] = {1, 3, 6, 3, 2, 3, 6, 8, 9, 5}; 
        int n = arr.length;
        System.out.print("Minimum number of jumps to reach end is " 
                          + minJumps(arr, 0, n-1));
   }
}
  
// This code is contributed by Sahil_Bansall

Python3

# Python3 program to find Minimum 


# number of jumps to reach end
  
# Returns minimum number of jumps
# to reach arr[h] from arr[l]
def minJumps(arr, l, h):
  
    # Base case: when source and
    # destination are same

1995
Chapter 275. Minimum number of jumps to reach end

    if (h == l):
        return 0
  
    # when nothing is reachable 
    # from the given source
    if (arr[l] == 0):
        return float('inf')
  
    # Traverse through all the points 
    # reachable from arr[l]. Recursively 
    # get the minimum number of jumps 
    # needed to reach arr[h] from 
    # these reachable points.
    min = float('inf')
    for i in range(l + 1, h + 1):
        if (i < l + arr[l] + 1):
            jumps = minJumps(arr, i, h)
            if (jumps != float('inf') and 
                       jumps + 1 < min):
                min = jumps + 1
  
    return min
  
# Driver program to test above function
arr = [1, 3, 6, 3, 2, 3, 6, 8, 9, 5]
n = len(arr)
print('Minimum number of jumps to reach',
     'end is', minJumps(arr, 0, n-1))
  
# This code is contributed by Soumen Ghosh

C#

// C# program to find Minimum 


// number of jumps to reach end
using System;
  
class GFG
{
    // Returns minimum number of 
    // jumps to reach arr[h] from arr[l]
    static int minJumps(int []arr, int l, int h)
    {
            // Base case: when source 
            // and destination are same
            if (h == l)
            return 0;
      

1996
Chapter 275. Minimum number of jumps to reach end

            // When nothing is reachable 


            // from the given source
            if (arr[l] == 0)
            return int.MaxValue;
      
            // Traverse through all the points 
            // reachable from arr[l]. Recursively
            // get the minimum number of jumps 
            // needed to reach arr[h] from these
            // reachable points.
            int min = int.MaxValue;
            for (int i = l+1; i <= h && i <= l + arr[l]; i++)
            {
                int jumps = minJumps(arr, i, h);
                if(jumps != int.MaxValue &&
                jumps + 1 < min)
                min = jumps + 1;
                  
            }
            return min;
              
    }
      
    // Driver code
    public static void Main()
    {
        int []arr = {1, 3, 6, 3, 2, 3, 6, 8, 9, 5}; 
        int n = arr.Length;
        Console.Write("Minimum number of jumps to reach end is "
                      + minJumps(arr, 0, n-1));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// php program to find Minimum 
// number of jumps to reach end
  
// Returns minimum number of jumps 
// to reach arr[h] from arr[l]
function minJumps($arr, $l, $h)
{
      
    // Base case: when source and
    // destination are same

1997
Chapter 275. Minimum number of jumps to reach end

    if ($h == $l)


        return 0;
      
    // When nothing is reachable
    // from the given source
    if ($arr[$l] == 0)
        return INT_MAX;
      
    // Traverse through all the points 
    // reachable from arr[l]. Recursively
    // get the minimum number of jumps
    // needed to reach arr[h] from these
    // reachable points.
    $min = 999999;
      
    for ($i = $l+1; $i <= $h && 
             $i <= $l + $arr[$l]; $i++)
    {
        $jumps = minJumps($arr, $i, $h);
          
        if($jumps != 999999 && 
                     $jumps + 1 < $min)
            $min = $jumps + 1;
    }
      
    return $min;
}
  
// Driver program to test above function
$arr = array(1, 3, 6, 3, 2, 3, 6, 8, 9, 5);
$n = count($arr);
  
echo "Minimum number of jumps to reach "
     . "end is ". minJumps($arr, 0, $n-1);
      
// This code is contributed by Sam007
?>

Output:

Minimum number of jumps to reach end is 4

If we trace the execution of this method, we can see that there will be overlapping sub-
problems. For example, minJumps(3, 9) will be called two times as arr[3] is reachable from
arr[1] and arr[2]. So this problem has both properties (optimal substructure and overlapping
subproblems) of Dynamic Programming.
Method 2 (Dynamic Programming)
In this method, we build a jumps[] array from left to right such that jumps[i] indicates the

1998
Chapter 275. Minimum number of jumps to reach end

minimum number of jumps needed to reach arr[i] from arr[0]. Finally, we return jumps[n-1].

C / C++

#include <stdio.h>
#include <limits.h>
  
int min(int x, int y) { return (x < y)? x: y; }
  
// Returns minimum number of jumps to reach arr[n-1] from arr[0]
int minJumps(int arr[], int n)
{
    int *jumps = new int[n];  // jumps[n-1] will hold the result
    int i, j;
  
    if (n == 0 || arr[0] == 0)
        return INT_MAX;
  
    jumps[0] = 0;
  
    // Find the minimum number of jumps to reach arr[i]
    // from arr[0], and assign this value to jumps[i]
    for (i = 1; i < n; i++)
    {
        jumps[i] = INT_MAX;
        for (j = 0; j < i; j++)
        {
            if (i <= j + arr[j] && jumps[j] != INT_MAX)
            {
                 jumps[i] = min(jumps[i], jumps[j] + 1);
                 break;
            }
        }
    }
    return jumps[n-1];
}
  
// Driver program to test above function
int main()
{
    int arr[] = {1, 3, 6, 1, 0, 9};
    int size = sizeof(arr)/sizeof(int);
    printf("Minimum number of jumps to reach end is %d ", minJumps(arr,size));
    return 0;
}

Java

1999
Chapter 275. Minimum number of jumps to reach end

// JAVA Code for Minimum number of jumps to reach end


class GFG{
       
private static int minJumps(int[] arr, int n) { 
    int jumps[] = new int[n];  // jumps[n-1] will hold the 
                               // result
    int i, j;
           
    if (n == 0 || arr[0] == 0)
         return Integer.MAX_VALUE;  // if first element is 0,
                                   // end cannot be reached
           
    jumps[0] = 0;
           
    // Find the minimum number of jumps to reach arr[i]
    // from arr[0], and assign this value to jumps[i]
    for (i = 1; i < n; i++)
    {
        jumps[i] = Integer.MAX_VALUE;
         for (j = 0; j < i; j++)
         {
              if (i <= j + arr[j] && jumps[j] != Integer.MAX_VALUE)
              {
                  jumps[i] = Math.min(jumps[i], jumps[j] + 1);
                  break;
              }
          }
    }
        return jumps[n-1];
    }
      
// driver program to test above function
public static void main(String[] args) {
    int arr[] = {1, 3, 6, 1, 0, 9};
                 
    System.out.println("Minimum number of jumps to reach end is : "+
                                  minJumps(arr,arr.length));
    }
}
          
// This code is contributed by Arnav Kr. Mandal.

Python3

# Python3 program to find Minimum 


# number of jumps to reach end
  
# Returns minimum number of jumps

2000
Chapter 275. Minimum number of jumps to reach end

# to reach arr[n-1] from arr[0]


def minJumps(arr, n):
    jumps = [0 for i in range(n)]
  
    if (n == 0) or (arr[0] == 0):
        return float('inf')
  
    jumps[0] = 0
  
    # Find the minimum number of 
    # jumps to reach arr[i] from 
    # arr[0] and assign this 
    # value to jumps[i]
    for i in range(1, n):
        jumps[i] = float('inf')
        for j in range(i):
            if (i <= j + arr[j]) and (jumps[j] != float('inf')):
                jumps[i] = min(jumps[i], jumps[j] + 1)
                break
    return jumps[n-1]
  
# Driver Program to test above function
arr = [1, 3, 6, 1, 0, 9]
size = len(arr)
print('Minimum number of jumps to reach',
      'end is', minJumps(arr,size))
  
# This code is contributed by Soumen Ghosh

C#

// C# Code for Minimum number of jumps to reach end


using System;
  
class GFG
{
    static int minJumps(int[] arr, int n) 
    { 
        // jumps[n-1] will hold the 
        // result
        int []jumps = new int[n]; 
          
        // if first element is 0,
        if (n == 0 || arr[0] == 0) 
          
        // end cannot be reached
        return int.MaxValue; 
          

2001
Chapter 275. Minimum number of jumps to reach end

              
        jumps[0] = 0;
              
        // Find the minimum number of 
        // jumps to reach arr[i]
        // from arr[0], and assign 
        // this value to jumps[i]
        for (int i = 1; i < n; i++)
        {
            jumps[i] = int.MaxValue; 
            for (int j = 0; j < i; j++)
            {
                if (i <= j + arr[j] && jumps[j] != int.MaxValue )
                {
                    jumps[i] = Math.Min(jumps[i], jumps[j] + 1);
                    break;
                }
            }
        }
            return jumps[n - 1];
    }
      
    // Driver program 
    public static void Main()
    {
        int []arr = {1, 3, 6, 1, 0, 9};
        Console.Write("Minimum number of jumps to reach end is : "+
                                        minJumps(arr,arr.Length));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP code for Minimum number of
// jumps to reach end
  
// Returns minimum number of jumps
// to reach arr[n-1] from arr[0]
function minJumps($arr, $n)
{
    // jumps[n-1] will
    // hold the result
    $jumps = array($n);
      
    if ($n == 0 || $arr[0] == 0)

2002
Chapter 275. Minimum number of jumps to reach end

        return 999999;
  
    $jumps[0] = 0;
  
    // Find the minimum number of
    // jumps to reach arr[i]
    // from arr[0], and assign 
    // this value to jumps[i]
    for ($i = 1; $i < $n; $i++)
    {
        $jumps[$i] = 999999;
        for ($j = 0; $j < $i; $j++)
        {
            if ($i <= $j + $arr[$j] && 
                $jumps[$j] != 999999)
            {
                $jumps[$i] = min($jumps[$i], 
                             $jumps[$j] + 1);
                break;
            }
        }
    }
    return $jumps[$n-1];
}
  
    // Driver Code
    $arr = array(1, 3, 6, 1, 0, 9);
    $size = count($arr);
    echo "Minimum number of jumps to reach end is ". 
                             minJumps($arr, $size);
                               
// This code is contributed by Sam007
?>

Output:

Minimum number of jumps to reach end is 3

Thanks to paras for suggesting this method.


Time Complexity: O(n^2)
Method 3 (Dynamic Programming)
In this method, we build jumps[] array from right to left such that jumps[i] indicates
the minimum number of jumps needed to reach arr[n-1] from arr[i]. Finally, we return arr[0].

C++

2003
Chapter 275. Minimum number of jumps to reach end

// CPP program to find Minimum 


// number of jumps to reach end
#include<bits/stdc++.h>
using namespace std;
  
// Returns Minimum number of
// jumps to reach end
int minJumps(int arr[], int n)
{   
    // jumps[0] will hold the result
    int *jumps = new int[n]; 
    int min;
  
    // Minimum number of jumps needed 
    // to reach last element from last
    // elements itself is always 0
    jumps[n-1] = 0;
  
  
    // Start from the second element, 
    // move from right to left and 
    // construct the jumps[] array where
    // jumps[i] represents minimum number
    // of jumps needed to reach 
    // arr[m-1] from arr[i]
    for (int i = n-2; i >=0; i--)
    {
        // If arr[i] is 0 then arr[n-1] 
        // can't be reached from here
        if (arr[i] == 0)
            jumps[i] = INT_MAX;
  
        // If we can direcly reach to 
        // the end point from here then
        // jumps[i] is 1
        else if (arr[i] >= n - i - 1)
            jumps[i] = 1;
  
        // Otherwise, to find out the minimum
        // number of jumps needed to reach 
        // arr[n-1], check all the points 
        // reachable from here and jumps[] 
        // value for those points
        else
        {   
            // initialize min value
            min = INT_MAX; 
  

2004
Chapter 275. Minimum number of jumps to reach end

            // following loop checks with all


            // reachable points and takes 
            // the minimum
            for (int j = i + 1; j < n && j <= 
                             arr[i] + i; j++)
            {
                if (min > jumps[j])
                    min = jumps[j];
            }     
  
            // Handle overflow 
            if (min != INT_MAX)
            jumps[i] = min + 1;
            else
            jumps[i] = min; // or INT_MAX
        }
    }
  
    return jumps[0];
}
  
// Driver program to test above function
int main()
{
    int arr[] = {1, 3, 6, 1, 0, 9};
    int size = sizeof(arr)/sizeof(int);
    cout << "Minimum number of jumps to reach" 
         << " end is " << minJumps(arr, size);
    return 0;
}

Python3

# Python3 progrma to find Minimum 


# number of jumps to reach end
  
# Returns Minimum number of
# jumps to reach end
def minJumps(arr, n):
      
    # jumps[0] will hold the result
    jumps = [0 for i in range(n)] 
  
    # Minimum number of jumps needed
    # to reach last element from 
    # last elements itself is always 0
    # jumps[n-1] is also initialized to 0
  

2005
Chapter 275. Minimum number of jumps to reach end

    # Start from the second element, 


    # move from right to left and 
    # construct the jumps[] array where
    # jumps[i] represents minimum number
    # of jumps needed to reach arr[m-1]
    # form arr[i]
    for i in range(n-2, -1, -1):
          
        # If arr[i] is 0 then arr[n-1]
        # can't be reached from here
        if (arr[i] == 0):
            jumps[i] = float('inf')
  
        # If we can directly reach to 
        # the end point from here then
        # jumps[i] is 1
        elif (arr[i] >= n - i - 1):
            jumps[i] = 1
  
        # Otherwise, to find out the 
        # minimum number of jumps
        # needed to reach arr[n-1], 
        # check all the points
        # reachable from here and 
        # jumps[] value for those points
        else:
            # initialize min value
            min = float('inf') 
  
            # following loop checks with 
            # all reachavle points and
            # takes the minimum
            for j in range(i + 1, n):
                if (j <= arr[i] + i):
                    if (min > jumps[j]):
                        min = jumps[j]
                          
            # Handle overflow
            if (min != float('inf')):
                jumps[i] = min + 1
            else:
                # or INT_MAX
                jumps[i] = min 
  
    return jumps[0]
  
# Driver program to test above function
arr = [1, 3, 6, 3, 2, 3, 6, 8, 9, 5]

2006
Chapter 275. Minimum number of jumps to reach end

n = len(arr)
print('Minimum number of jumps to reach',
      'end is', minJumps(arr, n-1))
        
# This code is contributed by Soumen Ghosh

Java

// Java program to find Minimum 


// number of jumps to reach end
class GFG
{
// Returns Minimum number 
// of jumps to reach end
static int minJumps(int arr[], 
                    int n)

    // jumps[0] will
    // hold the result
    int[] jumps = new int[n]; 
    int min;
  
    // Minimum number of jumps 
    // needed to reach last 
    // element from last elements 
    // itself is always 0
    jumps[n - 1] = 0;
  
  
    // Start from the second 
    // element, move from right
    // to left and construct the 
    // jumps[] array where jumps[i] 
    // represents minimum number of
    // jumps needed to reach arr[m-1]
    // from arr[i]
    for (int i = n - 2; i >= 0; i--)
    {
        // If arr[i] is 0 then arr[n-1] 
        // can't be reached from here
        if (arr[i] == 0)
            jumps[i] = Integer.MAX_VALUE;
  
        // If we can direcly reach to 
        // the end point from here then
        // jumps[i] is 1
        else if (arr[i] >= n - i - 1)
            jumps[i] = 1;

2007
Chapter 275. Minimum number of jumps to reach end

  
        // Otherwise, to find out 
        // the minimum number of 
        // jumps needed to reach 
        // arr[n-1], check all the 
        // points reachable from 
        // here and jumps[] value 
        // for those points
        else
        { 
            // initialize min value
            min = Integer.MAX_VALUE; 
  
            // following loop checks 
            // with all reachable points 
            // and takes the minimum
            for (int j = i + 1; j < n && 
                     j <= arr[i] + i; j++)
            {
                if (min > jumps[j])
                    min = jumps[j];
            } 
  
            // Handle overflow 
            if (min != Integer.MAX_VALUE)
                jumps[i] = min + 1;
            else
                jumps[i] = min; // or Integer.MAX_VALUE
        }
    }
  
    return jumps[0];
}
  
// Driver Code
public static void main(String[] args)
{
    int[] arr = {1, 3, 6, 1, 0, 9};
    int size = arr.length;
    System.out.println("Minimum number of" + 
                       " jumps to reach end is " +
                             minJumps(arr, size));
  
}
}
  
// This code is contributed by mits.

2008
Chapter 275. Minimum number of jumps to reach end

Output:

Minimum number of jumps to reach end is 3

Time Complexity: O(n^2) in worst case.


Minimum number of jumps to reach end | Set 2 (O(n) solution)
Thanks to Ashish for suggesting this solution.
Improved By : Sam007, Mithun Kumar

Source

https://www.geeksforgeeks.org/minimum-number-of-jumps-to-reach-end-of-a-given-array/

2009
Chapter 276

Minimum number of jumps to


reach end | Set 2 (O(n) solution)

Minimum number of jumps to reach end | Set 2 (O(n) solution) - GeeksforGeeks


Given an array of integers where each element represents the max number of steps that can
be made forward from that element. Write a function to return the minimum number of
jumps to reach the end of the array (starting from the first element). If an element is 0,
then we cannot move through that element.
Examples:

Input : arr[] = {1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9}


Output : 3 (1-> 3 -> 8 -> 9)

In this post, its O(n) solution will be discussed.


In Set -1, O(n2 ) solution is discussed.
Implementation:
Variables to be used:

1. maxReach The variable maxReach stores at all time the maximal reachable index in
the array.
2. step The variable step stores the number of steps we can still take(and is initialized
with value at index 0,i.e. initial number of steps)
3. jump jump stores the amount of jumps necessary to reach that maximal reachable
position.

Given array arr = 1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9

2010
Chapter 276. Minimum number of jumps to reach end | Set 2 (O(n) solution)

• maxReach = arr[0]; // arr[0] = 1, so the maximum index we can reach at the moment
is 1.
step = arr[0]; // arr[0] = 1, the amount of steps we can still take is also 1.
jump = 1; // we will always need to take at least one jump.
• Now, starting iteration from index 1, the above values are updated as follows:
1. First we test whether we have reached the end of the array, in that case we just
need to return the jump variable.
if (i == arr.length - 1)
return jump;
2. Next we update the maxReach. This is equal to the maximum of maxReach and
i+arr[i](the number of steps we can take from the current position).

maxReach = Math.max(maxReach,i+arr[i]);
3. We used up a step to get to the current index, so steps has to be decreased.

step--;
4. If no more steps are remaining (i.e. steps=0, then we must have used a jump.
Therefore increase jump. Since we know that it is possible somehow to reach
maxReach, we again initialize the steps to the number of steps to reach maxReach
from position i. But before re-initializing step, we also check whether a step is
becoming zero or negative. In this case, It is not possible to reach further.

if (step == 0) {
jump++;
if(i>=maxReach)
return -1;
step = maxReach - i;
}

// C program to count Minimum number


// of jumps to reach end
#include <stdio.h>
  
int max(int x, int y) { return (x > y)? x: y; }
  
// Returns minimum number of jumps to reach arr[n-1] from arr[0]
int minJumps(int arr[], int n)
{
      
    // The number of jumps needed to reach the starting index is 0
    if (n <= 1)

2011
Chapter 276. Minimum number of jumps to reach end | Set 2 (O(n) solution)

        return 0;
  
    // Return -1 if not possible to jump
    if (arr[0] == 0)
        return -1;
  
    // initialization
    int maxReach = arr[0];  // stores all time the maximal reachable index in the array.
    int step = arr[0];      // stores the number of steps we can still take
    int jump =1;//stores the number of jumps necessary to reach that maximal reachable position.
  
    // Start traversing array
    int i=1;
    for (i = 1; i < n; i++)
    {
        // Check if we have reached the end of the array
        if (i == n-1)
            return jump;
  
        // updating maxReach
        maxReach = max(maxReach, i+arr[i]);
  
        // we use a step to get to the current index
        step--;
  
        // If no further steps left
        if (step == 0)
        {
            // we must have used a jump
            jump++;
  
            // Check if the current index/position or lesser index
            // is the maximum reach point from the previous indexes
            if(i >= maxReach)
                return -1;
  
            // re-initialize the steps to the amount
            // of steps to reach maxReach from position i.
            step = maxReach - i;
        }
    }
  
    return -1;
}
  
// Driver program to test above function
int main()
{

2012
Chapter 276. Minimum number of jumps to reach end | Set 2 (O(n) solution)

    int arr[]={1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9};


    int size = sizeof(arr)/sizeof(int);
  
    // Calling the minJumps function
    printf("Minimum number of jumps to reach end is %d ", minJumps(arr,size));
    return 0;
}
// This code is contributed by Abhishek Kumar Singh

Java

// Java program to count Minimum number


// of jumps to reach end
  
class Test
{
    static int minJumps(int arr[])
    {
        if (arr.length <= 1)
            return 0;
  
        // Return -1 if not possible to jump
        if (arr[0] == 0)
            return -1;
  
        // initialization
        int maxReach = arr[0];
        int step = arr[0];
        int jump = 1;
  
  
        // Start traversing array
        for (int i = 1; i < arr.length; i++)
        {
            // Check if we have reached the end of the array
            if (i == arr.length - 1)
                return jump;
  
            // updating maxReach
            maxReach = Math.max(maxReach, i+arr[i]);
  
            // we use a step to get to the current index
            step--;
  
            // If no further steps left
            if (step == 0)
            {
                //  we must have used a jump

2013
Chapter 276. Minimum number of jumps to reach end | Set 2 (O(n) solution)

                jump++;
                   
                //Check if the current index/position  or lesser index
                // is the maximum reach point from the previous indexes
                if(i>=maxReach)
                   return -1;
  
                // re-initialize the steps to the amount
                // of steps to reach maxReach from position i.
                step = maxReach - i;
            }
        }
  
        return -1;
    }
  
    // Driver method to test the above function
    public static void main(String[] args)
    {
        int arr[] = new int[] {1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9};
  
        // calling minJumps method
        System.out.println(minJumps(arr));
    }
}

Python

# python program to count Minimum number


# of jumps to reach end
   
# Returns minimum number of jumps to reach arr[n-1] from arr[0]
def minJumps(arr, n):
  # The number of jumps needed to reach the starting index is 0
  if (n <= 1):
    return 0
   
  # Return -1 if not possible to jump
  if (arr[0] == 0):
    return -1
   
  # initialization
  # stores all time the maximal reachable index in the array
  maxReach = arr[0]  
  # stores the amount of steps we can still take
  step = arr[0]
  # stores the amount of jumps necessary to reach that maximal reachable position
  jump =1 

2014
Chapter 276. Minimum number of jumps to reach end | Set 2 (O(n) solution)

   
  # Start traversing array
   
  for i in range(1,n):
    # Check if we have reached the end of the array
    if (i == n-1):
      return jump
   
    # updating maxReach
    maxReach = max(maxReach, i+arr[i])
   
    # we use a step to get to the current index
    step -= 1;
   
    # If no further steps left
    if (step == 0):
      # we must have used a jump
      jump += 1
        
      # Check if the current index/position or lesser index
      # is the maximum reach point from the previous indexes
      if(i >= maxReach):
        return -1
   
      # re-initialize the steps to the amount
      # of steps to reach maxReach from position i.
      step = maxReach - i;
  return -1
   
  
# Driver program to test above function
arr = [1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9]
size = len(arr)
   
# Calling the minJumps function
print("Minimum number of jumps to reach end is %d " %minJumps(arr,size))
  
  
# This code is contributed by Aditi Sharma

C#

// C# program to count Minimum 


// number of jumps to reach end
using System; 
  
class GFG
{

2015
Chapter 276. Minimum number of jumps to reach end | Set 2 (O(n) solution)

    static int minJumps(int []arr)


    {
        if (arr.Length <= 1)
            return 0;
  
        // Return -1 if not 
        // possible to jump
        if (arr[0] == 0)
            return -1;
  
        // initialization
        int maxReach = arr[0];
        int step = arr[0];
        int jump = 1;
  
  
        // Start traversing array
        for (int i = 1; i < arr.Length; i++)
        {
            // Check if we have reached 
            // the end of the array
            if (i == arr.Length - 1)
                return jump;
  
            // updating maxReach
            maxReach = Math.Max(maxReach, i + arr[i]);
  
            // we use a step to get
            // to the current index
            step--;
  
            // If no further steps left
            if (step == 0)
            {
                // we must have used a jump
                jump++;
                  
                // Check if the current index/position 
                // or lesser index is the maximum reach
                // point from the previous indexes
                if(i >= maxReach)
                return -1;
  
                // re-initialize the steps to
                // the amount of steps to reach 
                // maxReach from position i.
                step = maxReach - i;
            }

2016
Chapter 276. Minimum number of jumps to reach end | Set 2 (O(n) solution)

        }
  
        return -1;
    }
  
    // Driver Code
    public static void Main()
    {
        int []arr = new int[] {1, 3, 5, 8, 9, 2,
                               6, 7, 6, 8, 9};
  
        // calling minJumps method
        Console.Write(minJumps(arr));
    }
}
  
// This code is contributed 
// by nitin mittal

Output:

References :- Stackoverflow
Thanks to Chiranjeev Jain for suggesting this solution.
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/minimum-number-jumps-reach-endset-2on-solution/

2017
Chapter 277

Minimum number of single digit


primes required whose sum is
equal to N

Minimum number of single digit primes required whose sum is equal to N - GeeksforGeeks
Find the minimum number of single-digit prime numbers required whose sum will be equal
to N.
Examples:

Input: 11
Output: 3
Explanation: 5 + 3 + 3.
Another possibility is 3 + 3 + 3 + 2, but it is not
the minimal

Input: 12
Output: 2
Explanation: 7 + 5

Approach: Dynamic Programming can be used to solve the above problem. The observa-
tions are:

• There are only 4 single digit primes {2, 3, 5, 7}.


• If it is possible to make N from summing up single digit primes, then at least one of
N-2, N-3, N-5 or N-7, is also reachable.
• The minimum number of single-digit prime numbers needed will be one more than the
minimum number of prime digits needed to make one of {N-2, N-3, N-5, N-7}.

Using these observations, built a recurrence to solve this problem. The recurrence will be:

2018
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

dp[i] = 1 + min(dp[i-2], dp[i-3], dp[i-5], dp[i-7])

For {2, 3, 5, 7}, the answer would be 1. For each other number, using Observation 3, try
to find the minimum value possible, if possible.
Below is the implementation of the above approach.

C++

// CPP program to find the minimum number of single


// digit prime numbers required which when summed
// equals to a given number N.
#include <bits/stdc++.h>
using namespace std;
  
// fuction to check if i-th
// index is valid or not
bool check(int i, int val)
{
    if (i - val < 0)
        return false;
    return true;
}
  
// function to find the minimum number of single
// digit prime numbers required which when summed up
// equals to a given number N.
int MinimumPrimes(int n)
{
    int dp[n + 1];
  
    for (int i = 1; i <= n; i++)
        dp[i] = 1e9;
  
    dp[0] = dp[2] = dp[3] = dp[5] = dp[7] = 1;
    for (int i = 1; i <= n; i++) {
  
        if (check(i, 2))
            dp[i] = min(dp[i], 1 + dp[i - 2]);
  
        if (check(i, 3))
            dp[i] = min(dp[i], 1 + dp[i - 3]);
  
        if (check(i, 5))
            dp[i] = min(dp[i], 1 + dp[i - 5]);
  
        if (check(i, 7))
            dp[i] = min(dp[i], 1 + dp[i - 7]);

2019
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

    }
  
    // Not possible
    if (dp[n] == (1e9))
        return -1;
    else
        return dp[n];
}
  
// Driver Code
int main()
{
  
    int n = 12;
  
    int minimal = MinimumPrimes(n);
    if (minimal != -1)
        cout << "Minimum number of single"
             << " digit primes required : "
             << minimal << endl;
  
    else
        cout << "Not possible";
  
    return 0;
}

Java

// Java program to find the minimum number


// of single digit prime numbers required 
// which when summed equals to a given 
// number N.
  
class Geeks {
      
// fuction to check if i-th
// index is valid or not
static boolean check(int i, int val)
{
    if (i - val < 0)
        return false;
    else
        return true;
}
  
// function to find the minimum number
// of single digit prime numbers required

2020
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

// which when summed up equals to a given


// number N.
static double MinimumPrimes(int n)
{
    double[] dp;
    dp = new double[n+1];
  
    for (int i = 1; i <= n; i++)
        dp[i] = 1e9;
  
    dp[0] = dp[2] = dp[3] = dp[5] = dp[7] = 1;
    for (int i = 1; i <= n; i++) {
  
        if (check(i, 2))
            dp[i] = Math.min(dp[i], 1 + dp[i - 2]);
  
        if (check(i, 3))
            dp[i] = Math.min(dp[i], 1 + dp[i - 3]);
  
        if (check(i, 5))
            dp[i] = Math.min(dp[i], 1 + dp[i - 5]);
  
        if (check(i, 7))
            dp[i] = Math.min(dp[i], 1 + dp[i - 7]);
    }
  
    // Not possible
    if (dp[n] == (1e9))
        return -1;
    else
        return dp[n];
}
  
    // Driver Code
    public static void main(String args[])
    {
      
        int n = 12;
        int minimal = (int)MinimumPrimes(n);
          
        if (minimal != -1)
            System.out.println("Minimum number of single "+ 
                        "digit primes required: "+minimal);
      
        else
            System.out.println("Not Possible");
      
    }

2021
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

}
  
// This code is contributed ankita_saini

Python 3

# Python3 program to find the minimum number 


# of single digit prime numbers required  
# which when summed equals to a given  
# number N.
  
# function to check if i-th 
# index is valid or not 
  
def check(i,val):
    if i-val<0:
        return False
    return True
  
# function to find the minimum number of single 
# digit prime numbers required which when summed up 
# equals to a given number N.
  
def MinimumPrimes(n):
    dp=[10**9]*(n+1)
    dp[0]=dp[2]=dp[3]=dp[5]=dp[7]=1
    for i in range(1,n+1):
        if check(i,2):
            dp[i]=min(dp[i],1+dp[i-2])
        if check(i,3):
            dp[i]=min(dp[i],1+dp[i-3])
        if check(i,5):
            dp[i]=min(dp[i],1+dp[i-5])
        if check(i,7):
            dp[i]=min(dp[i],1+dp[i-7])
  
    # Not possible
    if dp[n]==10**9:
        return -1
    else:
        return dp[n]
  
  
# Driver Code
if __name__ == "__main__":
    n=12
    minimal=MinimumPrimes(n)
    if minimal!=-1:

2022
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

        print("Minimum number of single digit primes required : ",minimal)


    else:
        print("Not possible")
#This code is contributed Saurabh Shukla

C#

// C# program to find the 


// minimum number of single
// digit prime numbers required 
// which when summed equals to 
// a given number N.
using System;
  
class GFG 
{
      
// fuction to check if i-th
// index is valid or not
static Boolean check(int i, 
                     int val)
{
    if (i - val < 0)
        return false;
    else
        return true;
}
  
// function to find the 
// minimum number of single 
// digit prime numbers 
// required which when summed 
// up equals to a given
// number N.
static double MinimumPrimes(int n)
{
    double[] dp;
    dp = new double[n + 1];
  
    for (int i = 1; i <= n; i++)
        dp[i] = 1e9;
  
    dp[0] = dp[2] = dp[3] = dp[5] = dp[7] = 1;
    for (int i = 1; i <= n; i++) 
    {
        if (check(i, 2))
            dp[i] = Math.Min(dp[i], 1 + 
                             dp[i - 2]);

2023
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

  
        if (check(i, 3))
            dp[i] = Math.Min(dp[i], 1 + 
                             dp[i - 3]);
  
        if (check(i, 5))
            dp[i] = Math.Min(dp[i], 1 + 
                             dp[i - 5]);
  
        if (check(i, 7))
            dp[i] = Math.Min(dp[i], 1 + 
                             dp[i - 7]);
    }
  
    // Not possible
    if (dp[n] == (1e9))
        return -1;
    else
        return dp[n];
}
  
// Driver Code
public static void Main(String []args)
{
    int n = 12;
    int minimal = (int)MinimumPrimes(n);
      
    if (minimal != -1)
        Console.WriteLine("Minimum number of single " + 
                            "digit primes required: " + 
                                              minimal);
    else
        Console.WriteLine("Not Possible");
  
}
}
  
// This code is contributed 
// by Ankita_Saini

PHP

<?php
// PHP program to find the minimum 
// number of single digit prime 
// numbers required which when summed
// equals to a given number N.
  

2024
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

// fuction to check if i-th


// index is valid or not
function check($i, $val)
{
    if ($i - $val < 0)
        return false;
    return true;
}
  
// function to find the minimum 
// number of single digit prime 
// numbers required which when 
// summed up equals to a given
// number N.
function MinimumPrimes($n)
{
  
    for ($i = 1; $i<= $n; $i++)
        $dp[$i] = 1e9;
  
    $dp[0] = $dp[2] = $dp[3] = $dp[5] = $dp[7] = 1;
    for ($i = 1; $i <= $n; $i++) 
    {
  
        if (check($i, 2))
            $dp[$i] = min($dp[$i], 1 + 
                          $dp[$i - 2]);
  
        if (check($i, 3))
            $dp[$i] = min($dp[$i], 1 + 
                          $dp[$i - 3]);
  
        if (check($i, 5))
            $dp[$i] = min($dp[$i], 1 + 
                          $dp[$i - 5]);
  
        if (check($i, 7))
            $dp[$i] = min($dp[$i], 1 +
                          $dp[$i - 7]);
    }
  
    // Not possible
    if ($dp[$n] == (1e9))
        return -1;
    else
        return $dp[$n];
}
  

2025
Chapter 277. Minimum number of single digit primes required whose sum is equal to N

// Driver Code
$n = 12;
  
$minimal = MinimumPrimes($n);
if ($minimal != -1)
{
    echo("Minimum number of single " . 
           "digit primes required :"); 
    echo( $minimal );
}
else
{
    echo("Not possible");
}
  
// This code is contributed 
// by Shivi_Aggarwal
?>

Output:

Minimum number of single digit primes required : 2

Time Complexity: O(N)


Note: In case of multiple queries, the dp[] array can be pre-computed and we can answer
every query in O(1).
Improved By : Shivi_Aggarwal, ankita_saini, S1gma

Source

https://www.geeksforgeeks.org/minimum-number-of-single-digit-primes-required-whose-sum-is-equal-to-n/

2026
Chapter 278

Minimum number of squares


whose sum equals to given
number n

Minimum number of squares whose sum equals to given number n - GeeksforGeeks


A number can always be represented as a sum of squares of other numbers. Note that 1 is
a square and we can always break a number as (1*1 + 1*1 + 1*1 + …). Given a number n,
find the minimum number of squares that sum to X.
Examples :

Input: n = 100
Output: 1
100 can be written as 102. Note that 100 can also be
written as 52 + 52 + 52 + 52, but this
representation requires 4 squares.

Input: n = 6
Output: 3

The idea is simple, we start from 1 and go till a number whose square is smaller than or
equals to n. For every number x, we recur for n-x. Below is the recursive formula.

If n = 1 and x*x <= n

Below is a simple recursive solution based on above recursive formula.

C++

2027
Chapter 278. Minimum number of squares whose sum equals to given number n

// A naive recursive C++ program to find minimum


// number of squares whose sum is equal to a given number
#include<bits/stdc++.h>
using namespace std;
  
// Returns count of minimum squares that sum to n
int getMinSquares(unsigned int n)
{
    // base cases
    if (n <= 3)
        return n;
  
    // getMinSquares rest of the table using recursive
    // formula
    int res = n; // Maximum squares required is n (1*1 + 1*1 + ..)
  
    // Go through all smaller numbers
    // to recursively find minimum
    for (int x = 1; x <= n; x++)
    {
        int temp = x*x;
        if (temp > n)
            break;
        else
            res =  min(res, 1+getMinSquares(n - temp));
    }
    return res;
}
  
// Driver program
int main()
{
    cout << getMinSquares(6);
    return 0;
}

Java

// A naive recursive JAVA program to find minimum


// number of squares whose sum is equal to a given number
class squares
{
    // Returns count of minimum squares that sum to n
    static int getMinSquares(int n)
    {
        // base cases
        if (n <= 3)
            return n;

2028
Chapter 278. Minimum number of squares whose sum equals to given number n

  
        // getMinSquares rest of the table using recursive
        // formula
        int res = n; // Maximum squares required is
                     // n (1*1 + 1*1 + ..)
  
        // Go through all smaller numbers
        // to recursively find minimum
        for (int x = 1; x <= n; x++)
        {
            int temp = x*x;
            if (temp > n)
                break;
            else
                res =  Math.min(res, 1+getMinSquares(n - temp));
        }
        return res;
    }
    public static void main(String args[])
    {
        System.out.println(getMinSquares(6));
    }
}
/* This code is contributed by Rajat Mishra */

Python

# A naive recursive Python program to


# find minimum number of squares whose
# sum is equal to a given number
  
# Returns count of minimum squares 
# that sum to n
def getMinSquares(n):
  
    # base cases
    if n <= 3:
        return n;
  
    # getMinSquares rest of the table 
    # using recursive formula
    res = n # Maximum squares required 
            # is n (1*1 + 1*1 + ..)
  
    # Go through all smaller numbers
    # to recursively find minimum
    for x in range(1, n+1):
        temp = x * x;

2029
Chapter 278. Minimum number of squares whose sum equals to given number n

        if temp > n:


            break
        else:
            res = min(res, 1 + getMinSquares(n 
                                  - temp))
      
    return res;
  
# Driver program 
print(getMinSquares(6))
  
# This code is contributed by nuclode

C#

// A naive recursive C# program


// to find minimum number of 
// squares whose sum is equal 
// to a given number
using System;
  
class GFG {
      
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
          
        // base cases
        if (n <= 3)
            return n;
  
        // getMinSquares rest of the
        // table using recursive
        // formula
          
        // Maximum squares required is
        // n (1*1 + 1*1 + ..)
        int res = n; 
          
        // Go through all smaller numbers
        // to recursively find minimum
        for (int x = 1; x <= n; x++)
        {
            int temp = x * x;
            if (temp > n)
                break;
            else

2030
Chapter 278. Minimum number of squares whose sum equals to given number n

                res = Math.Min(res, 1 + getMinSquares(n - temp));


        }
        return res;
    }
      
    // Driver Code
    public static void Main()
    {
        Console.Write(getMinSquares(6));
    }
}
  
// This code is contributed by nitin mittal

PHP

<?php
// A naive recursive PHP program
// to find minimum number of 
// squares whose sum is equal 
// to a given number
  
// Returns count of minimum 
// squares that sum to n
function getMinSquares($n)
{
    // base cases
    if ($n <= 3)
        return $n;
  
    // getMinSquares rest of the 
    // table using recursive formula
      
    // Maximum squares required
    // is n (1*1 + 1*1 + ..)
    $res = $n; 
  
    // Go through all smaller numbers
    // to recursively find minimum
    for ($x = 1; $x <= $n; $x++)
    {
        $temp = $x * $x;
        if ($temp > $n)
            break;
        else
            $res = min($res, 1 + 
                       getMinSquares($n - 
                                     $temp));

2031
Chapter 278. Minimum number of squares whose sum equals to given number n

    }
    return $res;
}
  
// Driver Code
echo getMinSquares(6);
  
// This code is contributed
// by nitin mittal.
?>

Output :

The time complexity of above solution is exponential. If we draw the complete recursion
tree, we can observer that many subproblems are solved again and again. For example,
when we start from n = 6, we can reach 4 by subtracting one 2 times and by subtracting 2
one times. So the subproblem for 4 is called twice.
Since same suproblems are called again, this problem has Overlapping Subprolems property.
So min square sum problem has both properties (see thisand this) of a dynamic program-
ming problem. Like other typical Dynamic Programming(DP) problems, recomputations of
same subproblems can be avoided by constructing a temporary array table[][] in bottom up
manner. Below is Dynamic Programming based solution
C++

// A dynamic programming based C++ program to find minimum


// number of squares whose sum is equal to a given number
#include<bits/stdc++.h>
using namespace std;
  
// Returns count of minimum squares that sum to n
int getMinSquares(int n)
{
    // Create a dynamic programming table
    // to store sq
    int *dp = new int[n+1];
  
    // getMinSquares table for base case entries
    dp[0] = 0;
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 3;
  
    // getMinSquares rest of the table using recursive
    // formula
    for (int i = 4; i <= n; i++)

2032
Chapter 278. Minimum number of squares whose sum equals to given number n

    {
        // max value is i as i can always be represented
        // as 1*1 + 1*1 + ...
        dp[i] = i;
  
        // Go through all smaller numbers to
        // to recursively find minimum
        for (int x = 1; x <= i; x++) {
            int temp = x*x;
            if (temp > i)
                break;
            else dp[i] = min(dp[i], 1+dp[i-temp]);
        }
    }
  
    // Store result and free dp[]
    int res = dp[n];
    delete [] dp;
  
    return res;
}
  
// Driver program
int main()
{
    cout << getMinSquares(6);
    return 0;
}

Java

// A dynamic programming based JAVA program to find minimum


// number of squares whose sum is equal to a given number
class squares
{
    // Returns count of minimum squares that sum to n
    static int getMinSquares(int n)
    {
        // Create a dynamic programming table
        // to store sq
        int dp[] = new int[n+1];
       
        // getMinSquares table for base case entries
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
       

2033
Chapter 278. Minimum number of squares whose sum equals to given number n

        // getMinSquares rest of the table using recursive


        // formula
        for (int i = 4; i <= n; i++)
        {
            // max value is i as i can always be represented
            // as 1*1 + 1*1 + ...
            dp[i] = i;
       
            // Go through all smaller numbers to
            // to recursively find minimum
            for (int x = 1; x <= i; x++) {
                int temp = x*x;
                if (temp > i)
                    break;
                else dp[i] = Math.min(dp[i], 1+dp[i-temp]);
            }
        }
       
        // Store result and free dp[]
        int res = dp[n];
       
        return res;
    }
    public static void main(String args[])
    {
       System.out.println(getMinSquares(6));
    }
}/* This code is contributed by Rajat Mishra */

Python

# A dynamic programming based Python


# program to find minimum number of
# squares whose sum is equal to a 
# given number
  
# Returns count of minimum squares 
# that sum to n
def getMinSquares(n):
  
    # Create a dynamic programming table
    # to store sq and getMinSquares table
    # for base case entries
    dp = [0, 1, 2, 3]
  
    # getMinSquares rest of the table 
    # using recursive formula
    for i in range(4, n+1):

2034
Chapter 278. Minimum number of squares whose sum equals to given number n

          
        # max value is i as i can always 
        # be represented as 1*1 + 1*1 + ...
        dp.append(i)
  
        # Go through all smaller numbers 
        # to recursively find minimum
        for x in range(1, i + 1):
            temp = x * x;
            if temp > i:
                break
            else:
                dp[i] = min(dp[i], 1 + 
                            dp[i-temp])
  
    # Store result
    return dp[n]
  
# Driver program
print(getMinSquares(6))
  
# This code is contributed by nuclode

C#

// A dynamic programming based 


// C# program to find minimum
// number of squares whose sum
// is equal to a given number
using System;
  
class squares
{
    // Returns count of minimum
    // squares that sum to n
    static int getMinSquares(int n)
    {
        // Create a dynamic programming
        // table to store sq
        int []dp = new int[n + 1];
      
        // getMinSquares table for base
        // case entries
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 3;
      

2035
Chapter 278. Minimum number of squares whose sum equals to given number n

        // getMinSquares for rest of the  


        // table using recursive formula
        for (int i = 4; i <= n; i++)
        {
            // max value is i as i can 
            // always be represented 
            // as 1 * 1 + 1 * 1 + ...
            dp[i] = i;
      
            // Go through all smaller numbers to
            // to recursively find minimum
            for (int x = 1; x <= i; x++) {
                int temp = x * x;
                if (temp > i)
                    break;
                else dp[i] = Math.Min(dp[i], 1 + 
                                      dp[i - temp]);
            }
        }
      
        // Store result and free dp[]
        int res = dp[n];
      
        return res;
    }
      
    // Driver Code
    public static void Main(String []args)
    {
    Console.Write(getMinSquares(6));
    }
}
  
// This code is contributed by Nitin Mittal.

PHP

<?php
// A dynamic programming based 
// PHP program to find minimum
// number of squares whose sum
// is equal to a given number
  
// Returns count of minimum
// squares that sum to n
function getMinSquares($n)
{
    // Create a dynamic programming

2036
Chapter 278. Minimum number of squares whose sum equals to given number n

    // table to store sq


    $dp;
  
    // getMinSquares table for
    // base case entries
    $dp[0] = 0;
    $dp[1] = 1;
    $dp[2] = 2;
    $dp[3] = 3;
  
    // getMinSquares rest of the 
    // table using recursive formula
    for ($i = 4; $i <= $n; $i++)
    {
        // max value is i as i can 
        // always be represented
        // as 1*1 + 1*1 + ...
        $dp[$i] = $i;
  
        // Go through all smaller 
        // numbers to recursively 
        // find minimum
        for ($x = 1; $x <= $i; $x++) 
        {
            $temp = $x * $x;
            if ($temp > $i)
                break;
            else $dp[$i] = min($dp[$i], 
                              (1 + $dp[$i - $temp]));
        }
    }
  
    // Store result 
    // and free dp[]
    $res = $dp[$n];
  
// delete $dp;
  
    return $res;
}
  
// Driver Code
echo getMinSquares(6);
      
// This code is contributed
// by shiv_bhakt. 
?>

2037
Chapter 278. Minimum number of squares whose sum equals to given number n

Output:

Thanks to Gaurav Ahirwar for suggesting this solution.


Improved By : nitin mittal, shiv_bhakt

Source

https://www.geeksforgeeks.org/minimum-number-of-squares-whose-sum-equals-to-given-number-n/

2038
Chapter 279

Minimum removals from array


to make max – min <= K

Minimum removals from array to make max - min <= K - GeeksforGeeks


Given N integers and K, find the minimum number of elements that should be removed such
that Amax -Amin <=K. After removal of elements, Amax and Amin is considered among the
remaining elements.
Examples:

Input : a[] = {1, 3, 4, 9, 10, 11, 12, 17, 20}


k = 4
Output : 5
Explanation: Remove 1, 3, 4 from beginning
and 17, 20 from the end.

Input : a[] = {1, 5, 6, 2, 8} K=2


Output : 3
Explanation: There are multiple ways to
remove elements in this case.
One among them is to remove 5, 6, 8.
The other is to remove 1, 2, 5

Approach: Sort the given elements. Using greedy approach, the best way is to remove the
minimum element or the maximum element and then check if Amax -Amin <= K. There
are various combinations of removals that have to be considered. We write a recurrence
relation to try every possible combination. There will be two possible ways of removal,
either we remove the minimum or we remove the maximum. Let(i…j) be the index of
elements left after removal of elements. Initially, we start with i=0 and j=n-1 and
the number of elements removed is 0 at the beginning. We only remove an element if
a[j]-a[i]>k, the two possible ways of removal are (i+1…j) or (i…j-1). The minimum of
the two is considered.

2039
Chapter 279. Minimum removals from array to make max – min <= K

Let DPi, j be the number of elements that need to be removed so that after removal a[j]-
a[i]<=k.
Recurrence relation for sorted array:

DPi, j = 1+ (min(countRemovals(i+1, j), countRemovals(i, j-1))

Below is the implementation of the above idea:


C++

// CPP program to find minimum removals


// to make max-min <= K
#include <bits/stdc++.h>
using namespace std;
  
#define MAX 100
int dp[MAX][MAX];
  
// function to check all possible combinations
// of removal and return the minimum one
int countRemovals(int a[], int i, int j, int k)
{
    // base case when all elements are removed
    if (i >= j)
        return 0;
  
    // if condition is satisfied, no more
    // removals are required
    else if ((a[j] - a[i]) <= k)
        return 0;
  
    // if the state has already been visited
    else if (dp[i][j] != -1)
        return dp[i][j];
  
    // when Amax-Amin>d
    else if ((a[j] - a[i]) > k) {
  
        // minimum is taken of the removal
        // of minimum element or removal
        // of the maximum element
        dp[i][j] = 1 + min(countRemovals(a, i + 1, j, k),
                           countRemovals(a, i, j - 1, k));
    }
    return dp[i][j];
}
  

2040
Chapter 279. Minimum removals from array to make max – min <= K

// To sort the array and return the answer


int removals(int a[], int n, int k)
{
    // sort the array
    sort(a, a + n);
  
    // fill all stated with -1
    // when only one element
    memset(dp, -1, sizeof(dp));
    if (n == 1)
        return 0;
    else
        return countRemovals(a, 0, n - 1, k);
}
  
// Driver Code
int main()
{
    int a[] = { 1, 3, 4, 9, 10, 11, 12, 17, 20 };
    int n = sizeof(a) / sizeof(a[0]);
    int k = 4;
    cout << removals(a, n, k);
    return 0;
}

Java

// Java program to find minimum removals


// to make max-min <= K
import java.util.Arrays;
  
class GFG
{
    static int MAX=100;
    static int dp[][]=new int[MAX][MAX];
      
    // function to check all possible combinations
    // of removal and return the minimum one
    static int countRemovals(int a[], int i, int j, int k)
    {
        // base case when all elements are removed
        if (i >= j)
            return 0;
      
        // if condition is satisfied, no more
        // removals are required
        else if ((a[j] - a[i]) <= k)
            return 0;

2041
Chapter 279. Minimum removals from array to make max – min <= K

      
        // if the state has already been visited
        else if (dp[i][j] != -1)
            return dp[i][j];
      
        // when Amax-Amin>d
        else if ((a[j] - a[i]) > k) {
      
            // minimum is taken of the removal
            // of minimum element or removal
            // of the maximum element
            dp[i][j] = 1 + Math.min(countRemovals(a, i + 1, j, k),
                                    countRemovals(a, i, j - 1, k));
        }
        return dp[i][j];
    }
      
    // To sort the array and return the answer
    static int removals(int a[], int n, int k)
    {
        // sort the array
        Arrays.sort(a);
      
        // fill all stated with -1
        // when only one element
        for(int[] rows:dp)
        Arrays.fill(rows,-1);
        if (n == 1)
            return 0;
        else
            return countRemovals(a, 0, n - 1, k);
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int a[] = { 1, 3, 4, 9, 10, 11, 12, 17, 20 };
        int n = a.length;
        int k = 4;
        System.out.print(removals(a, n, k));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python program to find 

2042
Chapter 279. Minimum removals from array to make max – min <= K

# minimum removals to
# make max-min <= K
MAX = 100
dp = [[0 for i in range(MAX)] 
         for i in range(MAX)]
for i in range(0, MAX) :
    for j in range(0, MAX) :
        dp[i][j] = -1
  
# function to check all 
# possible combinations
# of removal and return
# the minimum one
def countRemovals(a, i, j, k) :
  
    global dp
      
    # base case when all 
    # elements are removed
    if (i >= j) :
        return 0
  
    # if condition is satisfied, 
    # no more removals are required
    elif ((a[j] - a[i]) <= k) :
        return 0
  
    # if the state has 
    # already been visited
    elif (dp[i][j] != -1) :
        return dp[i][j]
  
    # when Amax-Amin>d
    elif ((a[j] - a[i]) > k) :
  
        # minimum is taken of 
        # the removal of minimum
        # element or removal of 
        # the maximum element
        dp[i][j] = 1 + min(countRemovals(a, i + 1, 
                                         j, k),
                           countRemovals(a, i, 
                                         j - 1, k))
    return dp[i][j]
  
# To sort the array 
# and return the answer
def removals(a, n, k) :

2043
Chapter 279. Minimum removals from array to make max – min <= K

  
    # sort the array
    a.sort()
  
    # fill all stated 
    # with -1 when only
    # one element
    if (n == 1) :
        return 0
    else :
        return countRemovals(a, 0, 
                             n - 1, k)
  
# Driver Code
a = [1, 3, 4, 9, 10, 
     11, 12, 17, 20]
n = len(a)
k = 4
print (removals(a, n, k))
  
# This code is contributed by 
# Manish Shaw(manishshaw1)

C#

// C# program to find minimum 


// removals to make max-min <= K
using System;
  
class GFG
{
    static int MAX = 100;
    static int [,]dp = new int[MAX, MAX];
      
    // function to check all 
    // possible combinations
    // of removal and return
    // the minimum one
    static int countRemovals(int []a, int i,
                             int j, int k)
    {
        // base case when all
        // elements are removed
        if (i >= j)
            return 0;
      
        // if condition is satisfied, 
        // no more removals are required

2044
Chapter 279. Minimum removals from array to make max – min <= K

        else if ((a[j] - a[i]) <= k)


            return 0;
      
        // if the state has
        // already been visited
        else if (dp[i, j] != -1)
            return dp[i, j];
      
        // when Amax-Amin>d
        else if ((a[j] - a[i]) > k)
        {
      
            // minimum is taken of the 
            // removal of minimum element 
            // or removal of the maximum 
            // element
            dp[i, j] = 1 + Math.Min(countRemovals(a, i + 1, 
                                                  j, k),
                                    countRemovals(a, i, 
                                                  j - 1, k));
        }
        return dp[i, j];
    }
      
    // To sort the array and
    // return the answer
    static int removals(int []a, 
                        int n, int k)
    {
        // sort the array
        Array.Sort(a);
      
        // fill all stated with -1
        // when only one element
        for(int i = 0; i < MAX; i++) 
        {
            for(int j = 0; j < MAX; j++)
                dp[i, j] = -1;
        }
        if (n == 1)
            return 0;
        else
            return countRemovals(a, 0, 
                                 n - 1, k);
    }
      
    // Driver code
    static void Main() 

2045
Chapter 279. Minimum removals from array to make max – min <= K

    {
        int []a = new int[]{ 1, 3, 4, 9, 10, 
                             11, 12, 17, 20 };
        int n = a.Length;
        int k = 4;
        Console.Write(removals(a, n, k));
    }
}
  
// This code is contributed by 
// ManishShaw(manishshaw1)

PHP

<?php
// PHP program to find 
// minimum removals to
// make max-min <= K
$MAX = 100;
$dp = array(array());
for($i = 0; $i < $MAX; $i++)
{
    for($j = 0; $j < $MAX; $j++)
        $dp[$i][$j] = -1;
}
  
// function to check all 
// possible combinations
// of removal and return
// the minimum one
function countRemovals($a, $i, 
                       $j, $k)
{
    global $dp;
      
    // base case when all 
    // elements are removed
    if ($i >= $j)
        return 0;
  
    // if condition is satisfied, 
    // no more removals are required
    else if (($a[$j] - $a[$i]) <= $k)
        return 0;
  
    // if the state has 
    // already been visited
    else if ($dp[$i][$j] != -1)

2046
Chapter 279. Minimum removals from array to make max – min <= K

        return $dp[$i][$j];
  
    // when Amax-Amin>d
    else if (($a[$j] - $a[$i]) > $k) 
    {
  
        // minimum is taken of 
        // the removal of minimum
        // element or removal of 
        // the maximum element
        $dp[$i][$j] = 1 + min(countRemovals($a, $i + 1, 
                                                $j, $k),
                              countRemovals($a, $i, 
                                            $j - 1, $k));
    }
    return $dp[$i][$j];
}
  
// To sort the array 
// and return the answer
function removals($a, $n, $k)
{
    // sort the array
    sort($a);
  
    // fill all stated with -1
    // when only one element
    if ($n == 1)
        return 0;
    else
        return countRemovals($a, 0, 
                             $n - 1, $k);
}
  
// Driver Code
$a = array(1, 3, 4, 9, 10, 
           11, 12, 17, 20);
$n = count($a);
$k = 4;
echo (removals($a, $n, $k));
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

Output:

2047
Chapter 279. Minimum removals from array to make max – min <= K

Time Complexity :O(n2 )


Auxiliary Space: O(n2 )
Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/minimum-removals-array-make-max-min-k/

2048
Chapter 280

Minimum splits in a binary


string such that every substring
is a power of 4 or 6.

Minimum splits in a binary string such that every substring is a power of 4 or 6. - Geeks-
forGeeks
Given a string S composed of 0 and 1. Find the minimum splits such that the substring is
a binary representation of the power of 4 or 6 with no leading zeros. Print -1 if no such
partitioning is possible.

Examples:

Input: 100110110
Output: 3
The string can be split into a minimum of
three substrings 100(power of 4), 110
(power of 6) and 110(power of 6).

Input : 00000
Output : -1
0 is not a power of 4 or 6.

A simple solution is to split the string recursively at different indices and check if each split
is a power of 4 or 6. Start with index 0 and split str[0] from other string. If it is a power of 4
or 6 then call recursively for index 1 and perform the same operation. When an entire string
is split check if a total number of partitions are minimum so far or not. Then split str[0..1],
check if it is the power of 4 or 6 and then call recursively for rest string. Compare partitions
with minimum so far at the end of string traversal. This approach will be exponential in
time.

2049
Chapter 280. Minimum splits in a binary string such that every substring is a power of 4
or 6.

An efficient solution is to use Dynamic Programming. A 1-D dp table is created in which


dp[i] stores minimum number of partitions required to split string str[i..n-1] into substrings
that are power of 4 or 6. Suppose we are at index i and str[i..j] is power of 4 or 6, then
minimum number of partitions will be minimum number of partitions to split str[j+1..n-1]
plus one partition to split str[i..j] from string, that is dp[j+1] + 1. Hence the recurrence
relation for (j!=(n-1)) and (dp[j + 1]!=-1) will be:

dp[i] = min(dp[i], dp[j + 1] + 1)

Implementation:

C++

// CPP program for Minimum splits in a 


//string such that substring is a power of 4 or 6.
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to find if given number
// is power of another number or not.
bool isPowerOf(long val, int base)
{
  
    // Divide given number repeatedly
    // by base value. 
    while (val > 1) {
        if (val % base != 0)
            return false; // not a power 
        val /= base;
    }
  
    return true;
}
  
// Function to find minimum number of
// partitions of given binary string
// so that each partition is power of 4 or 6. 
int numberOfPartitions(string binaryNo)
{
    int i, j, n = binaryNo.length();
  
    // Variable to store integer value of
    // given binary string partition.
    long val;
  
    // DP table to store results of

2050
Chapter 280. Minimum splits in a binary string such that every substring is a power of 4
or 6.

    // partitioning done at differentindices.


    int dp[n];
  
    // If the last digit is 1, hence 4^0=1 and 6^0=1
    dp[n - 1] = ((binaryNo[n - 1] - '0') == 0) ? -1 : 1;
  
    // Fix starting position for partition
    for (i = n - 2; i >= 0; i--) {
        val = 0;
  
        // Binary representation
        // with leading zeroes is not allowed. 
        if ((binaryNo[i] - '0') == 0) {
            dp[i] = -1;
            continue;
        }
  
        dp[i] = INT_MAX;
  
        // Iterate for all different partitions starting from i
        for (j = i; j < n; j++) {
  
            // Find integer value of current
            // binary partition.
            val = (val * 2) + (long)(binaryNo[j] - '0');
  
            // Check if the value is a power of 4 or 6 or not
            // apply recurrence relation
            if (isPowerOf(val, 4) || isPowerOf(val, 6)) {
                if (j == n - 1) {
                    dp[i] = 1;
                }
                else {
                    if (dp[j + 1] != -1)
                        dp[i] = min(dp[i], dp[j + 1] + 1);
                }
            }
        }
  
        // If no partitions are possible, then
        // make dp[i] = -1 to represent this.
        if (dp[i] == INT_MAX)
            dp[i] = -1;
    }
  
    return dp[0];
}
  

2051
Chapter 280. Minimum splits in a binary string such that every substring is a power of 4
or 6.

// Driver code
int main()
{
    string binaryNo = "100110110";
    cout << numberOfPartitions(binaryNo);
    return 0;
}

Java

// JAVA program for Minimum splits 


// in a string such that substring 
// is a power of 4 or 6.
import java.io.*;
  
class GFG 
{
    static boolean isPowerOf(long val, 
                             int base)
{
  
    // Divide given number 
    // repeatedly by base value. 
    while (val > 1) 
    {
        if (val % base != 0)
            return false; // not a power 
        val /= base;
    }
  
    return true;
}
  
// Function to find minimum 
// number of partitions of 
// given binary string so that
// each partition is power 
// of 4 or 6. 
static int numberOfPartitions(String binaryNo)
{
    int i, j, n = binaryNo.length();
  
    // Variable to store integer
    // value of given binary 
    // string partition.
    long val;
  
    // DP table to store results 

2052
Chapter 280. Minimum splits in a binary string such that every substring is a power of 4
or 6.

    // of partitioning done at 


    // differentindices.
    int dp[] = new int[n];
  
    // If the last digit is 1, 
    // hence 4^0=1 and 6^0=1
    dp[n - 1] = (((binaryNo.charAt(n - 1) - 
                               '0') == 0) ? 
                                   -1 : 1);
  
    // Fix starting position
    // for partition
    for (i = n - 2; i >= 0; i--) 
    {
        val = 0;
  
        // Binary representation
        // with leading zeroes 
        // is not allowed. 
        if ((binaryNo.charAt(i) - '0') == 0) 
        {
            dp[i] = -1;
            continue;
        }
  
        dp[i] = Integer.MAX_VALUE;
  
        // Iterate for all different
        // partitions starting from i
        for (j = i; j < n; j++) 
        {
  
            // Find integer value of 
            // current binary partition.
            val = (val * 2) + 
                  (long)(binaryNo.charAt(j) - '0');
  
            // Check if the value is a 
            // power of 4 or 6 or not
            // apply recurrence relation
            if (isPowerOf(val, 4) || 
                isPowerOf(val, 6))
            {
                if (j == n - 1)
                {
                    dp[i] = 1;
                }
                else 

2053
Chapter 280. Minimum splits in a binary string such that every substring is a power of 4
or 6.

                {
                    if (dp[j + 1] != -1)
                        dp[i] = Math.min(dp[i], 
                                         dp[j + 1] + 1);
                }
            }
        }
  
        // If no partitions are possible, 
        // then make dp[i] = -1 to 
        // represent this.
        if (dp[i] == Integer.MAX_VALUE)
            dp[i] = -1;
    }
  
    return dp[0];
}
  
// Driver code
public static void main (String[] args) 
{
    String binaryNo = "100110110";
    System.out.println(numberOfPartitions(binaryNo));
}
}
  
// This code is contributed
// by shiv_bhakt.

Output: 3

Time Complexity: O(n^2*log(x)), x = largest power of 4 or 6 obtainable from input


string.
Auxiliary Space: O(n)
Improved By : shiv_bhakt

Source

https://www.geeksforgeeks.org/minimum-splits-in-a-binary-string-such-that-every-substring-is-a-power-of-4-or-6/

2054
Chapter 281

Minimum steps to delete a


string after repeated deletion of
palindrome substrings

Minimum steps to delete a string after repeated deletion of palindrome substrings - Geeks-
forGeeks
Given a string containing characters as integers only. We need to delete all character of this
string in a minimum number of steps where in one step we can delete the substring which
is a palindrome. After deleting a substring remaining parts are concatenated.
Examples:

Input : s = “2553432”
Output : 2
We can delete all character of above string in
2 steps, first deleting the substring s[3, 5] “343”
and then remaining string completely s[0, 3] “2552”

Input : s = “1234”
Output : 4
We can delete all character of above string in 4
steps only because each character need to be deleted
separately. No substring of length 2 is a palindrome
in above string.

We can solve this problem using Dynamic programming. Let dp[i][j] denotes the number of
steps it takes to delete the substring s[i, j]. Each character will be deleted alone or as part of
some substring so in the first case we will delete the character itself and call subproblem (i+1,
j). In the second case we will iterate over all occurrence of the current character in right side,
if K is the index of one such occurrence then the problem will reduce to two subproblems

2055
Chapter 281. Minimum steps to delete a string after repeated deletion of palindrome
substrings

(i+1, K – 1) and (K+1, j). We can reach to this subproblem (i+1, K-1) because we can just
delete the same character and call for mid substring. We need to take care of a case when
first two characters are same in that case we can directly reduce to the subproblem (i+2, j)
So after above discussion of relation among subproblems, we can write dp relation as follows,

dp[i][j] = min(1 + dp[i+1][j],


dp[i+1][K-1] + dp[K+1][j], where s[i] == s[K]
1 + dp[i+2][j] )

Total time complexity of above solution is O(n^3)

C++

//  C++ program to find minimum step to delete a string


#include <bits/stdc++.h>
using namespace std;
  
/* method returns minimum step for deleting the string,
   where in one step a palindrome is removed */
int minStepToDeleteString(string str)
{
    int N = str.length();
  
    //  declare dp array and initialize it with 0s
    int dp[N + 1][N + 1];
    for (int i = 0; i <= N; i++)
        for (int j = 0; j <= N; j++)
            dp[i][j] = 0;
  
    // loop for substring length we are considering
    for (int len = 1; len <= N; len++)
    {
        // loop with two variables i and j, denoting
        // starting and ending of substrings
        for (int i = 0, j = len - 1; j < N; i++, j++)
        {
            // If substring length is 1, then 1 step
            // will be needed
            if (len == 1)
                dp[i][j] = 1;
            else
            {
                // delete the ith char individually
                // and assign result for subproblem (i+1,j)
                dp[i][j] = 1 + dp[i + 1][j];

2056
Chapter 281. Minimum steps to delete a string after repeated deletion of palindrome
substrings

  
                // if current and next char are same,
                // choose min from current and subproblem
                // (i+2,j)
                if (str[i] == str[i + 1])
                    dp[i][j] = min(1 + dp[i + 2][j], dp[i][j]);
  
                /*  loop over all right characters and suppose
                    Kth char is same as ith character then
                    choose minimum from current and two
                    substring after ignoring ith and Kth char */
                for (int K = i + 2; K <= j; K++)
                    if (str[i] == str[K])
                        dp[i][j] = min(dp[i+1][K-1] + dp[K+1][j],
                                                       dp[i][j]);
            }
        }
    }
  
    /* Uncomment below snippet to print actual dp tablex
    for (int i = 0; i < N; i++, cout << endl)
        for (int j = 0; j < N; j++)
            cout << dp[i][j] << " ";    */
  
    return dp[0][N - 1];
}
  
//  Driver code to test above methods
int main()
{
    string str = "2553432";
    cout << minStepToDeleteString(str) << endl;
    return 0;
}

Java

// Java program to find minimum step to 


// delete a string
public class GFG 
{                            
    /* method returns minimum step for deleting
       the string, where in one step a
       palindrome is removed
     */
    static int minStepToDeleteString(String str) {
        int N = str.length();
  

2057
Chapter 281. Minimum steps to delete a string after repeated deletion of palindrome
substrings

        // declare dp array and initialize it with 0s


        int[][] dp = new int[N + 1][N + 1];
        for (int i = 0; i <= N; i++)
            for (int j = 0; j <= N; j++)
                dp[i][j] = 0;
  
        // loop for substring length we are considering
        for (int len = 1; len <= N; len++) {
              
            // loop with two variables i and j, denoting
            // starting and ending of substrings
            for (int i = 0, j = len - 1; j < N; i++, j++) {
      
                // If substring length is 1, then 1 step
                // will be needed
                if (len == 1)
                    dp[i][j] = 1;
                      
                else {
                    // delete the ith char individually
                    // and assign result for 
                    // subproblem (i+1,j)
                    dp[i][j] = 1 + dp[i + 1][j];
  
                    // if current and next char are same,
                    // choose min from current and 
                    // subproblem (i+2, j)
                    if (str.charAt(i) == str.charAt(i + 1))
                        dp[i][j] = Math.min(1 + dp[i + 2][j], 
                                               dp[i][j]);
  
                    /* loop over all right characters and 
                      suppose Kth char is same as ith 
                      character then choose minimum from 
                      current and two substring after 
                      ignoring ith and Kth char
                     */
                    for (int K = i + 2; K <= j; K++)
                        if (str.charAt(i) == str.charAt(K))
                            dp[i][j] = Math.min(
                                         dp[i + 1][K - 1] +
                                        dp[K + 1][j], dp[i][j]);
                }
            }
        }
  
        /* Uncomment below snippet to print actual dp tablex 
           

2058
Chapter 281. Minimum steps to delete a string after repeated deletion of palindrome
substrings

           for (int i = 0; i < N; i++){


           System.out.println(); 
           for (int j = 0; j < N; j++) 
           System.out.print(dp[i][j] + " ");
           }
            */
              
        return dp[0][N - 1];
    }
  
    // Driver code to test above methods
    public static void main(String args[]) {
        String str = "2553432";
        System.out.println(minStepToDeleteString(str));
    }
}
// This code is contributed by Sumit Ghosh

C#

// C# program to find minimum step to 


// delete a string
using System;
  
class GFG {    
      
    /* method returns minimum step for deleting
    the string, where in one step a
    palindrome is removed */
    static int minStepToDeleteString(string str)
    {
        int N = str.Length;
  
        // declare dp array and initialize it 
        // with 0s
        int [,]dp = new int[N + 1,N + 1];
          
        for (int i = 0; i <= N; i++)
            for (int j = 0; j <= N; j++)
                dp[i,j] = 0;
  
        // loop for substring length we are
        // considering
        for (int len = 1; len <= N; len++) {
              
            // loop with two variables i and j,
            // denoting starting and ending of 
            // substrings

2059
Chapter 281. Minimum steps to delete a string after repeated deletion of palindrome
substrings

            for (int i = 0, j = len - 1; j < N; i++, j++)


            {
      
                // If substring length is 1, then 1
                // step will be needed
                if (len == 1)
                    dp[i,j] = 1;
                      
                else 
                {
                    // delete the ith char individually
                    // and assign result for 
                    // subproblem (i+1,j)
                    dp[i,j] = 1 + dp[i + 1,j];
  
                    // if current and next char are same,
                    // choose min from current and 
                    // subproblem (i+2, j)
                    if (str[i] == str[i + 1])
                        dp[i,j] = Math.Min(1 + dp[i + 2,j], 
                                                  dp[i,j]);
  
                    /* loop over all right characters and 
                    suppose Kth char is same as ith 
                    character then choose minimum from 
                    current and two substring after 
                    ignoring ith and Kth char
                    */
                    for (int K = i + 2; K <= j; K++)
                        if (str[i] == str[K])
                            dp[i,j] = Math.Min(
                                        dp[i + 1,K - 1] +
                                     dp[K + 1,j], dp[i,j]);
                }
            }
        }
  
        /* Uncomment below snippet to print actual dp tablex 
          
        for (int i = 0; i < N; i++){
        System.out.println(); 
        for (int j = 0; j < N; j++) 
        System.out.print(dp[i][j] + " ");
        } */
              
        return dp[0,N - 1];
    }
  

2060
Chapter 281. Minimum steps to delete a string after repeated deletion of palindrome
substrings

    // Driver code to test above methods


    public static void Main() 
    {
        string str = "2553432";
        Console.Write(minStepToDeleteString(str));
    }
}
  
// This code is contributed by nitin mittal

Output:

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/minimum-steps-to-delete-a-string-after-repeated-deletion-of-palindrome-substrings/

2061
Chapter 282

Minimum steps to minimize n


as per given condition

Minimum steps to minimize n as per given condition - GeeksforGeeks


Given a number n, count minimum steps to minimize it to 1 according to the following
criteria:

• If n is divisible by 2 then we may reduce n to n/2.


• If n is divisible by 3 then you may reduce n to n/3.
• Decrement n by 1.

Examples:

Input : n = 10
Output : 3

Input : 6
Output : 2

Greedy Approach (Doesn’t work always) :


As per greedy approach we may choose the step that makes n as low as possible and continue
the same, till it reaches 1.

while ( n > 1)
{
if (n % 3 == 0)
n /= 3;
else if (n % 2 == 0)

2062
Chapter 282. Minimum steps to minimize n as per given condition

n /= 2;
else
n--;
steps++;
}

If we observe carefully, the greedy strategy doesn’t work here.


Eg: Given n = 10 , Greedy –> 10 /2 = 5 -1 = 4 /2 = 2 /2 = 1 ( 4 steps ).
But the optimal way is –> 10 -1 = 9 /3 = 3 /3 = 1 ( 3 steps ).
So, we must think of dynamic approach for optimal solution.
Dynamic Approach:
For finding minimum steps we have three possibilities for n and they are:

f(n) = 1 + f(n-1)
f(n) = 1 + f(n/2) // if n is divisible by 2
f(n) = 1 + f(n/3) // if n is divisible by 3

Below is memoization based implementation of above recursive formula.

C++

// CPP program to minimize n to 1 by given


// rule in minimum steps
#include <bits/stdc++.h>
using namespace std;
  
// function to calculate min steps
int getMinSteps(int n, int *memo)
{
    // base case
    if (n == 1)
       return 0;
    if (memo[n] != -1)
       return memo[n];
  
    // store temp value for n as min( f(n-1),
    // f(n/2), f(n/3)) +1
    int res = getMinSteps(n-1, memo);
  
    if (n%2 == 0)
        res = min(res, getMinSteps(n/2, memo));
    if (n%3 == 0)
        res = min(res, getMinSteps(n/3, memo));
  
    // store memo[n] and return

2063
Chapter 282. Minimum steps to minimize n as per given condition

    memo[n] = 1 + res;
    return memo[n];
}
  
// This function mainly initializes memo[] and
// calls getMinSteps(n, memo)
int getMinSteps(int n)
{
    int memo[n+1];
  
    // initialize memoized array
    for (int i=0; i<=n; i++)
        memo[i] = -1;
  
    return  getMinSteps(n, memo);
}
  
// driver program
int main()
{
    int n = 10;
    cout << getMinSteps(n);
    return 0;
}

Java

// Java program to minimize n to 1 


// by given rule in minimum steps
import java.io.*;
class GFG {
  
// function to calculate min steps
static int getMinSteps(int n, int memo[])
{
    // base case
    if (n == 1)
    return 0;
    if (memo[n] != -1)
    return memo[n];
  
    // store temp value for
    // n as min( f(n-1),
    // f(n/2), f(n/3)) +1
    int res = getMinSteps(n - 1, memo);
  
    if (n % 2 == 0)
        res = Math.min(res, 

2064
Chapter 282. Minimum steps to minimize n as per given condition

              getMinSteps(n / 2, memo));
    if (n % 3 == 0)
        res = Math.min(res, 
               getMinSteps(n / 3, memo));
  
    // store memo[n] and return
    memo[n] = 1 + res;
    return memo[n];
}
  
// This function mainly
// initializes memo[] and
// calls getMinSteps(n, memo)
static int getMinSteps(int n)
{
    int memo[] = new int[n + 1];
  
    // initialize memoized array
    for (int i = 0; i <= n; i++)
        memo[i] = -1;
  
    return getMinSteps(n, memo);
}
  
    // Driver Code
    public static void main (String[] args) 
    {
        int n = 10;
        System.out.println(getMinSteps(n));
    }
}
  
// This code is contributed by anuj_67.

Python3

# Python program to minimize


# n to 1 by given
# rule in minimum steps
  
# function to calculate min steps
def getMinSteps(n, memo):
  
    # base case
    if (n == 1):
        return 0
    if (memo[n] != -1):
        return memo[n]

2065
Chapter 282. Minimum steps to minimize n as per given condition

  
    # store temp value for n as min(f(n-1),
    # f(n//2), f(n//3)) + 1
    res = getMinSteps(n-1, memo)
  
    if (n%2 == 0):
        res = min(res, getMinSteps(n//2, memo))
    if (n%3 == 0):
        res = min(res, getMinSteps(n//3, memo))
  
    # store memo[n] and return
    memo[n] = 1 + res
    return memo[n]
  
# This function mainly
# initializes memo[] and
# calls getMinSteps(n, memo)
def getsMinSteps(n):
  
    memo = [0 for i in range(n+1)]
  
    # initialize memoized array
    for i in range(n+1):
        memo[i] = -1
  
    return getMinSteps(n, memo)
  
# driver program
n = 10
print(getsMinSteps(n))
  
# This code is contributed by Soumen Ghosh.   

C#

// C# program to minimize n to 1 
// by given rule in minimum steps
using System;
  
class GFG {
  
    // function to calculate min steps
    static int getMinSteps(int n, int []memo)
    {
        // base case
        if (n == 1)
            return 0;
        if (memo[n] != -1)

2066
Chapter 282. Minimum steps to minimize n as per given condition

            return memo[n];
      
        // store temp value for
        // n as min( f(n-1),
        // f(n/2), f(n/3)) +1
        int res = getMinSteps(n - 1, memo);
      
        if (n % 2 == 0)
            res = Math.Min(res, 
                getMinSteps(n / 2, memo));
        if (n % 3 == 0)
            res = Math.Min(res, 
                getMinSteps(n / 3, memo));
      
        // store memo[n] and return
        memo[n] = 1 + res;
          
        return memo[n];
    }
      
    // This function mainly
    // initializes memo[] and
    // calls getMinSteps(n, memo)
    static int getMinSteps(int n)
    {
        int []memo = new int[n + 1];
      
        // initialize memoized array
        for (int i = 0; i <= n; i++)
            memo[i] = -1;
      
        return getMinSteps(n, memo);
    }
  
    // Driver Code
    public static void Main () 
    {
        int n = 10;
        Console.WriteLine(getMinSteps(n));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to minimize n to 1 by

2067
Chapter 282. Minimum steps to minimize n as per given condition

// given rule in minimum steps


  
// function to calculate min steps
function getMinSteps( $n, $memo)
{
      
    // base case
    if ($n == 1)
        return 0;
          
    if ($memo[$n] != -1)
        return $memo[$n];
  
    // store temp value for n
    // as min( f(n-1),
    // f(n/2), f(n/3)) +1
    $res = getMinSteps($n - 1, $memo);
  
    if ($n % 2 == 0)
        $res = min($res, getMinSteps($n / 2, $memo));
    if ($n % 3 == 0)
        $res = min($res, getMinSteps($n / 3, $memo));
  
    // store memo[n] and return
    $memo[$n] = 1 + $res;
    return $memo[$n];
}
  
// This function mainly initializes
// memo[] and calls getMinSteps(n, memo)
function g_etMinSteps( $n)
{
    $memo= array();
  
    // initialize memoized array
    for($i = 0; $i <= $n; $i++)
        $memo[$i] = -1;
  
    return getMinSteps($n, $memo);
}
  
    // Driver Code
    $n = 10;
    echo g_etMinSteps($n);
  
// This code is contributed by anuj_67.
?>

2068
Chapter 282. Minimum steps to minimize n as per given condition

Output:

Below is a tabulation based solution :

C++

// A tabulation based solution in C++


#include <bits/stdc++.h>
using namespace std;
   
int getMinSteps(int n)
{
    int table[n+1];
    for (int i=0; i<=n; i++)
        table[i] = n-i;
    for (int i=n; i>=1; i--)
    {
       if (!(i%2))
          table[i/2] = min(table[i]+1, table[i/2]);
       if (!(i%3))
          table[i/3] = min(table[i]+1, table[i/3]);
    }
    return table[1];
}
   
// driver program
int main()
{
    int n = 10;
    cout << getMinSteps(n);
    return 0;
}
// This code is contributed by Jaydeep Rathore

Java

// A tabulation based 
// solution in Java
import java.io.*;
  
class GFG 
{
static int getMinSteps(int n)

2069
Chapter 282. Minimum steps to minimize n as per given condition

{
    int table[] = new int[n + 1];
    for (int i = 0; i <= n; i++)
        table[i] = n - i;
    for (int i = n; i >= 1; i--)
    {
    if (!(i % 2 > 0))
        table[i / 2] = Math.min(table[i] + 1, 
                                table[i / 2]);
    if (!(i % 3 > 0))
        table[i / 3] = Math.min(table[i] + 1, 
                                table[i / 3]);
    }
    return table[1];
}
  
// Driver Code
public static void main (String[] args)
{
    int n = 10;
    System.out.print(getMinSteps(n));
}
}
  
// This code is contributed 
// by anuj_67.

C#

// A tabulation based 
// solution in C#
using System;
  
class GFG 
{
static int getMinSteps(int n)
{
    int []table = new int[n + 1];
    for (int i = 0; i <= n; i++)
        table[i] = n - i;
    for (int i = n; i >= 1; i--)
    {
    if (!(i % 2 > 0))
        table[i / 2] = Math.Min(table[i] + 1, 
                                table[i / 2]);
    if (!(i % 3 > 0))
        table[i / 3] = Math.Min(table[i] + 1, 
                                table[i / 3]);

2070
Chapter 282. Minimum steps to minimize n as per given condition

    }
    return table[1];
}
  
// Driver Code
public static void Main ()
{
    int n = 10;
    Console.WriteLine(getMinSteps(n));
}
}
  
// This code is contributed 
// by anuj_67.

PHP

<?php
// A tabulation based solution in PHP
  
function getMinSteps( $n)
{
    $table = array();
    for ($i = 0; $i <= $n; $i++)
        $table[$i] = $n - $i;
    for ($i = $n; $i >= 1; $i--)
    {
        if (!($i % 2))
            $table[$i / 2] = min($table[$i] + 
                          1, $table[$i / 2]);
        if (!($i % 3))
            $table[$i / 3] = min($table[$i] + 
                          1, $table[$i / 3]);
    }
    return $table[1];
}
  
    // Driver Code
    $n = 10;
    echo getMinSteps($n);
  
// This code is contributed by anuj_67.
?>

Output:

2071
Chapter 282. Minimum steps to minimize n as per given condition

Improved By : vt_m

Source

https://www.geeksforgeeks.org/minimum-steps-minimize-n-per-given-condition/

2072
Chapter 283

Minimum steps to reach a


destination

Minimum steps to reach a destination - GeeksforGeeks


Given a number line from -infinity to +infinity. You start at 0 and can go either to the left
or to the right. The condition is that in i’th move, you take i steps.
a) Find if you can reach a given number x
b) Find the most optimal way to reach a given number x, if we can indeed reach it. For
example, 3 can be reached in 2 steps, (0, 1) (1, 3) and 4 can be reached in 3 steps (0, -1),
(-1, 1) (1, 4).
Source: Flipkart Interview Question
The important think to note is we can reach any destination as it is always possible to make
a move of length 1. At any step i, we can move forward i, then backward i + 1.
Below is a recursive solution suggested by Arpit Thapar here.
1) Since distance of + 5 and – 5 from 0 is same, hence we find answer for absolute value of
destination.
2) We use a recursive function which takes as arguments:
i) Source Vertex
ii) Value of last step taken
iii) Destination
3) If at any point source vertex = destination; return number of steps.
4) Otherwise we can go in both of the possible directions. Take the minimum of steps in
both cases.
From any vertex we can go to :
(current source + last step +1) and
(current source – last step -1)
5) If at any point, absolute value of our position exceeds the absolute value of our destination
then it is intuitive that the shortest path is not possible from here. Hence we make the value

2073
Chapter 283. Minimum steps to reach a destination

of steps INT_MAX, so that when i take the minimum of both possibilities, this one gets
eliminated.
If we don’t use this last step, the program enters into an INFINITE recursion and gives
RUN TIME ERROR.
Below is the implementation of above idea. Note that the solution only counts steps.

C++

// C++ program to count number of 


// steps to reach a point
#include<bits/stdc++.h>
using namespace std;
  
// Function to count number of steps 
// required to reach a destination
  
// source -> source vertex
// step -> value of last step taken
// dest -> destination vertex
int steps(int source, int step, int dest)
{
    // base cases
    if (abs(source) > (dest)) 
         return INT_MAX;
    if (source == dest) return step;
  
    // at each point we can go either way
  
    // if we go on positive side
    int pos = steps(source + step + 1, 
                      step + 1, dest);
  
    // if we go on negative side
    int neg = steps(source - step - 1,
                      step + 1, dest);
  
    // minimum of both cases
    return min(pos, neg);
}
  
// Driver code
int main()
{
    int dest = 11;
    cout << "No. of steps required to reach "
                            << dest << " is " 
                        << steps(0, 0, dest);

2074
Chapter 283. Minimum steps to reach a destination

    return 0;
}

Java

// Java program to count number of


// steps to reach a point
import java.io.*;
  
class GFG 
{
  
    // Function to count number of steps
    // required to reach a destination
      
    // source -> source vertex
    // step -> value of last step taken
    // dest -> destination vertex
    static int steps(int source, int step,
                                int dest)
    {
        // base cases
        if (Math.abs(source) > (dest)) 
            return Integer.MAX_VALUE;
      
        if (source == dest) 
            return step;
  
        // at each point we can go either way
  
        // if we go on positive side
        int pos = steps(source + step + 1,
                        step + 1, dest);
  
        // if we go on negative side
        int neg = steps(source - step - 1, 
                        step + 1, dest);
  
        // minimum of both cases
        return Math.min(pos, neg);
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        int dest = 11;
        System.out.println("No. of steps required"+
                                " to reach " + dest +

2075
Chapter 283. Minimum steps to reach a destination

                       " is " + steps(0, 0, dest));


    }
}
  
// This code is contributed by Prerna Saini

Python3

# python program to count number of


# steps to reach a point
import sys
  
# Function to count number of steps
# required to reach a destination
      
# source -> source vertex
# step -> value of last step taken
# dest -> destination vertex
def steps(source, step, dest):
      
    #base cases
    if (abs(source) > (dest)) :
        return sys.maxsize 
      
    if (source == dest):
        return step
  
    # at each point we can go 
    # either way
  
    # if we go on positive side
    pos = steps(source + step + 1,
                    step + 1, dest)
  
    # if we go on negative side
    neg = steps(source - step - 1, 
                    step + 1, dest)
  
    # minimum of both cases
    return min(pos, neg)
      
  
# Driver Code
dest = 11;
print("No. of steps required",
               " to reach " ,dest , 
        " is " , steps(0, 0, dest));
      

2076
Chapter 283. Minimum steps to reach a destination

  
# This code is contributed by Sam007.

C#

// C# program to count number of


// steps to reach a point
using System;
  
class GFG 
{
    // Function to count number of steps
    // required to reach a destination
      
    // source -> source vertex
    // step -> value of last step taken
    // dest -> destination vertex
    static int steps(int source, int step,
                                int dest)
    {
        // base cases
        if (Math.Abs(source) > (dest)) 
            return int.MaxValue;
      
        if (source == dest)     
            return step;
  
        // at each point we can go either way
  
        // if we go on positive side
        int pos = steps(source + step + 1,
                        step + 1, dest);
  
        // if we go on negative side
        int neg = steps(source - step - 1, 
                        step + 1, dest);
  
        // minimum of both cases
        return Math.Min(pos, neg);
    }
  
    // Driver Code
    public static void Main()
    {
        int dest = 11;
        Console.WriteLine("No. of steps required"+
                             " to reach " + dest + 
                      " is " + steps(0, 0, dest));

2077
Chapter 283. Minimum steps to reach a destination

    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program to count number 
// of steps to reach a point
  
// Function to count number 
// of steps required to reach 
// a destination
  
// source -> source vertex
// step -> value of last step taken
// dest -> destination vertex
function steps($source, $step, $dest)
{
    // base cases
    if (abs($source) > ($dest)) 
        return PHP_INT_MAX;
    if ($source == $dest) 
        return $step;
  
    // at each point we 
    // can go either way
  
    // if we go on positive side
    $pos = steps($source + $step + 1, 
                   $step + 1, $dest);
  
    // if we go on negative side
    $neg = steps($source - $step - 1,
                   $step + 1, $dest);
  
    // minimum of both cases
    return min($pos, $neg);
}
  
// Driver code
$dest = 11;
echo "No. of steps required to reach ",
     $dest, " is ", steps(0, 0, $dest);
  
// This code is contributed by aj_36
?>

2078
Chapter 283. Minimum steps to reach a destination

Output :

No. of steps required to reach 11 is 5

Thanks to Arpit Thapar for providing above algorithm and implementation.


Optimized Solution : Find minimum moves to reach target on an infinite line
This article is contributed by Abhay. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above.
Improved By : Sam007, jit_t

Source

https://www.geeksforgeeks.org/minimum-steps-to-reach-a-destination/

2079
Chapter 284

Minimum steps to reach target


by a Knight | Set 2

Minimum steps to reach target by a Knight | Set 2 - GeeksforGeeks


Given a square chessboard of N x N size, the position of Knight and position of a target
is given, the task is to find out the minimum steps a Knight will take to reach the target
position.

Examples :

Input : (2, 4) - knight's position, (6, 4) - target cell


Output : 2

Input : (4, 5) (1, 1)


Output : 3

2080
Chapter 284. Minimum steps to reach target by a Knight | Set 2

A BFS approach to solve the above problem has already been discussed in the previous post.
In this a post, a Dynamic Programming solution is discussed.
Explanation of the approach :

• Case 1 : If target is not along one row or one column of knight’s position.
Let a chess board of 8 x 8 cell. Now, let say knight is at (3, 3) and the target is at
(7, 8). There are possible 8 moves from the current position of knight i.e. (2, 1), (1,
2), (4, 1), (1, 4), (5, 2), (2, 5), (5, 4), (4, 5). But, among these only two moves (5,
4) and (4, 5) will be towards the target and all other goes away from the target. So,
for finding minimum steps go to either (4, 5) or (5, 4). Now, calculate the minimum
steps taken from (4, 5) and (5, 4) to reach the target. This is calculated by dynamic
programming. Thus, this results in the minimum steps from (3, 3) to (7, 8).
• Case 2 : If the target is along one row or one column of knight’s position.
Let a chess board of 8 x 8 cell. Now, let’s say knight is at (4, 3) and the target is at
(4, 7). There are possible 8 moves but towards the target, there are only 4 moves i.e.
(5, 5), (3, 5), (2, 4), (6, 4). As, (5, 5) is equivalent to (3, 5) and (2, 4) is equivalent
to (6, 4). So, from these 4 points, it can be converted into 2 points. Taking (5, 5)
and (6, 4) (here). Now, calculate the minimum steps taken from these two points to
reach the target. This is calculated by dynamic programming. Thus, this results in
the minimum steps from (4, 3) to (4, 7).

Exception : When the knight will be at corner and the target is such that the difference
of x and y coordinates with knight’s position is (1, 1) or vice-versa. Then minimum steps
will be 4.
Dynamic Programming Equation :

1) dp[diffOfX][diffOfY] is the minimum steps taken from knight’s position to


target’s position.
2) dp[diffOfX][diffOfY] = dp[diffOfY][diffOfX].
where, diffOfX = difference between knight’s x-coordinate and target’s x-
coordinate
diffOfY = difference between knight’s y-coordinate and target’s y-coordinate

Below is the implementation of above approach:

// C++ code for minimum steps for


// a knight to reach target position
#include <bits/stdc++.h>
  
using namespace std;
  
// initializing the matrix.
int dp[8][8] = { 0 };
  
int getsteps(int x, int y, 

2081
Chapter 284. Minimum steps to reach target by a Knight | Set 2

             int tx, int ty)


{
    // if knight is on the target 
    // position return 0.
    if (x == tx && y == ty)
        return dp[0][0];
    else {
          
        // if already calculated then return
        // that value. Taking absolute difference.
        if (dp[abs(x - tx)][abs(y - ty)] != 0)
            return dp[abs(x - tx)][abs(y - ty)];
              
        else {
  
            // there will be two distinct positions
            // from the knight towards a target.
            // if the target is in same row or column
            // as of knight than there can be four
            // positions towards the target but in that
            // two would be the same and the other two
            // would be the same.
            int x1, y1, x2, y2;
              
            // (x1, y1) and (x2, y2) are two positions.
            // these can be different according to situation.
            // From position of knight, the chess board can be
            // divided into four blocks i.e.. N-E, E-S, S-W, W-N .
            if (x <= tx) {
                if (y <= ty) {
                    x1 = x + 2;
                    y1 = y + 1;
                    x2 = x + 1;
                    y2 = y + 2;
                } else {
                    x1 = x + 2;
                    y1 = y - 1;
                    x2 = x + 1;
                    y2 = y - 2;
                }
            } else {
                if (y <= ty) {
                    x1 = x - 2;
                    y1 = y + 1;
                    x2 = x - 1;
                    y2 = y + 2;
                } else {
                    x1 = x - 2;

2082
Chapter 284. Minimum steps to reach target by a Knight | Set 2

                    y1 = y - 1;
                    x2 = x - 1;
                    y2 = y - 2;
                }
            }
              
            // ans will be, 1 + minimum of steps 
            // required from (x1, y1) and (x2, y2).
            dp[abs(x - tx)][abs(y - ty)] = 
                           min(getsteps(x1, y1, tx, ty), 
                           getsteps(x2, y2, tx, ty)) + 1;
                             
            // exchanging the coordinates x with y of both
            // knight and target will result in same ans.
            dp[abs(y - ty)][abs(x - tx)] = 
                           dp[abs(x - tx)][abs(y - ty)];
            return dp[abs(x - tx)][abs(y - ty)];
        }
    }
}
  
// Driver Code
int main()
{
    int i, n, x, y, tx, ty, ans;
      
    // size of chess board n*n
    n = 100;
      
    // (x, y) coordinate of the knight.
    // (tx, ty) coordinate of the target position.
    x = 4;
    y = 5;
    tx = 1;
    ty = 1;
  
    // (Exception) these are the four corner points 
    // for which the minimum steps is 4.
    if ((x == 1 && y == 1 && tx == 2 && ty == 2) || 
        (x == 2 && y == 2 && tx == 1 && ty == 1))
            ans = 4;
    else if ((x == 1 && y == n && tx == 2 && ty == n - 1) ||
             (x == 2 && y == n - 1 && tx == 1 && ty == n))
                ans = 4;
    else if ((x == n && y == 1 && tx == n - 1 && ty == 2) || 
             (x == n - 1 && y == 2 && tx == n && ty == 1))
                ans = 4;
    else if ((x == n && y == n && tx == n - 1 && ty == n - 1) || 

2083
Chapter 284. Minimum steps to reach target by a Knight | Set 2

             (x == n - 1 && y == n - 1 && tx == n && ty == n))


                ans = 4;
    else {
        // dp[a][b], here a, b is the difference of
        // x & tx and y & ty respectively.
        dp[1][0] = 3;
        dp[0][1] = 3;
        dp[1][1] = 2;
        dp[2][0] = 2;
        dp[0][2] = 2;
        dp[2][1] = 1;
        dp[1][2] = 1;
  
        ans = getsteps(x, y, tx, ty);
    }
  
    cout << ans << endl;
  
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/minimum-steps-reach-target-knight-set-2/

2084
Chapter 285

Minimum sum of
multiplications of n numbers

Minimum sum of multiplications of n numbers - GeeksforGeeks


Given n integers. The task is to minimize the sum of multiplication of all the numbers by
taking two adjacent numbers at a time and putting back their sum % 100 till a number is
left.
Examples :

Input : 40 60 20
Output : 2400
Explanation: There are two possible cases:
1st possibility: Take 40 and 60, so multiplication=2400
and put back (60+40) % 100 = 0, making it 0, 20.
Multiplying 0 and 20 we get 0 so
multiplication = 2400+0 = 2400. Put back (0+20)%100 = 20.
2nd possibility: take 60 and 20, so 60*20 = 1200,
put back (60+20)%100 = 80, making it [40, 80]
multiply 40*80 to get 3200, so multiplication
sum = 1200+3200 = 4400. Put back (40+80)%100 = 20

Input : 5 6
Output : 30
Explanation: Only possibility is 5*6=30

Approach: The problem is a variation of Matrix chain Multiplication Dynamic Program-


ming
The idea is to partition N numbers into every possible value of k. Solve recursively for smaller
parts and add the multiplication and store the minimum of them. Since we are dividing it

2085
Chapter 285. Minimum sum of multiplications of n numbers

into k parts, for every DPi,j we will have k partitions i<=k<j , store the minimum of them.
So we get the formula similar to Matrix chain Multiplication Dynamic Programming.

DPi,j = min(DPi,j , (DPi,k +DPk+1,j +(cumulative_sumi,k *cumulative_sumk+1,j )


))
for every i<=k<j.

Since many subproblems will be repeating, hence we use memoization to store the values in
a nXn matrix.
Given below is the illustration of the above approach:

C++

// CPP program to find the 


// minimum sum of multiplication
// of n numbers
#include <bits/stdc++.h>
using namespace std;
  
// Used in recursive 
// memoized solution
long long dp[1000][1000];
  
// function to calculate the cumulative 
// sum from a[i] to a[j]
long long sum(int a[], int i, int j)
{     
    long long ans = 0;
    for (int m = i; m <= j; m++)     
        ans = (ans + a[m]) % 100;
    return ans;
}
  
long long solve(int a[], int i, int j)
{
    // base case 
    if (i == j)
        return 0; 
      
    // memoization, if the partition 
    // has been called before then 
    // return the stored value 
    if (dp[i][j] != -1)
        return dp[i][j];
      
    // store a max value 

2086
Chapter 285. Minimum sum of multiplications of n numbers

    dp[i][j] = INT_MAX;
      
    // we break them into k partitions 
    for (int k = i; k < j; k++)
    {
        // store the min of the 
        // formula thus obtained
        dp[i][j] = min(dp[i][j], (solve(a, i, k) +
                              solve(a, k + 1, j) + 
              (sum(a, i, k) * sum(a, k + 1, j))));
    }
      
    // return the minimum 
    return dp[i][j];
}
  
void intialize(int n)
{
    for (int i = 0; i <= n; i++) 
        for (int j = 0; j <= n; j++)
            dp[i][j] = -1;     
}
  
// Driver code 
int main() {
    int a[] = {40, 60, 20}; 
    int n = sizeof(a) / sizeof(a[0]);
    intialize(n);
    cout << solve(a, 0, n - 1) << endl;
    return 0;
}

Java

// Java program to find the  


// minimum sum of multiplication
// of n numbers
import java.io.*;
import java.math.*;
  
  
class GFG
{
      
    // Used in recursive
    // memoized solution
    static long dp[][] = new long[1000][1000];
      

2087
Chapter 285. Minimum sum of multiplications of n numbers

    // function to calculate the 


    // cumulative  sum from a[i] to a[j]
    static long sum(int a[], int i, int j)
    {     
        long ans = 0;
        for (int m = i; m <= j; m++)     
            ans = (ans + a[m]) % 100;
        return ans;
    }
      
    static long solve(int a[], int i, int j)
    {
        // base case 
        if (i == j)
            return 0; 
          
        // memoization, if the partition 
        // has been called before then 
        // return the stored value 
        if (dp[i][j] != -1)
            return dp[i][j];
          
        // store a max value 
        dp[i][j] = 100000000;
          
        // we break them into k partitions 
        for (int k = i; k < j; k++)
        {
            // store the min of the
            // formula thus obtained
            dp[i][j] = Math.min(dp[i][j], (solve(a, i, k) +
                                       solve(a, k + 1, j) + 
                        (sum(a, i, k) * sum(a, k + 1,j))));
        }
          
        // return the minimum 
        return dp[i][j];
    }
      
    static void intialize(int n)
    {
        for (int i = 0; i <= n; i++) 
            for (int j = 0; j <= n; j++)
                dp[i][j] = -1;     
    }
      
    // Driver code 
    public static void main(String args[]) 

2088
Chapter 285. Minimum sum of multiplications of n numbers

    {
        int a[] = {40, 60, 20}; 
        int n = a.length;
        intialize(n);
        System.out.println(solve(a, 0, n - 1));
          
    }
}
  
/*This code is contributed by Nikita Tiwari.*/

C#

// C# program to find the 


// minimum sum of multiplication 
// of n numbers
using System;
  
class GFG 
{
      
    // Used in recursive 
    // memoized solution
    static long [,]dp = new long[1000, 1000];
      
    // Function to calculate the cumulative 
    // sum from a[i] to a[j]
    static long sum(int []a, int i, int j)
    { 
        long ans = 0;
        for (int m = i; m <= j; m++) 
            ans = (ans + a[m]) % 100;
        return ans;
    }
      
    static long solve(int []a, int i, int j)
    {
        // base case 
        if (i == j)
            return 0; 
          
        // memoization, if the partition 
        // has been called before then 
        // return the stored value 
        if (dp[i, j] != -1)
            return dp[i, j];
          
        // store a max value 

2089
Chapter 285. Minimum sum of multiplications of n numbers

        dp[i, j] = 100000000;
          
        // we break them into k partitions 
        for (int k = i; k < j; k++)
        {
            // store the min of the 
            // formula thus obtained
            dp[i, j] = Math.Min(dp[i, j], (solve(a, i, k) +
                                       solve(a, k + 1, j) + 
                       (sum(a, i, k) * sum(a, k + 1, j))));
        }
          
        // return the minimum 
        return dp[i, j];
    }
      
    static void intialize(int n)
    {
        for (int i = 0; i <= n; i++) 
            for (int j = 0; j <= n; j++)
                dp[i, j] = -1; 
    }
      
    // Driver code 
    public static void Main() 
    {
        int []a = {40, 60, 20}; 
        int n = a.Length;
        intialize(n);
        Console.WriteLine(solve(a, 0, n - 1));
          
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to find the 
// minimum sum of multiplication 
// of n numbers
  
  
// Used in recursive
// memoized solution
$dp = array(array());
  

2090
Chapter 285. Minimum sum of multiplications of n numbers

// function to calculate the 


// cumulative sum from a[i] to a[j]
function sum( $a, $i, $j)

    $ans = 0;
    for ( $m = $i; $m <= $j; $m++) 
        $ans = ($ans + $a[$m]) % 100;
    return $ans;
}
  
function solve( $a, $i, $j)
{
    global $dp;
    // base case 
    if ($i == $j)
        return 0; 
      
    // memoization, if the partition
    // has been  called before then
    // return the stored value 
    if ($dp[$i][$j] != -1)
        return $dp[$i][$j];
      
    // store a max value 
    $dp[$i][$j] = PHP_INT_MAX;
      
    // we break them into
    // k partitions 
    for ( $k = $i; $k < $j; $k++)
    {
        // store the min of the
        // formula thus obtained
        $dp[$i][$j] = min($dp[$i][$j], 
                      (solve($a, $i, $k) +
                       solve($a, $k + 1, $j) + 
                      (sum($a, $i, $k) * 
                       sum($a, $k + 1, $j))));
    }
      
    // return the minimum 
    return $dp[$i][$j];
}
  
function intialize( $n)
{
    global $dp;
    for ( $i = 0; $i <= $n; $i++) 
        for ( $j = 0; $j <= $n; $j++)

2091
Chapter 285. Minimum sum of multiplications of n numbers

            $dp[$i][$j] = -1; 
}
  
// Driver code 
$a = array(40, 60, 20); 
$n = count($a);
intialize($n);
echo solve($a, 0, $n - 1) ;
  
// This code is contributed by anuj_67.
?>

Output :

2400

Time Complexity: O(n^3)


Auxiliary Space: O(n^2)
Improved By : vt_m

Source

https://www.geeksforgeeks.org/minimum-sum-of-multiplications-of-n-numbers/

2092
Chapter 286

Minimum sum submatrix in a


given 2D array

Minimum sum submatrix in a given 2D array - GeeksforGeeks


Given a 2D array, find the minimum sum submatrix in it.
Examples:

Input : M[][] = {{1, 2, -1, -4, -20},


{-8, -3, 4, 2, 1},
{3, 8, 10, 1, 3},
{-4, -1, 1, 7, -6}}
Output : -26
Submatrix starting from (Top, Left): (0, 0)
and ending at (Bottom, Right): (1, 4) indexes.
The elements are of the submtrix are:
{ {1, 2, -1, -4, -20},
{-8, -3, 4, 2, 1} } having sum = -26

Method 1 (Naive Approach): Check every possible submatrix in given 2D array. This
solution requires 4 nested loops and time complexity of this solution would be O(n^4).
Method 2 (Efficient Approach): Kadane’s algorithm for 1D array can be used to
reduce the time complexity to O(n^3). The idea is to fix the left and right columns one by
one and find the minimum sum contiguous rows for every left and right column pair. We
basically find top and bottom row numbers (which have minimum sum) for every fixed left
and right column pair. To find the top and bottom row numbers, calculate sun of elements in
every row from left to right and store these sums in an array say temp[]. So temp[i] indicates
sum of elements from left to right in row i. If we apply Kadane’s 1D algorithm on temp[],
and get the minimum sum subarray of temp, this minimum sum would be the minimum
possible sum with left and right as boundary columns. To get the overall minimum sum,
we compare this sum with the minimum sum so far.

2093
Chapter 286. Minimum sum submatrix in a given 2D array

// C++ implementation to find minimum sum 


// submatrix in a given 2D array
#include <bits/stdc++.h>
using namespace std;
  
#define ROW 4
#define COL 5
  
// Implementation of Kadane's algorithm for 
// 1D array. The function returns the miniimum 
// sum and stores starting and ending indexes
// of the minimum sum subarray at addresses
// pointed by start and finish pointers
// respectively.
int kadane(int* arr, int* start, int* finish,
                                       int n)
{
    // initialize sum, maxSum and
    int sum = 0, minSum = INT_MAX, i;
  
    // Just some initial value to check for 
    // all negative values case
    *finish = -1;
  
    // local variable
    int local_start = 0;
  
    for (i = 0; i < n; ++i) {
        sum += arr[i];
        if (sum > 0) {
            sum = 0;
            local_start = i + 1;
        } else if (sum < minSum) {
            minSum = sum;
            *start = local_start;
            *finish = i;
        }
    }
  
    // There is at-least one non-negative number
    if (*finish != -1)
        return minSum;
  
    // Special Case: When all numbers in arr[]
    // are positive
    minSum = arr[0];
    *start = *finish = 0;
  

2094
Chapter 286. Minimum sum submatrix in a given 2D array

    // Find the minimum element in array


    for (i = 1; i < n; i++) {
        if (arr[i] < minSum) {
            minSum = arr[i];
            *start = *finish = i;
        }
    }
    return minSum;
}
  
// function to find minimum sum submatrix
// in a given 2D array
void findMinSumSubmatrix(int M[][COL])
{
    // Variables to store the final output
    int minSum = INT_MAX, finalLeft, finalRight, 
                          finalTop, finalBottom;
  
    int left, right, i;
    int temp[ROW], sum, start, finish;
  
    // Set the left column
    for (left = 0; left < COL; ++left) {
  
        // Initialize all elements of temp as 0
        memset(temp, 0, sizeof(temp));
  
        // Set the right column for the left 
        // column set by outer loop
        for (right = left; right < COL; ++right) {
  
            // Calculate sum between current left
            // and right for every row 'i'
            for (i = 0; i < ROW; ++i)
                temp[i] += M[i][right];
  
            // Find the minimum sum subarray in temp[]. 
            // The kadane() function also sets values 
            // of start and finish.  So 'sum' is sum of
            // rectangle between (start, left) and
            // (finish, right) which is the minimum sum
            // with boundary columns strictly as
            // left and right.
            sum = kadane(temp, &start, &finish, ROW);
  
            // Compare sum with maximum sum so far. If 
            // sum is more, then update maxSum and other 
            // output values

2095
Chapter 286. Minimum sum submatrix in a given 2D array

            if (sum < minSum) {


                minSum = sum;
                finalLeft = left;
                finalRight = right;
                finalTop = start;
                finalBottom = finish;
            }
        }
    }
  
    // Print final values
    cout << "(Top, Left): (" << finalTop << ", " 
            << finalLeft << ")\n";
    cout << "(Bottom, Right): (" << finalBottom << ", " 
         << finalRight << ")\n";
    cout << "Minimum sum: " << minSum;
}
  
// Driver program to test above
int main()
{
    int M[ROW][COL] = { { 1, 2, -1, -4, -20 },
                        { -8, -3, 4, 2, 1 },
                        { 3, 8, 10, 1, 3 },
                        { -4, -1, 1, 7, -6 } };
    findMinSumSubmatrix(M);
    return 0;
}

Output:

(Top, Left): (0, 0)


(Bottom, Right): (1, 4)
Minimum sum: -26

Time Complexity: O(n^3)

Source

https://www.geeksforgeeks.org/minimum-sum-submatrix-given-2d-array/

2096
Chapter 287

Minimum sum subsequence such


that at least one of every four
consecutive elements is picked

Minimum sum subsequence such that at least one of every four consecutive elements is
picked - GeeksforGeeks
Given an array arr[] of positive integers. The task is to find minimum sum subsequence
from the array such that at least one value among all groups of four consecutive elements
is picked.
Examples :

Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8}


Output: 6
6 is sum of output subsequence {1, 5}
Note that we have following subarrays of four
consecutive elements
{(1, 2, 3, 4),
(2, 3, 4, 5),
(3, 4, 5, 6)
(4, 5, 6, 7)
(5, 6, 7, 8)}
Our subsequence {1, 5} has an element from
all above groups of four consecutive elements.
And this subsequence is minimum sum such
subsequence.

Input : arr[] = {1, 2, 3, 3, 4, 5, 6, 1}


Output : 4
The subsequence is {3, 1}. Here we consider

2097
Chapter 287. Minimum sum subsequence such that at least one of every four consecutive
elements is picked

second three.

Input: arr[] = {1, 2, 3, 2, 1}


Output: 2
The subsequence can be {1, 1} or {2}

Input: arr[] = {6, 7, 8}


Output: 6

Input: arr[] = {6, 7}


Output: 6

The idea is similar to LIS problem. We store minimum sum subsequence ending with every
element of arr[]. We finally return minimum of last four values.

dp[i] stores minimum sum subsequence (with at least


one of every four consecutive elements) of arr[0..i]
such that arr[i] is part of the solution. Note that
this may not be the best solution for subarray
arr[0..i].

We can recursively compute dp[i] using below formula


dp[i] = arr[i] + min(dp[i-1], dp[i-2], dp[i-3], dp[i-4])

Finally we return minimum of dp[n-1], dp[n-2],


dp[n-4] and dp[n-3]

Below is the implementation of above idea.


C++

// C++ program to find minimum sum subsequence


// of an array such that one of every four
// consecutive elements is picked.
#include <iostream>
using namespace std;
  
// Returns sum of minimum sum subsequence
// such that one of every four consecutive
// elements is picked from arr[].
int minSum(int arr[], int n)
{
    // dp[i] is going to store minimum sum
    // subsequence of arr[0..i] such that arr[i]
    // is part of the solution. Note that this
    // may not be the best solution for subarray
    // arr[0..i]

2098
Chapter 287. Minimum sum subsequence such that at least one of every four consecutive
elements is picked

    int dp[n];
  
    // If there is single value, we get the
    // minimum sum equal to arr[0]
    if (n == 1)
        return arr[0];
  
    // If there are two values, we get the
    // minimum sum equal to the minimum of
    // two values
    if (n == 2)
        return min(arr[0], arr[1]);
  
    // If there are three values, return
    // minimum of the three elements of
    // array
    if (n == 3)
        return min(arr[0], min(arr[1], arr[2]));
  
    // If there are four values, return minimum
    // of the four elements of array
    if (n == 4)
        return min(min(arr[0], arr[1]),
                   min(arr[2], arr[3]));
  
    dp[0] = arr[0];
    dp[1] = arr[1];
    dp[2] = arr[2];
    dp[3] = arr[3];
  
    for (int i = 4; i < n; i++)
        dp[i] = arr[i] + min(min(dp[i - 1], dp[i - 2]),
                             min(dp[i - 3], dp[i - 4]));
  
    // Return the minimum of last 4 index
    return min(min(dp[n - 1], dp[n - 2]),
               min(dp[n - 4], dp[n - 3]));
}
  
// Driver code
int main()
{
    int arr[] = { 1, 2, 3, 3, 4, 5, 6, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << minSum(arr, n);
    return 0;
}

2099
Chapter 287. Minimum sum subsequence such that at least one of every four consecutive
elements is picked

Java

// Java program to find minimum sum subsequence


// of an array such that one of every four
// consecutive elements is picked.
import java.io.*;
  
class GFG {
  
    // Returns sum of minimum sum subsequence
    // such that one of every four consecutive
    // elements is picked from arr[].
    static int minSum(int[] arr, int n)
    {
        // dp[i] is going to store minimum sum
        // subsequence of arr[0..i] such that arr[i]
        // is part of the solution. Note that this
        // may not be the best solution for subarray
        // arr[0..i]
        int[] dp = new int[n];
  
        // If there is single value, we get the
        // minimum sum equal to arr[0]
        if (n == 1)
            return arr[0];
  
        // If there are two values, we get the
        // minimum sum equal to the minimum of
        // two values
        if (n == 2)
            return Math.min(arr[0], arr[1]);
  
        // If there are three values, return
        // minimum of the three elements of
        // array
        if (n == 3)
        return Math.min(arr[0], Math.min(arr[1], arr[2]));
  
        // If there are four values, return minimum
        // of the four elements of array
        if (n == 4)
            return Math.min(Math.min(arr[0], arr[1]),
                            Math.min(arr[2], arr[3]));
  
        dp[0] = arr[0];
        dp[1] = arr[1];
        dp[2] = arr[2];
        dp[3] = arr[3];

2100
Chapter 287. Minimum sum subsequence such that at least one of every four consecutive
elements is picked

  
        for (int i = 4; i < n; i++)
        dp[i] = arr[i] + Math.min(Math.min(dp[i - 1], dp[i - 2]),
                         Math.min(dp[i - 3], dp[i - 4]));
  
        // Return the minimum of last 4 index
        return Math.min(Math.min(dp[n - 1], dp[n - 2]),
                        Math.min(dp[n - 4], dp[n - 3]));
    }
  
    // Driver code
    static public void main(String[] args)
    {
        int[] arr = { 1, 2, 3, 3, 4, 5, 6, 1 };
        int n = arr.length;
        System.out.println(minSum(arr, n));
    }
}
  
// This Code is contributed by vt_m.

C#

// C# program to find minimum sum subsequence


// of an array such that one of every four
// consecutive elements is picked.
using System;
  
class GFG {
  
    // Returns sum of minimum sum subsequence
    // such that one of every four consecutive
    // elements is picked from arr[].
    static int minSum(int[] arr, int n)
    {
        // dp[i] is going to store minimum sum
        // subsequence of arr[0..i] such that arr[i]
        // is part of the solution. Note that this
        // may not be the best solution for subarray
        // arr[0..i]
        int[] dp = new int[n];
  
        // If there is single value, we get the
        // minimum sum equal to arr[0]
        if (n == 1)
            return arr[0];
  
        // If there are two values, we get the

2101
Chapter 287. Minimum sum subsequence such that at least one of every four consecutive
elements is picked

        // minimum sum equal to the minimum of


        // two values
        if (n == 2)
            return Math.Min(arr[0], arr[1]);
  
        // If there are three values, return
        // minimum of the three elements of
        // array
        if (n == 3)
            return Math.Min(arr[0], Math.Min(arr[1], arr[2]));
  
        // If there are four values, return minimum
        // of the four elements of array
        if (n == 4)
            return Math.Min(Math.Min(arr[0], arr[1]),
                            Math.Min(arr[2], arr[3]));
  
        dp[0] = arr[0];
        dp[1] = arr[1];
        dp[2] = arr[2];
        dp[3] = arr[3];
  
        for (int i = 4; i < n; i++)
            dp[i] = arr[i] + Math.Min(Math.Min(dp[i - 1], dp[i - 2]), 
                             Math.Min(dp[i - 3], dp[i - 4]));
  
        // Return the minimum of last 4 index
        return Math.Min(Math.Min(dp[n - 1], dp[n - 2]),
                        Math.Min(dp[n - 4], dp[n - 3]));
    }
  
    // Driver code
    static public void Main()
    {
        int[] arr = { 1, 2, 3, 3, 4, 5, 6, 1 };
        int n = arr.Length;
        Console.WriteLine(minSum(arr, n));
    }
}
  
// This code is contributed by vt_m.

Output:

Alternate Solution :

2102
Chapter 287. Minimum sum subsequence such that at least one of every four consecutive
elements is picked

First of all, think that we have only four elements then our result is at least four given
elements. Now, in the case if we have more than four elements then we must maintain an
array sum[] where sum[i] includes the possible minimal sum up to i-th element and also i-th
element must be a part of the solution.
While computing sum[i], our base condition is that arr[i] must be a part of sum[i] and then we
must have an element from last four elements. So, we can recursively compute sum[i] as sum
of arr[i] and minimum (sum[i-1], sum[i-2], sum[i-3], sum[i-4]). Since there are overlapping
sub problems in recursive structure of our problem, we can use Dynamic Programming to
solve this problem. And for final result we must compute minimum of last four values of
sum[] array as result must contain an element from last four elements.

// CPP program to calculate


// minimum possible sum  for given constraint
#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
  
// function to caluclate min sum using dp
int minSum(int ar[], int n)
{
    // if elements are less than or equal to 4
    if (n <= 4)
        return *min_element(ar, ar + n);
  
    // save start four element as it is
    int sum[n];
    sum[0] = ar[0];
    sum[1] = ar[1];
    sum[2] = ar[2];
    sum[3] = ar[3];
  
    // compute sum[] for all rest elements
    for (int i = 4; i < n; i++)
        sum[i] = ar[i] + (*min_element(sum + i - 4, sum + i));
  
    // Since one of the last 4 elements must be
    // present
    return *min_element(sum + n - 4, sum + n);
}
  
// driver program
int main()
{
    int ar[] = { 2, 4, 1, 5, 2, 3, 6, 1, 2, 4 };
    int n = sizeof(ar) / sizeof(ar[0]);
    cout << "Minimum sum = " << minSum(ar, n);
    return 0;
}

2103
Chapter 287. Minimum sum subsequence such that at least one of every four consecutive
elements is picked

Output:

Time Complexity : O(n).


Thanks to Shivam Pradhan (anuj_charm) for providing this alternate solution.
Improved By : vt_m

Source

https://www.geeksforgeeks.org/minimum-sum-subsequence-least-one-every-four-consecutive-elements-picked/

2104
Chapter 288

Minimum time to finish tasks


without skipping two
consecutive

Minimum time to finish tasks without skipping two consecutive - GeeksforGeeks


Given time taken by n tasks. Find the minimum time needed to finish the tasks such that
skipping of tasks is allowed, but can not skip two consecutive tasks.

Examples :

Input : arr[] = {10, 5, 7, 10}


Output : 12
We can skip first and last task and
finish these task in 12 min.

Input : arr[] = {10}


Output : 0
There is only one task and we can
skip it.

Input : arr[] = {10, 30}


Output : 10

Input : arr[] = {10, 5, 2, 4, 8, 6, 7, 10}


Output : 22

Expected Time Complexity is O(n) and extra space is O(1).


The given problem has the following recursive property.

2105
Chapter 288. Minimum time to finish tasks without skipping two consecutive

Let minTime(i) be minimum time to finish till i’th task. It can be written as minimum of
two values.

1. Minimum time if i’th task is included in list, let this time be incl(i)
2. Minimum time if i’th task is excluded from result, let this time be excl(i)

minTime(i) = min(excl(i), incl(i))

Result is minTime(n-1) if there are n tasks and indexes start from 0.


incl(i) can be written as below.

// There are two possibilities


// (a) Previous task is also included
// (b) Previous task is not included
incl(i) = min(incl(i-1), excl(i-1)) +
arr[i] // Since this is inclusive
// arr[i] must be included

excl(i) can be written as below.

// There is only one possibility (Previous task must be


// included as we can't skip consecutive tasks.
excl(i) = incl(i-1)

A simple solution is to make two tables incl[] and excl[] to store times for tasks. Finally
return minimum of incl[n-1] and excl[n-1]. This solution requires O(n) time and O(n) space.
If we take a closer look, we can notice that we only need incl and excl of previous job.
So we can save space and solve the problem in O(n) time and O(1) space. Below is C++
implementation of the idea.

C++

// C++ program to find minimum time to finish tasks


// such that no two consecutive tasks are skipped.
#include <bits/stdc++.h>
using namespace std;
  
// arr[] represents time taken by n given tasks
int minTime(int arr[], int n)
{

2106
Chapter 288. Minimum time to finish tasks without skipping two consecutive

    // Corner Cases


    if (n <= 0)
        return 0;
  
    // Initialize value for the case when there
    // is only one task in task list.
    int incl = arr[0];  // First task is included
    int excl = 0;       // First task is exluded
  
    // Process remaining n-1 tasks
    for (int i=1; i<n; i++)
    {
       // Time taken if current task is included
       // There are two possibilities
       // (a) Previous task is also included
       // (b) Previous task is not included
       int incl_new = arr[i] + min(excl, incl);
  
       // Time taken when current task is not
       // included.  There is only one possibility
       // that previous task is also included.
       int excl_new = incl;
  
       // Update incl and excl for next iteration
       incl = incl_new;
       excl = excl_new;
    }
  
    // Return maximum of two values for last task
    return min(incl, excl);
}
  
// Driver code
int main()
{
    int arr1[] = {10, 5, 2, 7, 10};
    int n1 = sizeof(arr1)/sizeof(arr1[0]);
    cout << minTime(arr1, n1) << endl;
  
    int arr2[] = {10, 5, 7, 10};
    int n2 = sizeof(arr2)/sizeof(arr2[0]);
    cout << minTime(arr2, n2) << endl;
  
    int arr3[] = {10, 5, 2, 4, 8, 6, 7, 10};
    int n3 = sizeof(arr3)/sizeof(arr3[0]);
    cout << minTime(arr3, n3) << endl;
  
    return 0;

2107
Chapter 288. Minimum time to finish tasks without skipping two consecutive

Java

// Java program to find minimum time to


// finish tasks such that no two
// consecutive tasks are skipped.
import java.io.*;
  
class GFG {
  
    // arr[] represents time taken by n
    // given tasks
    static int minTime(int arr[], int n)
    {
        // Corner Cases
        if (n <= 0)
            return 0;
  
        // Initialize value for the case
        // when there is only one task in 
        // task list.
        // First task is included
        int incl = arr[0];
          
        // First task is exluded
        int excl = 0;     
  
        // Process remaining n-1 tasks
        for (int i = 1; i < n; i++)
        {
        // Time taken if current task is
        // included. There are two 
        // possibilities
        // (a) Previous task is also included
        // (b) Previous task is not included
        int incl_new = arr[i] + Math.min(excl,
                                       incl);
  
        // Time taken when current task is not
        // included. There is only one 
        // possibility that previous task is 
        // also included.
        int excl_new = incl;
  
        // Update incl and excl for next
        // iteration
        incl = incl_new;

2108
Chapter 288. Minimum time to finish tasks without skipping two consecutive

        excl = excl_new;
        }
  
        // Return maximum of two values for 
        // last task
        return Math.min(incl, excl);
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int arr1[] = {10, 5, 2, 7, 10};
        int n1 = arr1.length;
        System.out.println(minTime(arr1, n1));
  
        int arr2[] = {10, 5, 7, 10};
        int n2 = arr2.length;
        System.out.println(minTime(arr2, n2));
  
        int arr3[] = {10, 5, 2, 4, 8, 6, 7, 10};
        int n3 = arr3.length;
        System.out.println(minTime(arr3, n3));
  
    }
}
// This code is contributed by Prerna Saini

Python3

   
# Python3 program to find minimum
# time to finish tasks such that no
# two consecutive tasks are skipped.
  
# arr[] represents time
# taken by n given tasks
def minTime(arr, n):
  
    # Corner Cases
    if (n <= 0): return 0
  
    # Initialize value for the 
    # case when there is only
    # one task in task list.
    incl = arr[0] # First task is included
    excl = 0      # First task is exluded
  
    # Process remaining n-1 tasks

2109
Chapter 288. Minimum time to finish tasks without skipping two consecutive

    for i in range(1, n):


      
        # Time taken if current task is included
        # There are two possibilities
        # (a) Previous task is also included
        # (b) Previous task is not included
        incl_new = arr[i] + min(excl, incl)
  
        # Time taken when current task is not
        # included. There is only one possibility
        # that previous task is also included.
        excl_new = incl
  
        # Update incl and excl for next iteration
        incl = incl_new
        excl = excl_new
      
  
    # Return maximum of two values for last task
    return min(incl, excl)
  
# Driver code
arr1 = [10, 5, 2, 7, 10]
n1 = len(arr1)
print(minTime(arr1, n1))
  
arr2 = [10, 5, 7, 10]
n2 = len(arr2)
print(minTime(arr2, n2))
  
arr3 = [10, 5, 2, 4, 8, 6, 7, 10]
n3 = len(arr3)
print(minTime(arr3, n3))
  
# This code is contributed by Anant Agarwal.

C#

// C# program to find minimum time to


// finish tasks such that no two
// consecutive tasks are skipped.
using System;
  
class GFG {
   
    // arr[] represents time taken by n
    // given tasks
    static int minTime(int []arr, int n)

2110
Chapter 288. Minimum time to finish tasks without skipping two consecutive

    {
        // Corner Cases
        if (n <= 0)
            return 0;
   
        // Initialize value for the case
        // when there is only one task in 
        // task list.
        // First task is included
        int incl = arr[0];
           
        // First task is exluded
        int excl = 0;     
   
        // Process remaining n-1 tasks
        for (int i = 1; i < n; i++)
        {
        // Time taken if current task is
        // included. There are two 
        // possibilities
        // (a) Previous task is also included
        // (b) Previous task is not included
        int incl_new = arr[i] + Math.Min(excl,
                                       incl);
   
        // Time taken when current task is not
        // included. There is only one 
        // possibility that previous task is 
        // also included.
        int excl_new = incl;
   
        // Update incl and excl for next
        // iteration
        incl = incl_new;
        excl = excl_new;
        }
   
        // Return maximum of two values for 
        // last task
        return Math.Min(incl, excl);
    }
   
    // Driver code
    public static void Main()
    {
        int []arr1 = {10, 5, 2, 7, 10};
        int n1 = arr1.Length;
        Console.WriteLine(minTime(arr1, n1));

2111
Chapter 288. Minimum time to finish tasks without skipping two consecutive

   
        int []arr2 = {10, 5, 7, 10};
        int n2 = arr2.Length;
        Console.WriteLine(minTime(arr2, n2));
   
        int []arr3 = {10, 5, 2, 4, 8, 6, 7, 10};
        int n3 = arr3.Length;
        Console.WriteLine(minTime(arr3, n3));
   
    }
}
// This code is contributed by Anant Agarwal.

PHP

<?php
// PHP program to find minimum time 
// to finish tasks such that no two 
// consecutive tasks are skipped.
  
// arr[] represents time 
// taken by n given tasks
function minTime($arr, $n)
{
    // Corner Cases
    if ($n <= 0)
        return 0;
  
    // Initialize value for the 
    // case when there is only 
    // one task in task list.
      
    // First task is included
    $incl = $arr[0]; 
      
    // First task is exluded
    $excl = 0;     
  
    // Process remaining n-1 tasks
    for ($i = 1; $i < $n; $i++)
    {
    // Time taken if current task is 
    // included There are two possibilities
    // (a) Previous task is also included
    // (b) Previous task is not included
    $incl_new = $arr[$i] + min($excl, $incl);
  
    // Time taken when current task 

2112
Chapter 288. Minimum time to finish tasks without skipping two consecutive

    // is not included. There is only 


    // one possibility that previous 
    // task is also included.
    $excl_new = $incl;
  
    // Update incl and excl 
    // for next iteration
    $incl = $incl_new;
    $excl = $excl_new;
    }
  
    // Return maximum of two 
    // values for last task
    return min($incl, $excl);
}
  
// Driver code
  
$arr1 = array(10, 5, 2, 7, 10);
$n1 = sizeof($arr1);
echo minTime($arr1, $n1),"\n" ;
  
$arr2 = array(10, 5, 7, 10);
$n2 = sizeof($arr2);
echo minTime($arr2, $n2),"\n" ;
  
$arr3 = array(10, 5, 2, 4, 
             8, 6, 7, 10);
$n3 = sizeof($arr3);
echo minTime($arr3, $n3);
  
// This code is contributed
// by nitin mittal. 
?>

Output :

12
12
22

Related Problems:
Find minimum time to finish all jobs with given constraints
Maximum sum such that no two elements are adjacent.
Improved By : nitin mittal

2113
Chapter 288. Minimum time to finish tasks without skipping two consecutive

Source

https://www.geeksforgeeks.org/minimum-time-to-finish-tasks-without-skipping-two-consecutive/

2114
Chapter 289

Minimum time to write


characters using insert, delete
and copy operation

Minimum time to write characters using insert, delete and copy operation - GeeksforGeeks
We need to write N same characters on a screen and each time we can insert a character,
delete the last character and copy and paste all written characters i.e. after copy operation
count of total written character will become twice. Now we are given time for insertion,
deletion and copying. We need to output minimum time to write N characters on the screen
using these operations.
Examples:

Input : N = 9
insert time = 1
removal time = 2
copy time = 1
Output : 5
N character can be written on screen in 5 time units as shown below,
insert a character
characters = 1 total time = 1
again insert character
characters = 2 total time = 2
copy characters
characters = 4 total time = 3
copy characters
characters = 8 total time = 4
insert character
characters = 9 total time = 5

2115
Chapter 289. Minimum time to write characters using insert, delete and copy operation

We can solve this problem using dynamic programming. We can observe a pattern after
solving some examples by hand that for writing each character we have two choices either
get it by inserting or get it by copying, whichever takes less time. Now writing relation
accordingly,
Let dp[i] be the optimal time to write i characters on screen then,

If i is even then,
dp[i] = min((dp[i-1] + insert_time),
(dp[i/2] + copy_time))
Else (If i is odd)
dp[i] = min(dp[i-1] + insert_time),
(dp[(i+1)/2] + copy_time + removal_time)

In the case of odd, removal time is added because when (i+1)/2 characters will be copied
one extra character will be on the screen which needs to be removed. Total time complexity
of solution will be O(N) and auxiliary space needed will be O(N).

// C++ program to write characters in


// minimum time by inserting, removing
// and copying operation
#include <bits/stdc++.h>
using namespace std;
  
//  method returns minimum time to write
// 'N' characters
int minTimeForWritingChars(int N, int insert,
                       int remove, int copy)
{
    if (N == 0)
       return 0;
    if (N == 1)
       return insert;
  
    //  declare dp array and initialize with zero
    int dp[N + 1];
    memset(dp, 0, sizeof(dp));
  
    //  loop for 'N' number of times
    for (int i = 1; i <= N; i++)
    {
        /*  if current char count is even then
            choose minimum from result for (i-1)
            chars and time for insertion and
            result for half of chars and time
            for copy  */
        if (i % 2 == 0)

2116
Chapter 289. Minimum time to write characters using insert, delete and copy operation

            dp[i] = min(dp[i-1] + insert,


                        dp[i/2] + copy);
  
        /*  if current char count is odd then
            choose minimum from
            result for (i-1) chars and time for
            insertion and
            result for half of chars and time for
            copy and one extra character deletion*/
        else
            dp[i] = min(dp[i-1] + insert,
                        dp[(i+1)/2] + copy + remove);
    }
    return dp[N];
}
  
// Driver code to test above methods
int main()
{
    int N = 9;
    int insert = 1, remove = 2, copy = 1;
    cout << minTimeForWritingChars(N, insert,
                                remove, copy);
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/minimum-time-write-characters-using-insert-delete-copy-operation/

2117
Chapter 290

Mobile Numeric Keypad


Problem

Mobile Numeric Keypad Problem - GeeksforGeeks


Given the mobile numeric keypad. You can only press buttons that are up, left, right or
down to the current button. You are not allowed to press bottom row corner buttons (i.e.
* and # ).

Given a number N, find out the number of possible numbers of given length.
Examples:
For N=1, number of possible numbers would be 10 (0, 1, 2, 3, …., 9)
For N=2, number of possible numbers would be 36
Possible numbers: 00,08 11,12,14 22,21,23,25 and so on.
If we start with 0, valid numbers will be 00, 08 (count: 2)
If we start with 1, valid numbers will be 11, 12, 14 (count: 3)
If we start with 2, valid numbers will be 22, 21, 23,25 (count: 4)
If we start with 3, valid numbers will be 33, 32, 36 (count: 3)
If we start with 4, valid numbers will be 44,41,45,47 (count: 4)
If we start with 5, valid numbers will be 55,54,52,56,58 (count: 5)
………………………………

2118
Chapter 290. Mobile Numeric Keypad Problem

………………………………
We need to print the count of possible numbers.
N = 1 is trivial case, number of possible numbers would be 10 (0, 1, 2, 3, …., 9)
For N > 1, we need to start from some button, then move to any of the four direction (up,
left, right or down) which takes to a valid button (should not go to *, #). Keep doing this
until N length number is obtained (depth first traversal).
Recursive Solution:
Mobile Keypad is a rectangular grid of 4X3 (4 rows and 3 columns)
Lets say Count(i, j, N) represents the count of N length numbers starting from position (i,
j)

If N = 1
Count(i, j, N) = 10
Else
Count(i, j, N) = Sum of all Count(r, c, N-1) where (r, c) is new
position after valid move of length 1 from current
position (i, j)

Following is C implementation of above recursive formula.

// A Naive Recursive C program to count number of possible numbers


// of given length
#include <stdio.h>
  
// left, up, right, down move from current location
int row[] = {0, 0, -1, 0, 1};
int col[] = {0, -1, 0, 1, 0};
  
// Returns count of numbers of length n starting from key position
// (i, j) in a numeric keyboard.
int getCountUtil(char keypad[][3], int i, int j, int n)
{
    if (keypad == NULL || n <= 0)
        return 0;
  
    // From a given key, only one number is possible of length 1
    if (n == 1)
        return 1;
  
    int k=0, move=0, ro=0, co=0, totalCount = 0;
  
    // move left, up, right, down from current location and if
    // new location is valid, then get number count of length
    // (n-1) from that new position and add in count obtained so far
    for (move=0; move<5; move++)

2119
Chapter 290. Mobile Numeric Keypad Problem

    {
        ro = i + row[move];
        co = j + col[move];
        if (ro >= 0 && ro <= 3 && co >=0 && co <= 2 &&
           keypad[ro][co] != '*' && keypad[ro][co] != '#')
        {
            totalCount += getCountUtil(keypad, ro, co, n-1);
        }
    }
  
    return totalCount;
}
  
// Return count of all possible numbers of length n
// in a given numeric keyboard
int getCount(char keypad[][3], int n)
{
    // Base cases
    if (keypad == NULL || n <= 0)
        return 0;
    if (n == 1)
        return 10;
  
    int i=0, j=0, totalCount = 0;
    for (i=0; i<4; i++)  // Loop on keypad row
    {
        for (j=0; j<3; j++)   // Loop on keypad column
        {
            // Process for 0 to 9 digits
            if (keypad[i][j] != '*' && keypad[i][j] != '#')
            {
                // Get count when number is starting from key
                // position (i, j) and add in count obtained so far
                totalCount += getCountUtil(keypad, i, j, n);
            }
        }
    }
    return totalCount;
}
  
// Driver program to test above function
int main(int argc, char *argv[])
{
   char keypad[4][3] = {{'1','2','3'},
                        {'4','5','6'},
                        {'7','8','9'},
                        {'*','0','#'}};
   printf("Count for numbers of length %d: %dn", 1, getCount(keypad, 1));

2120
Chapter 290. Mobile Numeric Keypad Problem

   printf("Count for numbers of length %d: %dn", 2, getCount(keypad, 2));


   printf("Count for numbers of length %d: %dn", 3, getCount(keypad, 3));
   printf("Count for numbers of length %d: %dn", 4, getCount(keypad, 4));
   printf("Count for numbers of length %d: %dn", 5, getCount(keypad, 5));
  
   return 0;
}

Output:

Count for numbers of length 1: 10


Count for numbers of length 2: 36
Count for numbers of length 3: 138
Count for numbers of length 4: 532
Count for numbers of length 5: 2062

Dynamic Programming
There are many repeated traversal on smaller paths (traversal for smaller N) to find all
possible longer paths (traversal for bigger N). See following two diagrams for example. In
this traversal, for N = 4 from two starting positions (buttons ‘4’ and ‘8’), we can see there
are few repeated traversals for N = 2 (e.g. 4 -> 1, 6 -> 3, 8 -> 9, 8 -> 7 etc).

2121
Chapter 290. Mobile Numeric Keypad Problem

Since the problem has both properties: Optimal Substructure and Overlapping Subproblems,
it can be efficiently solved using dynamic programming.
Following is C program for dynamic programming implementation.

// A Dynamic Programming based C program to count number of


// possible numbers of given length
#include <stdio.h>
  
// Return count of all possible numbers of length n
// in a given numeric keyboard
int getCount(char keypad[][3], int n)
{
    if(keypad == NULL || n <= 0)
        return 0;
    if(n == 1)
        return 10;
  
    // left, up, right, down move from current location
    int row[] = {0, 0, -1, 0, 1};
    int col[] = {0, -1, 0, 1, 0};
  
    // taking n+1 for simplicity - count[i][j] will store
    // number count starting with digit i and length j
    int count[10][n+1];
    int i=0, j=0, k=0, move=0, ro=0, co=0, num = 0;
    int nextNum=0, totalCount = 0;
  
    // count numbers starting with digit i and of lengths 0 and 1
    for (i=0; i<=9; i++)
    {

2122
Chapter 290. Mobile Numeric Keypad Problem

        count[i][0] = 0;
        count[i][1] = 1;
    }
  
    // Bottom up - Get number count of length 2, 3, 4, ... , n
    for (k=2; k<=n; k++)
    {
        for (i=0; i<4; i++)  // Loop on keypad row
        {
            for (j=0; j<3; j++)   // Loop on keypad column
            {
                // Process for 0 to 9 digits
                if (keypad[i][j] != '*' && keypad[i][j] != '#')
                {
                    // Here we are counting the numbers starting with
                    // digit keypad[i][j] and of length k keypad[i][j]
                    // will become 1st digit, and we need to look for
                    // (k-1) more digits
                    num = keypad[i][j] - '0';
                    count[num][k] = 0;
  
                    // move left, up, right, down from current location
                    // and if new location is valid, then get number
                    // count of length (k-1) from that new digit and
                    // add in count we found so far
                    for (move=0; move<5; move++)
                    {
                        ro = i + row[move];
                        co = j + col[move];
                        if (ro >= 0 && ro <= 3 && co >=0 && co <= 2 &&
                           keypad[ro][co] != '*' && keypad[ro][co] != '#')
                        {
                            nextNum = keypad[ro][co] - '0';
                            count[num][k] += count[nextNum][k-1];
                        }
                    }
                }
            }
        }
    }
  
    // Get count of all possible numbers of length "n" starting
    // with digit 0, 1, 2, ..., 9
    totalCount = 0;
    for (i=0; i<=9; i++)
        totalCount += count[i][n];
    return totalCount;
}

2123
Chapter 290. Mobile Numeric Keypad Problem

  
// Driver program to test above function
int main(int argc, char *argv[])
{
   char keypad[4][3] = {{'1','2','3'},
                        {'4','5','6'},
                        {'7','8','9'},
                        {'*','0','#'}};
   printf("Count for numbers of length %d: %dn", 1, getCount(keypad, 1));
   printf("Count for numbers of length %d: %dn", 2, getCount(keypad, 2));
   printf("Count for numbers of length %d: %dn", 3, getCount(keypad, 3));
   printf("Count for numbers of length %d: %dn", 4, getCount(keypad, 4));
   printf("Count for numbers of length %d: %dn", 5, getCount(keypad, 5));
  
   return 0;
}

Output:

Count for numbers of length 1: 10


Count for numbers of length 2: 36
Count for numbers of length 3: 138
Count for numbers of length 4: 532
Count for numbers of length 5: 2062

A Space Optimized Solution:


The above dynamic programming approach also runs in O(n) time and requires O(n) aux-
iliary space, as only one for loop runs n times, other for loops runs for constant time. We
can see that nth iteration needs data from (n-1)th iteration only, so we need not keep the
data from older iterations. We can have a space efficient dynamic programming approach
with just two arrays of size 10. Thanks to Nik for suggesting this solution.

// A Space Optimized C program to count number of possible numbers


// of given length
#include <stdio.h>
  
// Return count of all possible numbers of length n
// in a given numeric keyboard
int getCount(char keypad[][3], int n)
{
    if(keypad == NULL || n <= 0)
        return 0;
    if(n == 1)
        return 10;
  
    // odd[i], even[i] arrays represent count of numbers starting
    // with digit i for any length j

2124
Chapter 290. Mobile Numeric Keypad Problem

    int odd[10], even[10];


    int i = 0, j = 0, useOdd = 0, totalCount = 0;
  
    for (i=0; i<=9; i++)
        odd[i] = 1;  // for j = 1
  
    for (j=2; j<=n; j++) // Bottom Up calculation from j = 2 to n
    {
        useOdd = 1 - useOdd;
  
        // Here we are explicitly writing lines for each number 0
        // to 9. But it can always be written as DFS on 4X3 grid
        // using row, column array valid moves
        if(useOdd == 1)
        {
            even[0] = odd[0] + odd[8];
            even[1] = odd[1] + odd[2] + odd[4];
            even[2] = odd[2] + odd[1] + odd[3] + odd[5];
            even[3] = odd[3] + odd[2] + odd[6];
            even[4] = odd[4] + odd[1] + odd[5] + odd[7];
            even[5] = odd[5] + odd[2] + odd[4] + odd[8] + odd[6];
            even[6] = odd[6] + odd[3] + odd[5] + odd[9];
            even[7] = odd[7] + odd[4] + odd[8];
            even[8] = odd[8] + odd[0] + odd[5] + odd[7] + odd[9];
            even[9] = odd[9] + odd[6] + odd[8];
        }
        else
        {
            odd[0] = even[0] + even[8];
            odd[1] = even[1] + even[2] + even[4];
            odd[2] = even[2] + even[1] + even[3] + even[5];
            odd[3] = even[3] + even[2] + even[6];
            odd[4] = even[4] + even[1] + even[5] + even[7];
            odd[5] = even[5] + even[2] + even[4] + even[8] + even[6];
            odd[6] = even[6] + even[3] + even[5] + even[9];
            odd[7] = even[7] + even[4] + even[8];
            odd[8] = even[8] + even[0] + even[5] + even[7] + even[9];
            odd[9] = even[9] + even[6] + even[8];
        }
    }
  
    // Get count of all possible numbers of length "n" starting
    // with digit 0, 1, 2, ..., 9
    totalCount = 0;
    if(useOdd == 1)
    {
        for (i=0; i<=9; i++)
            totalCount += even[i];

2125
Chapter 290. Mobile Numeric Keypad Problem

    }
    else
    {
        for (i=0; i<=9; i++)
            totalCount += odd[i];
    }
    return totalCount;
}
  
// Driver program to test above function
int main()
{
    char keypad[4][3] = {{'1','2','3'},
        {'4','5','6'},
        {'7','8','9'},
        {'*','0','#'}
    };
    printf("Count for numbers of length %d: %dn", 1, getCount(keypad, 1));
    printf("Count for numbers of length %d: %dn", 2, getCount(keypad, 2));
    printf("Count for numbers of length %d: %dn", 3, getCount(keypad, 3));
    printf("Count for numbers of length %d: %dn", 4, getCount(keypad, 4));
    printf("Count for numbers of length %d: %dn", 5, getCount(keypad, 5));
  
    return 0;
}

Output:

Count for numbers of length 1: 10


Count for numbers of length 2: 36
Count for numbers of length 3: 138
Count for numbers of length 4: 532
Count for numbers of length 5: 2062

This article is contributed by Anurag Singh. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.

Source

https://www.geeksforgeeks.org/mobile-numeric-keypad-problem/

2126
Chapter 291

Modify array to maximize sum


of adjacent differences

Modify array to maximize sum of adjacent differences - GeeksforGeeks


Given an array, we need to modify values of this array in such a way that sum of absolute
differences between two consecutive elements is maximized. If the value of an array element
is X, then we can change it to either 1 or X.
Examples :

Input : arr[] = [3, 2, 1, 4, 5]


Output : 8
We can modify above array as,
Modified arr[] = [3, 1, 1, 4, 1]
Sum of differences =
|1-3| + |1-1| + |4-1| + |1-4| = 8
Which is the maximum obtainable value
among all choices of modification.

Input : arr[] = [1, 8, 9]


Output : 14

This problem is a variation of Assembly Line Scheduling and can be solved using dynamic
programming. We need to maximize sum of differences each value X should be changed to
either 1 or X. To achieve above stated condition we take a dp array of array length size
with 2 columns, where dp[i][0] stores the maximum value of sum using first i elements only
if ith array value is modified to 1 and dp[i][1] stores the maximum value of sum using first
i elements if ith array value is kept as a[i] itself.Main thing to observe is,
C++

//  C++ program to get maximum consecutive element

2127
Chapter 291. Modify array to maximize sum of adjacent differences

// difference sum
#include <bits/stdc++.h>
using namespace std;
  
// Returns maximum-difference-sum with array
// modifications allowed.
int maximumDifferenceSum(int arr[], int N)
{
    // Initialize dp[][] with 0 values.
    int dp[N][2];
    for (int i = 0; i < N; i++)
        dp[i][0] = dp[i][1] = 0;
  
    for (int i=0; i<(N-1); i++)
    {
        /*  for [i+1][0] (i.e. current modified
            value is 1), choose maximum from
            dp[i][0] + abs(1 - 1) = dp[i][0] and
            dp[i][1] + abs(1 - arr[i])   */
        dp[i + 1][0] = max(dp[i][0],
                          dp[i][1] + abs(1-arr[i]));
  
        /*  for [i+1][1] (i.e. current modified value
            is arr[i+1]), choose maximum from
            dp[i][0] + abs(arr[i+1] - 1)    and
            dp[i][1] + abs(arr[i+1] - arr[i])*/
        dp[i + 1][1] = max(dp[i][0] + abs(arr[i+1] - 1),
                     dp[i][1] + abs(arr[i+1] - arr[i]));
    }
  
    return max(dp[N-1][0], dp[N-1][1]);
}
  
//  Driver code to test above methods
int main()
{
    int arr[] = {3, 2, 1, 4, 5};
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << maximumDifferenceSum(arr, N) << endl;
    return 0;
}

Java

// java program to get maximum consecutive element


// difference sum
import java.io.*;
  

2128
Chapter 291. Modify array to maximize sum of adjacent differences

class GFG 
{
    // Returns maximum-difference-sum with array
    // modifications allowed.
    static int maximumDifferenceSum(int arr[], int N)
    {
        // Initialize dp[][] with 0 values.
        int dp[][] = new int [N][2];
  
        for (int i = 0; i < N; i++)
            dp[i][0] = dp[i][1] = 0;
      
        for (int i = 0; i< (N - 1); i++)
        {
            /* for [i+1][0] (i.e. current modified
            value is 1), choose maximum from
            dp[i][0] + abs(1 - 1) = dp[i][0] and
            dp[i][1] + abs(1 - arr[i]) */
            dp[i + 1][0] = Math.max(dp[i][0],
                           dp[i][1] + Math.abs(1 - arr[i]));
      
            /* for [i+1][1] (i.e. current modified value
            is arr[i+1]), choose maximum from
            dp[i][0] + abs(arr[i+1] - 1) and
            dp[i][1] + abs(arr[i+1] - arr[i])*/
            dp[i + 1][1] = Math.max(dp[i][0] + 
                           Math.abs(arr[i + 1] - 1),
                           dp[i][1] + Math.abs(arr[i + 1] 
                           - arr[i]));
        }
      
        return Math.max(dp[N - 1][0], dp[N - 1][1]);
    }
  
    // Driver code 
    public static void main (String[] args) 
    {
        int arr[] = {3, 2, 1, 4, 5};
        int N = arr.length;
        System.out.println( maximumDifferenceSum(arr, N));
                  
    }
}
  
// This code is contributed by vt_m

C#

2129
Chapter 291. Modify array to maximize sum of adjacent differences

// C# program to get maximum consecutive element


// difference sum
using System;
  
class GFG {
      
    // Returns maximum-difference-sum with array
    // modifications allowed.
    static int maximumDifferenceSum(int []arr, int N)
    {
          
        // Initialize dp[][] with 0 values.
        int [,]dp = new int [N,2];
  
        for (int i = 0; i < N; i++)
            dp[i,0] = dp[i,1] = 0;
      
        for (int i = 0; i < (N - 1); i++)
        {
            /* for [i+1][0] (i.e. current modified
            value is 1), choose maximum from
            dp[i][0] + abs(1 - 1) = dp[i][0] and
            dp[i][1] + abs(1 - arr[i]) */
            dp[i + 1,0] = Math.Max(dp[i,0],
                        dp[i,1] + Math.Abs(1 - arr[i]));
      
            /* for [i+1][1] (i.e. current modified value
            is arr[i+1]), choose maximum from
            dp[i][0] + abs(arr[i+1] - 1) and
            dp[i][1] + abs(arr[i+1] - arr[i])*/
            dp[i + 1,1] = Math.Max(dp[i,0] + 
                        Math.Abs(arr[i + 1] - 1),
                        dp[i,1] + Math.Abs(arr[i + 1] 
                        - arr[i]));
        }
      
        return Math.Max(dp[N - 1,0], dp[N - 1,1]);
    }
  
    // Driver code 
    public static void Main () 
    {
        int []arr = {3, 2, 1, 4, 5};
        int N = arr.Length;
          
        Console.Write( maximumDifferenceSum(arr, N));
    }
}

2130
Chapter 291. Modify array to maximize sum of adjacent differences

  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to get maximum 
// consecutive element 
// difference sum
  
// Returns maximum-difference-sum 
// with array modifications allowed.
function maximumDifferenceSum($arr, $N)
{
    // Initialize dp[][] 
    // with 0 values.
    $dp = array(array());
    for ($i = 0; $i < $N; $i++)
        $dp[$i][0] = $dp[$i][1] = 0;
  
    for ($i = 0; $i < ($N - 1); $i++)
    {
        /* for [i+1][0] (i.e. current 
            modified value is 1), choose 
            maximum from dp[$i][0] + 
            abs(1 - 1) = dp[i][0] and 
            dp[$i][1] + abs(1 - arr[i]) */
        $dp[$i + 1][0] = max($dp[$i][0],
                            $dp[$i][1] + 
                            abs(1 - $arr[$i]));
  
        /* for [i+1][1] (i.e. current 
            modified value is arr[i+1]), 
            choose maximum from dp[i][0] + 
            abs(arr[i+1] - 1) and dp[i][1] + 
            abs(arr[i+1] - arr[i])*/
        $dp[$i + 1][1] = max($dp[$i][0] + 
                             abs($arr[$i + 1] - 1),
                                       $dp[$i][1] + 
                                 abs($arr[$i + 1] - 
                                        $arr[$i]));
    }
  
    return max($dp[$N - 1][0], $dp[$N - 1][1]);
}
  
// Driver Code
$arr = array(3, 2, 1, 4, 5);

2131
Chapter 291. Modify array to maximize sum of adjacent differences

$N = count($arr);
echo maximumDifferenceSum($arr, $N);
  
// This code is contributed by anuj_67.
?>

Output :

Time Complexity : O(N)


Auxiliary Space : O(N)
Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/modify-array-to-maximize-sum-of-adjacent-differences/

2132
Chapter 292

Moser-de Bruijn Sequence

Moser-de Bruijn Sequence - GeeksforGeeks


Given an integer ‘n’, print the first ‘n’ terms of the Moser-de Bruijn Sequence.
The Moser-de Bruijn sequence is the sequence obtained by adding up the distinct powers
of the number 4 (For example 1, 4, 16, 64, etc).
Examples :

Input : 5
Output : 0 1 4 5 16

Input : 10
Output : 0 1 4 5 16 17 20 21 64 65

It is observed that the terms of the sequence follow the recurrence relation :

1) S(2 * n) = 4 * S(n)
2) S(2 * n + 1) = 4 * S(n) + 1
with S(0) = 0 and S(1) = 1

It may be noted here that any number which is the sum of non-distinct powers of 4 are not
a part of the sequence. For example, 8 is not a part of the sequence because it is formed as
the sum of non-distinct powers of 4, that are 4 and 4.
Thus, any number which is not a power of 4 and is present in the sequence must be the sum
of the distinct powers of 4.
For example, 21 is a part of the sequence, even though it is not a power of 4 because it is
the sum of the distinct powers of 4, that are 1, 4 and 16.
Employ the recurrence relation discussed above to generate the sequence, efficiently.
C++

2133
Chapter 292. Moser-de Bruijn Sequence

   
// CPP code to generate first 'n' terms 
// of the Moser-de Bruijn Sequence
#include <bits/stdc++.h>
using namespace std;
  
// Function to generate nth term 
// of Moser-de Bruijn Sequence
int gen(int n)

    // S(0) = 0
    if (n == 0)
        return 0;
      
    // S(1) = 1
    else if (n == 1)
        return 1;
      
    // S(2 * n) = 4 * S(n)
    else if (n % 2 == 0)
        return 4 * gen(n / 2);
      
    // S(2 * n + 1) = 4 * S(n) + 1
    else if (n % 2 == 1)
        return 4 * gen(n / 2) + 1;
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
void moserDeBruijn(int n)
{
    for (int i = 0; i < n; i++)
        cout << gen(i) << " ";
    cout << "\n";
}
  
// Driver Code
int main()
{
    int n = 15;
    cout << "First " << n << " terms of "
         << "Moser-de Bruijn Sequence : \n";
    moserDeBruijn(n);
    return 0;
}

Java

2134
Chapter 292. Moser-de Bruijn Sequence

// Java code to generate first 'n' terms 


// of the Moser-de Bruijn Sequence
  
class GFG 
{
      
// Function to generate nth term 
// of Moser-de Bruijn Sequence
public static int gen(int n)

      
    // S(0) = 0
    if (n == 0)
        return 0;
      
    // S(1) = 1
    else if (n == 1)
        return 1;
      
    // S(2 * n) = 4 * S(n)
    else if (n % 2 == 0)
        return 4 * gen(n / 2);
      
    // S(2 * n + 1) = 4 * S(n) + 1
    else if (n % 2 == 1)
        return 4 * gen(n / 2) + 1;
    return 0;
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
public static void moserDeBruijn(int n)
{
    for (int i = 0; i < n; i++)
        System.out.print(gen(i) + " ");
    System.out.println();
}
  
// Driver Code
public static void main(String args[])
{
    int n = 15;
    System.out.println("First " + n + 
                       " terms of " + 
      "Moser-de Bruijn Sequence : ");
    moserDeBruijn(n);
}
}

2135
Chapter 292. Moser-de Bruijn Sequence

  
// This code is contributed by JaideepPyne.

Python3

# Python code to generate first 


# 'n' terms of the Moser-de 
# Bruijn Sequence
  
# Function to generate nth term
# of Moser-de Bruijn Sequence
def gen(n):
  
    # S(0) = 0
    if n == 0:
        return 0
  
    # S(1) = 1
    elif n ==1:
        return 1
  
    # S(2 * n) = 4 * S(n)
    elif n % 2 ==0:
        return 4 * gen(n // 2)
  
    # S(2 * n + 1) = 4 * S(n) + 1
    elif n % 2 == 1:
        return 4 * gen(n // 2) +1
  
# Generating the first 'n' terms
# of Moser-de Bruijn Sequence
def moserDeBruijn(n):
    for i in range(n):
        print(gen(i), end = " ")
  
# Driver Program
n = 15
print("First", n, "terms of ",
       "Moser-de Brujn Sequence:")
moserDeBruijn(n)
  
# This code is contributed by Shrikant13

C#

// C# code to generate first 'n' terms 


// of the Moser-de Bruijn Sequence

2136
Chapter 292. Moser-de Bruijn Sequence

using System;
  
class GFG {
      
// Function to generate nth term 
// of Moser-de Bruijn Sequence
public static int gen(int n)

      
    // S(0) = 0
    if (n == 0)
        return 0;
      
    // S(1) = 1
    else if (n == 1)
        return 1;
      
    // S(2 * n) = 4 * S(n)
    else if (n % 2 == 0)
        return 4 * gen(n / 2);
      
    // S(2 * n + 1) = 4 * S(n) + 1
    else if (n % 2 == 1)
        return 4 * gen(n / 2) + 1;
    return 0;
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
public static void moserDeBruijn(int n)
{
    for (int i = 0; i < n; i++)
        Console.Write(gen(i) + " ");
        Console.WriteLine();
}
  
// Driver Code
public static void Main()
{
    int n = 15;
    Console.WriteLine("First " + n + 
                    " terms of " + 
    "Moser-de Bruijn Sequence : ");
    moserDeBruijn(n);
}
}
  
// This code is contributed by anuj_67.

2137
Chapter 292. Moser-de Bruijn Sequence

PHP

<?php
// PHP code to generate first 'n' terms 
// of the Moser-de Bruijn Sequence
  
// Function to generate nth term 
// of Moser-de Bruijn Sequence
function gen($n)

      
    // S(0) = 0
    if ($n == 0)
        return 0;
      
    // S(1) = 1
    else if ($n == 1)
        return 1;
      
    // S(2 * n) = 4 * S(n)
    else if ($n % 2 == 0)
        return 4 * gen($n / 2);
      
    // S(2 * n + 1) = 4 * S(n) + 1
    else if ($n % 2 == 1)
        return 4 * gen($n / 2) + 1;
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
function moserDeBruijn($n)
{
    for ($i = 0; $i < $n; $i++)
        echo(gen($i) . " ");
    echo("\n");
}
  
// Driver Code
$n = 15;
echo("First " . $n . " terms of " . 
  "Moser-de Bruijn Sequence : \n");
echo(moserDeBruijn($n));
  
// This code is contributed by Ajit.
?>

Output :

2138
Chapter 292. Moser-de Bruijn Sequence

First 15 terms of Moser-de Bruijn Sequence :


0 1 4 5 16 17 20 21 64 65 68 69 80 81 84

Dynamic Programming Implementation:

C++

// CPP code to generate first 'n' terms 


// of the Moser-de Bruijn Sequence
#include <bits/stdc++.h>
using namespace std;
  
// Function to generate nth term 
// of Moser-de Bruijn Sequence
int gen(int n)

    int S[n+1];
  
    S[0] = 0;
    S[1] = 1;
  
    for (int i = 2; i <= n; i++)
    {    
        // S(2 * n) = 4 * S(n)
        if (i % 2 == 0)
           S[i] = 4 * S[i / 2];
      
        // S(2 * n + 1) = 4 * S(n) + 1
        else 
           S[i] = 4 * S[i / 2] + 1;
    }
      
    return S[n];
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
void moserDeBruijn(int n)
{
    for (int i = 0; i < n; i++)
        cout << gen(i) << " ";
    cout << "\n";
}
  
// Driver Code
int main()

2139
Chapter 292. Moser-de Bruijn Sequence

{
    int n = 15;
    cout << "First " << n << " terms of "
         << "Moser-de Bruijn Sequence : \n";
    moserDeBruijn(n);
    return 0;
}

Java

// Java code to generate first 'n' terms 


// of the Moser-de Bruijn Sequence
  
class GFG 
{
      
// Function to generate nth term 
// of Moser-de Bruijn Sequence
static int gen(int n)

    int []S = new int [n + 1];
  
    S[0] = 0;
    if(n != 0)
        S[1] = 1;
  
    for (int i = 2; i <= n; i++)
    { 
          
        // S(2 * n) = 4 * S(n)
        if (i % 2 == 0)
        S[i] = 4 * S[i / 2];
      
        // S(2 * n + 1) = 4 * S(n) + 1
        else
        S[i] = 4 * S[i/2] + 1;
    }
      
    return S[n];
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
static void moserDeBruijn(int n)
{
    for (int i = 0; i < n; i++)
        System.out.print(gen(i)+" ");
}

2140
Chapter 292. Moser-de Bruijn Sequence

  
// Driver Code
public static void main(String[] args)
{
    int n = 15;
    System.out.println("First " + n + 
                       " terms of " + 
      "Moser-de Bruijn Sequence : ");
    moserDeBruijn(n);
}
}
  
// This code is contributed by 
// Smitha Dinesh Semwal.

python3

# python3 code to generate first 'n' terms 


# of the Moser-de Bruijn Sequence
  
# Function to generate nth term 
# of Moser-de Bruijn Sequence
def gen( n ):
    S = [0, 1]
    for i in range(2, n+1):
          
        # S(2 * n) = 4 * S(n)
        if i % 2 == 0:
            S.append(4 * S[int(i / 2)]);
              
        # S(2 * n + 1) = 4 * S(n) + 1
        else:
            S.append(4 * S[int(i / 2)] + 1);
    z = S[n];
    return z;
  
# Generating the first 'n' terms 
# of Moser-de Bruijn Sequence
def moserDeBruijn(n):
    for i in range(n):
        print(gen(i), end = " ")
  
# Driver Code
n = 15
print("First", n, "terms of ",
    "Moser-de Brujn Sequence:")
moserDeBruijn(n)
  

2141
Chapter 292. Moser-de Bruijn Sequence

# This code is contributed by mits.

C#

// C# code to generate first 'n' terms 


// of the Moser-de Bruijn Sequence
using System;
  
class GFG 
{
      
// Function to generate nth term 
// of Moser-de Bruijn Sequence
static int gen(int n)

    int []S = new int [n + 1];
  
    S[0] = 0;
    if(n != 0)
        S[1] = 1;
  
    for (int i = 2; i <= n; i++)
    { 
          
        // S(2 * n) = 4 * S(n)
        if (i % 2 == 0)
        S[i] = 4 * S[i / 2];
      
        // S(2 * n + 1) = 4 * S(n) + 1
        else
        S[i] = 4 * S[i/2] + 1;
    }
      
    return S[n];
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
static void moserDeBruijn(int n)
{
    for (int i = 0; i < n; i++)
        Console.Write(gen(i)+" ");
}
  
// Driver Code
public static void Main()
{
    int n = 15;

2142
Chapter 292. Moser-de Bruijn Sequence

    Console.WriteLine("First " + n + 
                      " terms of " + 
     "Moser-de Bruijn Sequence : ");
    moserDeBruijn(n);
}
}
  
// This code is contributed by 
// Smitha Dinesh Semwal.

PHP

<?php
// PHP code to generate first 'n' terms 
// of the Moser-de Bruijn Sequence
  
// Function to generate nth term 
// of Moser-de Bruijn Sequence
function gen( $n)

    $S = array();
  
    $S[0] = 0;
    $S[1] = 1;
  
    for ( $i = 2; $i <= $n; $i++)
    { 
        // S(2 * n) = 4 * S(n)
        if ($i % 2 == 0)
        $S[$i] = 4 * $S[$i / 2];
      
        // S(2 * n + 1) = 4 * S(n) + 1
        else
        $S[$i] = 4 * $S[$i/2] + 1;
    }
      
    return $S[$n];
}
  
// Generating the first 'n' terms 
// of Moser-de Bruijn Sequence
function moserDeBruijn( $n)
{
    for ( $i = 0; $i < $n; $i++)
        echo gen($i) , " ";
    echo "\n";
}
  

2143
Chapter 292. Moser-de Bruijn Sequence

// Driver Code
$n = 15;
echo "First " ,$n ," terms of "
    , "Moser-de Bruijn Sequence : \n";
moserDeBruijn($n);
  
// This code is contributed by anuj_67.
?>

Output :

First 15 terms of Moser-de Bruijn Sequence :


0 1 4 5 16 17 20 21 64 65 68 69 80 81 84

Improved By : shrikanth13, Smitha Dinesh Semwal, jit_t, jaideeppyne1997, vt_m, more


Mithun Kumar

Source

https://www.geeksforgeeks.org/moser-de-bruijn-sequence/

2144
Chapter 293

Multistage Graph (Shortest


Path)

Multistage Graph (Shortest Path) - GeeksforGeeks


A Multistage graph is a directed graph in which the nodes can be divided into a set of
stages such that all edges are from a stage to next stage only (In other words there is no
edge between vertices of same stage and from a vertex of current stage to previous stage).
We are give a multistage graph, a source and a destination, we need to find shortest path
from source to destination. By convention, we consider source at stage 1 and destination as
last stage.
Following is an example graph we will consider in this article :-

Now there are various strategies we can apply :-

2145
Chapter 293. Multistage Graph (Shortest Path)

• The Brute force method of finding all possible paths between Source and Destination
and then finding the minimum. That’s the WORST possible strategy.
• Dijkstra’s Algorithm of Single Source shortest paths. This method will find shortest
paths from source to all other nodes which is not required in this case. So it will take
a lot of time and it doesn’t even use the SPECIAL feature that this MULTI-STAGE
graph has.
• Simple Greedy Method – At each node, choose the shortest outgoing path. If we
apply this approach to the example graph give above we get the solution as 1 + 4 +
18 = 23. But a quick look at the graph will show much shorter paths available than
23. So the greedy method fails !
• The best option is Dynamic Programming. So we need to find Optimal Sub-
structure, Recursive Equations and Overlapping Sub-problems.

Optimal Substructure and Recursive Equation :-

We define the notation :- M(x, y) as the minimum cost to T(target node) from Stage x,
Node y.

Shortest distance from stage 1, node 0 to


destination, i.e., 7 is M(1, 0).

// From 0, we can go to 1 or 2 or 3 to
// reach 7.
M(1, 0) = min(1 + M(2, 1),
2 + M(2, 2),
5 + M(2, 3))

This means that our problem of 0 —> 7 is now sub-divided into 3 sub-problems :-

So if we have total 'n' stages and target


as T, then the stopping condition will be :-
M(n-1, i) = i ---> T + M(n, T) = i ---> T

Recursion Tree and Overlapping Sub-Problems:-


So, the hierarchy of M(x, y) evaluations will look something like this :-

In M(i, j), i is stage number and


j is node number

M(1, 0)
/ | \
/ | \
M(2, 1) M(2, 2) M(2, 3)

2146
Chapter 293. Multistage Graph (Shortest Path)

/ \ / \ / \
M(3, 4) M(3, 5) M(3, 4) M(3, 5) M(3, 6) M(3, 6)
. . . . . .
. . . . . .
. . . . . .

So, here we have drawn a very small part of the Recursion Tree and we can already see
Overlapping Sub-Problems. We can largely reduce the number of M(x, y) evaluations using
Dynamic Programming.
Implementation details:
The below implementation assumes that nodes are numbered from 0 to N-1 from first stage
(source) to last stage (destination). We also assume that the input graph is multistage.

// CPP program to find shortest distance


// in a multistage graph.
#include<bits/stdc++.h>
using namespace std;
  
#define N 8
#define INF INT_MAX
  
// Returns shortest distance from 0 to
// N-1.
int shortestDist(int graph[N][N]) {
  
    // dist[i] is going to store shortest
    // distance from node i to node N-1.
    int dist[N];
  
    dist[N-1] = 0;
  
    // Calculating shortest path for
    // rest of the nodes
    for (int i = N-2 ; i >= 0 ; i--)
    {
  
        // Initialize distance from i to
        // destination (N-1)
        dist[i] = INF;
  
        // Check all nodes of next stages
        // to find shortest distance from
        // i to N-1.
        for (int j = i ; j < N ; j++)
        {
            // Reject if no edge exists
            if (graph[i][j] == INF)

2147
Chapter 293. Multistage Graph (Shortest Path)

                continue;
  
            // We apply recursive equation to
            // distance to target through j.
            // and compare with minimum distance 
            // so far.
            dist[i] = min(dist[i], graph[i][j] +
                                        dist[j]);
        }
    }
  
    return dist[0];
}
  
// Driver code
int main()
{
    // Graph stored in the form of an
    // adjacency Matrix
    int graph[N][N] =
      {{INF, 1, 2, 5, INF, INF, INF, INF},
       {INF, INF, INF, INF, 4, 11, INF, INF},
       {INF, INF, INF, INF, 9, 5, 16, INF},
       {INF, INF, INF, INF, INF, INF, 2, INF},
       {INF, INF, INF, INF, INF, INF, INF, 18},
       {INF, INF, INF, INF, INF, INF, INF, 13},
       {INF, INF, INF, INF, INF, INF, INF, 2}};
  
    cout << shortestDist(graph);
    return 0;
}

Output:

Time Complexity : O(n2 )

Source

https://www.geeksforgeeks.org/multistage-graph-shortest-path/

2148
Chapter 294

Newman-Conway Sequence

Newman-Conway Sequence - GeeksforGeeks


Newman-Conway Sequence is the one which generates the following integer sequence.
1 1 2 2 3 4 4 4 5 6 7 7…
In mathematical terms, the sequence P(n) of Newman-Conway numbers is defined by recur-
rence relation

P(n) = P(P(n - 1)) + P(n - P(n - 1))

with seed values P(1) = 1 and P(2) = 1


Given a number n, print n-th number in Newman-Conway Sequence.
Examples :

Input : n = 2
Output : 1

Input : n = 10
Output : 6

Method 1 (Use Recursion) :


A simple approach is direct recursive implementation of above recurrence relation.

C++

// C++ program for n-th 


// element of Newman-Conway Sequence
#include <bits/stdc++.h>

2149
Chapter 294. Newman-Conway Sequence

using namespace std;


  
// Recursive Function to find the n-th element
int sequence(int n)
{
    if (n == 1 || n == 2)
        return 1;
    else
        return sequence(sequence(n - 1)) 
                + sequence(n - sequence(n - 1));
}
  
// Driver Program
int main()
{
    int n = 10;
    cout << sequence(n);
    return 0;
}

Java

// Java program to find nth


// element of Newman-Conway Sequence
import java.io.*;
  
class GFG {
      
    // Recursion to find 
    // n-th element
    static int sequence(int n)
    {
        if (n == 1 || n == 2)
            return 1;
        else
            return sequence(sequence(n - 1)) 
                  + sequence(n - sequence(n - 1));
    }
       
    // Driver Program
    public static void main(String args[])
    {
        int n = 10;
        System.out.println(sequence(n));
    }
}
  
/*This code is contributed by Nikita Tiwari.*/

2150
Chapter 294. Newman-Conway Sequence

Python

# Recursive function to find the n-th 


# element of sequence
def sequence(n):
    if n == 1 or n == 2:
        return 1
    else:
        return sequence(sequence(n-1)) + sequence(n-sequence(n-1));
          
# Driver code
def main():
    n = 10
    print sequence(n)
      
if __name__ == '__main__':
    main()

C#

// C# program to find nth element


// of Newman-Conway Sequence
using System;
  
class GFG {
      
    // Recursion to find 
    // n-th element
    static int sequence(int n)
    {
        if (n == 1 || n == 2)
            return 1;
        else
            return sequence(sequence(n - 1)) + sequence
                           (n - sequence(n - 1));
    }
      
    // Driver code
    public static void Main()
    {
        int n = 10;
        Console.Write(sequence(n));
    }
}
  
// This code is contributed by Nitin Mittal.

PHP

2151
Chapter 294. Newman-Conway Sequence

<?php
// PHP program for n-th element 
// of Newman-Conway Sequence
  
// Recursive Function to 
// find the n-th element
function sequence($n)
{
    if ($n == 1 || $n == 2)
        return 1;
    else
        return sequence(sequence($n - 1))+ 
               sequence($n - sequence($n - 1));
}
  
// Driver Code
$n = 10;
echo(sequence($n));
  
// This code is contributed by Ajit.
?>

Output :

Method 2 (Use Dynamic Programming) :


We can avoid repeated work done in method 1 by storing the values in the sequence in an
array.

C++

// C++ program to find the n-th element of 


// Newman-Conway Sequence
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the n-th element
int sequence(int n)
{
    // Declare array to store sequence
    int f[n + 1];
    int i;
    f[0] = 0;
    f[1] = 1;
    f[2] = 1;
  

2152
Chapter 294. Newman-Conway Sequence

    for (i = 3; i <= n; i++) 


        f[i] = f[f[i - 1]] + f[i - f[i - 1]];    
  
    return f[n];
}
  
// Driver Program
int main()
{
    int n = 10;
    cout << sequence(n);
    return 0;
}

Java

// JAVA Code for Newman-Conway Sequence


import java.util.*;
  
class GFG {
      
    // Function to find the n-th element
    static int sequence(int n)
    {
        // Declare array to store sequence
        int f[] = new int[n + 1];
        f[0] = 0;
        f[1] = 1;
        f[2] = 1;
  
        int i;
       
        for (i = 3; i <= n; i++) 
            f[i] = f[f[i - 1]] +
                        f[i - f[i - 1]];    
       
        return f[n];
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
         int n = 10;
         System.out.println(sequence(n));
  
    }
}
  

2153
Chapter 294. Newman-Conway Sequence

// This code is contributed by Arnav Kr. Mandal.

Python

''' Python program to find the n-th element of 


    Newman-Conway Sequence'''
  
# To declare array import module array
import array
def sequence(n):
    f = array.array('i', [0, 1, 1])
  
    # To store values of sequence in array
    for i in range(3, n + 1):
        r = f[f[i-1]]+f[i-f[i-1]]
        f.append(r);
  
    return r
  
# Driver code
def main():
    n = 10
    print sequence(n)
      
if __name__ == '__main__':
    main()

C#

// C# Code for Newman-Conway Sequence


using System;
  
class GFG {
      
    // Function to find the n-th element
    static int sequence(int n)
    {
        // Declare array to store sequence
        int []f = new int[n + 1];
        f[0] = 0;
        f[1] = 1;
        f[2] = 1;
  
        int i;
      
        for (i = 3; i <= n; i++) 
            f[i] = f[f[i - 1]] +

2154
Chapter 294. Newman-Conway Sequence

                   f[i - f[i - 1]]; 


      
        return f[n];
    }
      
    // Driver Code
    public static void Main() 
    {
        int n = 10;
        Console.Write(sequence(n));
  
    }
}
  
// This code is contributed by Nitin Mittal.

PHP

<?php
// PHP program to find the n-th element  
// of Newman-Conway Sequence
  
// Function to find 
// the n-th element
function sequence($n)
{
      
    // Declare array to 
    // store sequence
    $i;
    $f[0] = 0;
    $f[1] = 1;
    $f[2] = 1;
  
    for ($i = 3; $i <= $n; $i++) 
        $f[$i] = $f[$f[$i - 1]] + 
                 $f[$i - $f[$i - 1]]; 
  
    return $f[$n];
}
  
// Driver Code
$n = 10;
echo(sequence($n));
  
// This code is contributed by Ajit.
?>

2155
Chapter 294. Newman-Conway Sequence

Output :

Time Complexity : O(n)


References : https://archive.lib.msu.edu/crcmath/math/math/n/n078.htm
Improved By : nitin mittal, jit_t

Source

https://www.geeksforgeeks.org/newman-conway-sequence/

2156
Chapter 295

Newman–Shanks–Williams
prime

Newman–Shanks–Williams prime - GeeksforGeeks


In mathematics, a Newman–Shanks–Williams prime (NSW prime) is a prime number
p which can be written in the form:

Recurrence relation for Newman–Shanks–Williams prime is:

The first few terms of the sequence are 1, 1, 3, 7, 17, 41, 99, ….
Examples:

Input : n = 3
Output : 7

Input : n = 4
Output : 17

Below is the implementation of finding nth Newman–Shanks–Williams prime:

C++

2157
Chapter 295. Newman–Shanks–Williams prime

// CPP Program to find Newman–Shanks–Williams prime


#include <bits/stdc++.h>
using namespace std;
  
// return nth Newman–Shanks–Williams prime
int nswp(int n)
{
    // Base case
    if (n == 0 || n == 1)
        return 1;
  
    // Recursive step
    return 2 * nswp(n - 1) + nswp(n - 2);
}
  
// Driven Program
int main()
{
    int n = 3;
  
    cout << nswp(n) << endl;
    return 0;
}

Java

// Java Program to find 


// Newman-Shanks-Williams prime
class GFG
{
// return nth Newman-Shanks-Williams
// prime
static int nswp(int n)
{
    // Base case
    if (n == 0 || n == 1)
        return 1;
  
    // Recursive step
    return 2 * nswp(n - 1) + nswp(n - 2);
}
  
// Driver code 
public static void main (String[] args)
{
    int n = 3;
    System.out.println(nswp(n));
}

2158
Chapter 295. Newman–Shanks–Williams prime

}
  
// This code is contributed by Anant Agarwal.

Python3

# Python3 Program to find Newman–Shanks–Williams prime


  
# return nth Newman–Shanks–Williams prime
def nswp(n):
      
    # Base case
    if n == 0 or n == 1:
        return 1
  
    # Recursive step
    return 2 * nswp(n - 1) + nswp(n - 2)
  
# Driven Program
n = 3
print (nswp(n))
  
  
# This code is contributed by Shreyanshi Arun.

C#

// C# Program to find
// Newman-Shanks-Williams prime
using System;
  
class GFG {
      
    // return nth Newman-Shanks-Williams
    // prime
    static int nswp(int n)
    {
          
        // Base case
        if (n == 0 || n == 1)
            return 1;
  
        // Recursive step
        return 2 * nswp(n - 1) + nswp(n - 2);
    }
  
    // Driver code

2159
Chapter 295. Newman–Shanks–Williams prime

    public static void Main()


    {
        int n = 3;
          
        Console.WriteLine(nswp(n));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program to find 
// Newman–Shanks–Williams prime
  
// return nth Newman – 
// Shanks – Williams prime
function nswp($n)
{
      
    // Base case
    if ($n == 0 || $n == 1)
        return 1;
  
    // Recursive step
    return 2 * nswp($n - 1) + 
               nswp($n - 2);
}
  
// Driver Code
$n = 3;
echo(nswp($n));
  
// This code is contributed by Ajit.
?>

Output:

Below is Dynamic Programming solution of finding nth Newman–Shanks–Williams prime:

C++

2160
Chapter 295. Newman–Shanks–Williams prime

// CPP Program to find Newman–Shanks–Williams prime


#include <bits/stdc++.h>
using namespace std;
  
// return nth Newman–Shanks–Williams prime
int nswp(int n)
{
    int dp[n + 1];
  
    // Base case
    dp[0] = dp[1] = 1;
  
    // Finding nth Newman–Shanks–Williams prime
    for (int i = 2; i <= n; i++)
        dp[i] = 2 * dp[i - 1] + dp[i - 2];
  
    return dp[n];
}
  
// Driver Program
int main()
{
    int n = 3;
  
    cout << nswp(n) << endl;
    return 0;
}

Java

// Java Program for finding


// Newman-Shanks-Williams prime
import java.util.*;
  
class GFG
{
    // return nth Newman_Shanks_Williams prime
    public static int nswpn(int n)
    {
        int dp[] = new int[n + 1];
          
        // Base case
        dp[0] = dp[1] = 1;
          
        // Finding nth Newman_Shanks_Williams prime
        for (int i = 2; i <= n; i++)
          dp[i] = 2 * dp[i - 1] + dp[i - 2];
          

2161
Chapter 295. Newman–Shanks–Williams prime

        return dp[n];
    }
      
    // Driver Program
    public static void main (String[] args) {
          
        int n = 3;
          
        System.out.println(nswpn(n));
    }
}
  
/* This code is contributed by Akash Singh */

Python3

# Python3 Program to find 


# Newman–Shanks–Williams prime
  
# return nth Newman–Shanks
# –Williams prime
def nswp(n):
      
    # Base case
    dp = [1 for x in range(n + 1)];
      
    # Finding nth Newman–Shanks
    # –Williams prime
    for i in range(2, n + 1):
        dp[i] = (2 * dp[i - 1] + 
                     dp[i - 2]);
    return dp[n];
  
# Driver Code
n = 3;
print(nswp(n));
  
# This code is contributed
# by mits

C#

// C# Program to find Newman–Shanks–Williams prime


  
using System;
  
class GFG {

2162
Chapter 295. Newman–Shanks–Williams prime

  
    // return nth Newman–Shanks–Williams prime
    static int nswp(int n)
    {
          
        int[] dp = new int[n + 1];
  
        // Base case
        dp[0] = dp[1] = 1;
  
        // Finding nth Newman–Shanks–Williams prime
        for (int i = 2; i <= n; i++)
            dp[i] = 2 * dp[i - 1] + dp[i - 2];
  
        return dp[n];
    }
  
    // Driver Program
    public static void Main()
    {
        int n = 3;
  
        Console.WriteLine(nswp(n));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program to find 
// Newman–Shanks–Williams prime
  
// return nth Newman–Shanks
// –Williams prime
function nswp($n)
{
      
    // Base case
    $dp[0] = $dp[1] = 1;
  
    // Finding nth Newman–Shanks
    // –Williams prime
    for ($i = 2; $i <= $n; $i++)
        $dp[$i] = 2 * $dp[$i - 1] + 
                      $dp[$i - 2];
  

2163
Chapter 295. Newman–Shanks–Williams prime

    return $dp[$n];
}
  
// Driver Code
$n = 3;
echo(nswp($n));
  
// This code is contributed by Ajit.
?>

Output:

Improved By : jit_t, Mithun Kumar

Source

https://www.geeksforgeeks.org/newman-shanks-williams-prime/

2164
Chapter 296

Non-crossing lines to connect


points in a circle

Non-crossing lines to connect points in a circle - GeeksforGeeks


Consider a circle with n points on circumference of it where n is even. Count number of
ways we can connect these points such that no two connecting lines to cross each other and
every point is connected with exactly one other point. Any point can be connected with
any other point.

Consider a circle with 4 points.


1
2 3
4
In above diagram, there are two
non-crossing ways to connect
{{1, 2}, {3, 4}} and {{1, 3}, {2, 4}}.

Note that {{2, 3}, {1, 4}} is invalid


as it would cause a cross

Examples :

Input : n = 2
Output : 1

Input : n = 4
Output : 2

Input : n = 6

2165
Chapter 296. Non-crossing lines to connect points in a circle

Output : 5

Input : n = 3
Output : Invalid
n must be even.

We need to draw n/2 lines to connect n points. When we draw a line, we divide the points
in two sets that need to connected. Each set needs to be connected within itself. Below is
recurrence relation for the same.

Let m = n/2

// For each line we draw, we divide points


// into two sets such that one set is going
// to be connected with i lines and other
// with m-i-1 lines.
Count(m) = &Sum; Count(i) * Count(m-i-1)
where 0 <= i < m
Count(0) = 1

Total number of ways with n points


= Count(m) = Count(n/2)

If we take a closer look at above recurrence, it is actually recurrence of Catalan Numbers.


So the task reduces to finding n/2’th Catalan number.
Below is implementation based on above idea.
C++

// C++ program to count number of ways to connect n (where n


// is even) points on a circle such that no two connecting
// lines cross each other and every point is connected with
// one other point.
#include<iostream>
using namespace std;
  
// A dynamic programming based function to find nth
// Catalan number
unsigned long int catalanDP(unsigned int n)
{
    // Table to store results of subproblems
    unsigned long int catalan[n+1];
  
    // Initialize first two values in table
    catalan[0] = catalan[1] = 1;
  

2166
Chapter 296. Non-crossing lines to connect points in a circle

    // Fill entries in catalan[] using recursive formula


    for (int i=2; i<=n; i++)
    {
        catalan[i] = 0;
        for (int j=0; j<i; j++)
            catalan[i] += catalan[j] * catalan[i-j-1];
    }
  
    // Return last entry
    return catalan[n];
}
  
// Returns count of ways to connect n points on a circle
// such that no two connecting lines cross each other and
// every point is connected with one other point.
unsigned long int countWays(unsigned long int n)
{
   // Throw error if n is odd
   if (n & 1)
   {
      cout << "Invalid";
      return 0;
   }
  
   // Else return n/2'th Catalan number
   return catalanDP(n/2);
}
  
// Driver program to test above function
int main()
{
    cout << countWays(6) << " ";
    return 0;
}

Java

// Java program to count number 


// of ways to connect n (where 
// n is even) points on a circle
// such that no two connecting
// lines cross each other and 
// every point is connected with
// one other point.
import java.io.*;
  
class GFG 
{

2167
Chapter 296. Non-crossing lines to connect points in a circle

  
// A dynamic programming 
// based function to find 
// nth Catalan number
static int catalanDP(int n)
{
    // Table to store 
    // results of subproblems
    int []catalan = new int [n + 1];
  
    // Initialize first
    // two values in table
    catalan[0] = catalan[1] = 1;
  
    // Fill entries in catalan[] 
    // using recursive formula
    for (int i = 2; i <= n; i++)
    {
        catalan[i] = 0;
        for (int j = 0; j < i; j++)
            catalan[i] += catalan[j] * 
                          catalan[i - j - 1];
    }
  
    // Return last entry
    return catalan[n];
}
  
// Returns count of ways to 
// connect n points on a circle
// such that no two connecting
// lines cross each other and
// every point is connected 
// with one other point.
static int countWays(int n)
{
    // Throw error if n is odd
    if (n < 1)
    {
        System.out.println("Invalid");
        return 0;
    }
  
    // Else return n/2'th 
    // Catalan number
    return catalanDP(n / 2);
}
  

2168
Chapter 296. Non-crossing lines to connect points in a circle

// Driver Code
public static void main (String[] args) 
{
    System.out.println(countWays(6) + " ");
}
}
  
// This code is contributed 
// by akt_mit

C#

// C# program to count number 


// of ways to connect n (where 
// n is even) points on a circle
// such that no two connecting
// lines cross each other and 
// every point is connected with
// one other point.
using System;
  
class GFG
{
      
// A dynamic programming 
// based function to find 
// nth Catalan number
static int catalanDP(int n)
{
    // Table to store 
    // results of subproblems
    int []catalan = new int [n + 1];
  
    // Initialize first
    // two values in table
    catalan[0] = catalan[1] = 1;
  
    // Fill entries in catalan[] 
    // using recursive formula
    for (int i = 2; i <= n; i++)
    {
        catalan[i] = 0;
        for (int j = 0; j < i; j++)
            catalan[i] += catalan[j] * 
                          catalan[i - j - 1];
    }
  
    // Return last entry

2169
Chapter 296. Non-crossing lines to connect points in a circle

    return catalan[n];
}
  
// Returns count of ways to 
// connect n points on a circle
// such that no two connecting
// lines cross each other and
// every point is connected 
// with one other point.
static int countWays(int n)
{
    // Throw error if n is odd
    if (n < 1)
    {
        Console.WriteLine("Invalid");
        return 0;
    }
  
    // Else return n/2'th 
    // Catalan number
    return catalanDP(n / 2);
}
  
// Driver Code
static public void Main ()
{
    Console.WriteLine(countWays(6) + " ");
}
}
  
// This code is contributed 
// by M_kit

PHP

<?php
// PHP program to count number of
// ways to connect n (where n is 
// even) points on a circle such 
// that no two connecting lines 
// cross each other and every 
// point is connected with one 
// other point.
  
// A dynamic programming based 
// function to find nth Catalan number
function catalanDP($n)
{

2170
Chapter 296. Non-crossing lines to connect points in a circle

    // Table to store results 


    // of subproblems Initialize 
    // first two values in table
    $catalan[0] = $catalan[1] = 1;
  
    // Fill entries in catalan[] 
    // using recursive formula
    for ($i = 2; $i <= $n; $i++)
    {
        $catalan[$i] = 0;
        for ($j = 0; $j < $i; $j++)
            $catalan[$i] += $catalan[$j] * 
                            $catalan[$i - $j - 1];
    }
  
    // Return last entry
    return $catalan[$n];
}
  
// Returns count of ways to connect 
// n points on a circle such that 
// no two connecting lines cross 
// each other and every point is 
// connected with one other point.
function countWays($n)
{
// Throw error if n is odd
if ($n & 1)
{
    echo "Invalid";
    return 0;
}
  
// Else return n/2'th
// Catalan number
return catalanDP($n / 2);
}
  
// Driver Code
echo countWays(6) , " ";
  
// This code is contributed by aj_36 
?>

Output :

2171
Chapter 296. Non-crossing lines to connect points in a circle

Time Complexity : O(n2 )


Auxiliary Space : O(n)
Improved By : jit_t

Source

https://www.geeksforgeeks.org/non-crossing-lines-connect-points-circle/

2172
Chapter 297

Non-decreasing subsequence of
size k with minimum sum

Non-decreasing subsequence of size k with minimum sum - GeeksforGeeks


Given a sequence of n integers, you have to find out the non-decreasing subsequence of
length k with minimum sum. If no sequence exists output -1.
Examples :

Input : [58 12 11 12 82 30 20 77 16 86],


k = 3
Output : 39
{11 + 12 + 16}

Input : [58 12 11 12 82 30 20 77 16 86],


k = 4
Output : 120
{11 + 12 + 20 + 77}

Input : [58 12 11 12 82 30 20 77 16 86],


k = 5
Output : 206

Let solve(i, k) be the minimum sum of a subsequence of size k ending at index i. Then there
would be two states:
1. Include current element. {solve(j, k-1) + a[i]}
2. Exclude current element. {solve(j, k)}
Our recurrence state would be:

dp[i][k] = min(solve(j, k-1) + a[i], solve(j, k))


if a[i] >= a[j] for all 0 <= j <= i.

2173
Chapter 297. Non-decreasing subsequence of size k with minimum sum

C++

// C++ program to find Non-decreasing sequence


// of size k with minimum sum
#include <bits/stdc++.h>
using namespace std;
const int MAX = 100;
const int inf = 2e9;
  
// Global table used for memoization
int dp[MAX][MAX];
  
void initialize()
{
    for (int i = 0; i < MAX; i++)
        for (int j = 0; j < MAX; j++)
            dp[i][j] = -1;
}
  
int solve(int arr[], int i, int k)
{
    // If already computed
    if (dp[i][k] != -1)
        return dp[i][k];
  
    // Corner cases
    if (i < 0)
        return inf;
    if (k == 1) {
        int ans = inf;
        for (int j = 0; j <= i; j++)
            ans = min(ans, arr[j]);
        return ans;
    }
  
    // Recursive computation.
    int ans = inf;
    for (int j = 0; j < i; j++)
        if (arr[i] >= arr[j])
            ans = min(ans, min(solve(arr, j, k),
                               solve(arr, j, k - 1) + arr[i]));
        else {
            ans = min(ans, solve(arr, j, k));
        }
  
    dp[i][k] = ans;
    return dp[i][k];
}

2174
Chapter 297. Non-decreasing subsequence of size k with minimum sum

  
// Driver code
int main()
{
    initialize();
    int a[] = { 58, 12, 11, 12, 82, 30,
                20, 77, 16, 86 };
    int n = sizeof(a) / sizeof(a[0]);
    int k = 4;
    cout << solve(a, n - 1, k) << endl;
    return 0;
}

Java

// Java program to find Non-decreasing sequence


// of size k with minimum sum
import java.io.*;
import java.util.*;
  
class GFG {
    public static int MAX = 100;
    public static int inf = 1000000;
  
    // Table used for memoization
    public static int[][] dp = new int[MAX][MAX];
  
    // intialize
    static void initialize()
    {
        for (int i = 0; i < MAX; i++)
            for (int j = 0; j < MAX; j++)
                dp[i][j] = -1;
    }
  
    // Function to find non-decreasing sequence
    // of size k with minimum sum
    static int solve(int arr[], int i, int k)
    {
        // If already computed
        if (dp[i][k] != -1)
            return dp[i][k];
  
        // Corner cases
        if (i < 0)
            return inf;
        if (k == 1) {
            int ans = inf;

2175
Chapter 297. Non-decreasing subsequence of size k with minimum sum

            for (int j = 0; j <= i; j++)


                ans = Math.min(ans, arr[j]);
            return ans;
        }
  
        // Recursive computation
        int ans = inf;
        for (int j = 0; j < i; j++)
            if (arr[i] >= arr[j])
                ans = Math.min(ans, Math.min(solve(arr, j, k), solve(arr, j, k - 1) + arr[i]));
            else
                ans = Math.min(ans, solve(arr, j, k));
  
        dp[i][k] = ans;
  
        return dp[i][k];
    }
  
    // driver program
    public static void main(String[] args)
    {
        initialize();
        int a[] = { 58, 12, 11, 12, 82, 30,
                    20, 77, 16, 86 };
        int n = a.length;
        int k = 4;
        System.out.println(solve(a, n - 1, k));
    }
}
  
// Contributed by Pramod Kumar

Python

# Python program to find Non-decreasing sequence


# of size k with minimum sum
   
# Global table used for memoization
dp = []
for i in xrange(10**2 + 1):
    temp = [-1]*(10**2 + 1)
    dp.append(temp)
   
def solve(a, i, k):
    if dp[i][k] != -1:  # Memoization
        return dp[i][k]
    elif i < 0: # out of bounds
        return float('inf')

2176
Chapter 297. Non-decreasing subsequence of size k with minimum sum

   
    # when there is only one element
    elif k == 1:    
        return min(a[: i + 1])
   
    # Else two cases
    # 1 include current element 
    # solve(a, j, k-1) + a[i]
    # 2 ignore current element 
    # solve(a, j, k)
    else:  
        ans = float('inf')
        for j in xrange(i):
            if a[i] >= a[j]:
                ans = min(ans, solve(a, j, k), solve(a, j, k-1) + a[i])
            else:
                ans = min(ans, solve(a, j, k))
        dp[i][k] = ans
        return dp[i][k]
   
# Driver code
a = [58, 12, 11, 12, 82, 30, 20, 77, 16, 86]        
print solve(a, len(a)-1, 4)

C#

// C# program to find Non-decreasing sequence


// of size k with minimum sum
using System;
  
class GFG {
      
    public static int MAX = 100;
    public static int inf = 1000000;
  
    // Table used for memoization
    public static int[, ] dp = new int[MAX, MAX];
  
    // intialize
    static void initialize()
    {
        for (int i = 0; i < MAX; i++)
          for (int j = 0; j < MAX; j++)
            dp[i, j] = -1;
    }
  
    // Function to find non-decreasing 
    // sequence of size k with minimum sum

2177
Chapter 297. Non-decreasing subsequence of size k with minimum sum

    static int solve(int[] arr, int i, int k)


    {
        int ans = 0;
          
        // If already computed
        if (dp[i, k] != -1)
            return dp[i, k];
  
        // Corner cases
        if (i < 0)
            return inf;
        if (k == 1)
        {
            ans = inf;
            for (int j = 0; j <= i; j++)
            ans = Math.Min(ans, arr[i]);
            return ans;
        }
  
        // Recursive computation
        ans = inf;
        for (int j = 0; j < i; j++)
            if (arr[i] >= arr[j])
                ans = Math.Min(ans, Math.Min(solve(arr, j, k),
                               solve(arr, j, k - 1) + arr[i]));
            else
                ans = Math.Min(ans, solve(arr, j, k));
  
        dp[i, k] = ans;
  
        return dp[i, k];
    }
  
    // driver program
    public static void Main()
    {
        initialize();
        int[] a = { 58, 12, 11, 12, 82, 30,
                          20, 77, 16, 86 };
        int n = a.Length;
        int k = 4;
        Console.WriteLine(solve(a, n - 1, k));
    }
}
  
// This code is contributed by vt_m

2178
Chapter 297. Non-decreasing subsequence of size k with minimum sum

120

Improved By : vt_m, valarMorghulis18

Source

https://www.geeksforgeeks.org/non-decreasing-subsequence-of-size-k-with-minimum-sum/

2179
Chapter 298

Number of Co-prime pairs


obtained from the sum of digits
of elements in the given range

Number of Co-prime pairs obtained from the sum of digits of elements in the given range -
GeeksforGeeks
Given two numbers A and B where 1 <= A <= B. The task is to count the number of
pairs whose elements are co-prime where pairs are formed from the sum of the digits of the
elements in the given range.

Note: Two pairs are counted as distinct if at least one of the number in the pair is
different. It may be assumed that the maximum digit sum can be 162.
Examples:

Input: 12 15
Output: 4
12 = 1+2 = 3
13 = 1+3 = 4
14 = 1+4 = 5
15 = 1+5 = 6
Thus pairs who are co-prime to each other are
(3, 4), (3, 5), (4, 5), (5, 6)
i.e the answer is 4.

Input: 7 10
Output: 5

Method-1:

2180
Chapter 298. Number of Co-prime pairs obtained from the sum of digits of elements in the
given range

• Consider each and every element from a to b.


• Find the sum of the digits of every element and store it into a vector.
• Consider each and every pair one by one and check if the gcd of the elements of that
pair is 1.
• If yes, count that pair as it is co-prime.
• Print the count of pairs that are co-prime.

Below is the implementation of above approach:

C++

// C++ program to count the pairs 


// whose sum of digits is co-prime 
#include <bits/stdc++.h> 
using namespace std; 
  
// Function to find the elements 
// after doing the sum of digits
int makePairs(vector<int> &pairs, int a, int b) 
{
      
    // Traverse from a  to b
    for (int i = a; i <= b; i++)
    {
          
    // Find the sum of the digits of the elements
    // in the given range one by one
      int sumOfDigits = 0, k = i;
      while(k>0)
      {
          sumOfDigits += k%10;
          k /= 10;
      }
      if (sumOfDigits <= 162)
      pairs.push_back(sumOfDigits);
    }
}
  
// Function to count the co-prime pairs
int countCoPrime(int a, int b){
    vector<int> pairs;
      
    // Function to make the pairs 
    // by doing the sum of digits
    makePairs(pairs, a, b);
    int count = 0;
      

2181
Chapter 298. Number of Co-prime pairs obtained from the sum of digits of elements in the
given range

    // Count pairs that are co-primes


    for(int i = 0; i < pairs.size(); i++)
       for (int j = i+1; j < pairs.size(); j++)
          if (__gcd(pairs[i], pairs[j]) == 1)
                 count++;
               
   return count;
      
}
  
// Driver code 
int main() 

    int a = 12, b = 15; 
  
    // Function to count the pairs 
    cout << countCoPrime(a, b) ;
  
    return 0; 

Java

// Java program to count the pairs 


// whose sum of digits is co-prime 
import java.util.*;
  
class GFG
{
static int GCD(int a, int b) 
{
if (b == 0) return a;
return GCD(b, a % b);
}
// Function to find the elements 
// after doing the sum of digits
static void makePairs(Vector<Integer> pairs, 
                      int a, int b) 
{
      
    // Traverse from a to b
    for (int i = a; i <= b; i++)
    {
          
    // Find the sum of the digits 
    // of the elements in the given 
    // range one by one
    int sumOfDigits = 0, k = i;

2182
Chapter 298. Number of Co-prime pairs obtained from the sum of digits of elements in the
given range

    while(k > 0)
    {
        sumOfDigits += k % 10;
        k /= 10;
    }
    if (sumOfDigits <= 162)
        pairs.add(sumOfDigits);
    }
}
  
// Function to count 
// the co-prime pairs
static int countCoPrime(int a, int b)
{
    Vector<Integer> pairs = new Vector<Integer>();
      
    // Function to make the pairs 
    // by doing the sum of digits
    makePairs(pairs, a, b);
    int count = 0;
      
    // Count pairs that are co-primes
    for(int i = 0; i < pairs.size(); i++)
    for (int j = i+1; j < pairs.size(); j++)
        if (GCD(pairs.get(i), 
                pairs.get(j)) == 1)
                count++;
              
return count;
      
}
  
// Driver code 
public static void main(String args[])

    int a = 12, b = 15; 
  
    // Function to count the pairs 
    System.out.println(countCoPrime(a, b));

}
  
// This code is contributed by Arnab Kundu

Output:

2183
Chapter 298. Number of Co-prime pairs obtained from the sum of digits of elements in the
given range

Method-2:
As mentioned in the question, the maximum sum can be 162. So, find out the frequency of
numbers having their digit sum from 1 to 162 in range A to B and store the frequency in
the array. Later, find the answer using this frequency.
Since,

Number, Frequency
1, 0
2, 0
3, 1
4, 1
5, 1
6, 1
7, 0
8, 0
., .
., .
162, 0
Thus Number of gcd pairs = freq(3)*freq(4) + freq(3)*freq(5) + freq(4)*freq(5)
+ freq(5)* freq(6)
= 1+1+1+1
=4

Thus pairs who are co-prime to each other are (3,4), (3,5), (4,5), (5,6) i.e the answer is 4.
Below is the required implementation:

// C++ program to count the pairs


// whose sum of digits is co-prime
#include <bits/stdc++.h>
#define ll long long int
using namespace std;
  
// Recursive function to return the frequency
// of numbers having their sum of digits i
ll recursive(ll idx, ll sum, ll tight, string st,
             ll dp[20][2][166], ll num)
{
    if (idx == num)
        // Returns 1 or 0
        return sum == 0;
  
    // Returns value of the dp if already stored
    if (dp[idx][tight][sum] != -1)
        return dp[idx][tight][sum];
  
    bool newTight;
    ll ans = 0;

2184
Chapter 298. Number of Co-prime pairs obtained from the sum of digits of elements in the
given range

    ll d;
  
    // Loop from digit 0 to 9
    for (d = 0; d < 10; ++d) {
        newTight = false;
        if (tight && st[idx] - '0' < d)
            continue;
  
        // To change the tight to 1
        if (tight && st[idx] - '0' == d)
            newTight = true;
  
        // Calling the recursive function to find the frequency
        if (sum >= d)
            ans += recursive(idx + 1, sum - d,
                             newTight, st, dp, num);
    }
  
    return dp[idx][tight][sum] = ans;
}
  
// Function to find out frequency of numbers
// from 1 to N having their sum of digits
// from 1 to 162 and store them in array
vector<ll> formArray(ll N)
{
    ll dp[20][2][166];
    memset(dp, -1, sizeof dp);
  
    // Number to string conversion
    ostringstream x;
    x << N;
    string st = x.str();
    ll num = st.size();
  
    vector<ll> arr;
    for (int i = 1; i <= 162; ++i) {
  
        // Calling the recursive function
        // and pushing it into array
        arr.push_back(recursive(0, i, 1, st, dp, num));
    }
  
    return arr;
}
  
// Function to find the pairs
ll findPair(ll a, ll b)

2185
Chapter 298. Number of Co-prime pairs obtained from the sum of digits of elements in the
given range

{
    // Calling the  formArray function of a-1 numbers
    vector<ll> arr_smaller = formArray(a - 1);
  
    // Calling the  formArray function of b numbers
    vector<ll> arr_greater = formArray(b);
  
    // Subtracting the frequency of higher number array with lower
    // number array and thus finding the range of
    // numbers from a to b having sum from 1 to 162
    for (int i = 0; i < arr_greater.size(); ++i)
        arr_greater[i] -= arr_smaller[i];
  
    int ans = 0;
    for (int i = 1; i <= 162; ++i) {
        for (int j = i + 1; j <= 162; ++j) {
  
            // To find out total number of pairs
            // which are co-prime
            if (__gcd(i, j) == 1)
                ans = (ans + arr_greater[i - 1] * arr_greater[j - 1]);
        }
    }
  
    return ans;
}
  
// Driver code
int main()
{
    ll a = 12, b = 15;
  
    // Function to count the pairs
    cout << findPair(a, b);
  
    return 0;
}

Output:

Improved By : andrew1234

Source
https://www.geeksforgeeks.org/number-of-co-prime-pairs-obtained-from-the-sum-of-digits-of-elements-in-the-given

2186
Chapter 299

Number of NGEs to the right

Number of NGEs to the right - GeeksforGeeks


Given an array of n integers and q queries, print the number of next greater elements to the
right of the given index element.
Examples:

Input : a[] = {3, 4, 2, 7, 5, 8, 10, 6}


q = 2
index = 0,
index = 5
Output: 4
1
Explanation: the next greater elements
to the right of 3(index 0) are 4, 7, 8,
10. The next greater elements to the right
of 8(index 5) are 10.

A naive approach is to iterate for every query from index to end, and find out the number
of next greater elements to the right. This won’t be efficient enough as we run two nested
loops .
Time complexity: O(n) to answer a query.
Auxiliary space: O(1)
Better approach is to store the next greater index of every element and run a loop for
every query that iterates from index and keeping the increasing counter as j = next[i]. This
will avoid checking all elements and will directly jump to the next greater element of every
element. But this won’t be efficient enough in cases like 1 2 3 4 5 6, where the next greater
elements are sequentially increasing, ending it up in taking O(n) for every query.
Time complexity : O(n) to answer a query.
Auxiliary space : O(n) for next greater element.

2187
Chapter 299. Number of NGEs to the right

Efficient approach is to store the next greater elements index using next greater element
in a next[] array. Then create a dp[] array that starts from n-2, as n-1th index will have
no elements to its right and dp[n-1] = 0. While traversing from back we use dynamic
programming to count the number of elements to the right where we use memoization as
dp[next[i]] which gives us a count of the numbers to the right of the next greater element of
the current element, hence we add 1 to it. If next[i]=-1 then we do not have any element to
the right hence dp[i]=0. dp[index] stores the count of the number of next greater elements
to the right.
Below is the c++ implementation of the above approach

#include <bits/stdc++.h>
using namespace std;
  
// array to store the next greater element index
void fillNext(int next[], int a[], int n)
{
    // use of stl stack in c++
    stack<int> s;
  
    // push the 0th index to the stack
    s.push(0);
  
    // traverse in the loop from 1-nth index
    for (int i = 1; i < n; i++) {
  
        // iterate till loop is empty
        while (!s.empty()) {
  
            // get the topmost index in the stack
            int cur = s.top();
  
            // if the current element is greater
            // then the top index-th element, then
            // this will be the next greatest index
            // of the top index-th element
            if (a[cur] < a[i]) {
  
                // initialize the cur index position's
                // next greatest as index
                next[cur] = i;
  
                // pop the cur index as its greater
                // element has been found
                s.pop();
            }
  
            // if not greater then break
            else

2188
Chapter 299. Number of NGEs to the right

                break;
        }
  
        // push the i index so that its next greatest
        // can be found
        s.push(i);
    }
  
    // iterate for all other index left inside stack
    while (!s.empty()) {
  
        int cur = s.top();
  
        // mark it as -1 as no element in greater
        // then it in right
        next[cur] = -1;
  
        s.pop();
    }
}
  
// function to count the number of next greater numbers to the right
void count(int a[], int dp[], int n)
{
    // initializes the next array as 0
    int next[n];
    memset(next, 0, sizeof(next));
  
    // calls the function to pre-calculate
    // the next greatest element indexes
    fillNext(next, a, n);
  
    for (int i = n - 2; i >= 0; i--) {
  
        // if the i-th element has no next
        // greater element to right
        if (next[i] == -1)
            dp[i] = 0;
  
        // Count of next greater numbers to right.
        else
            dp[i] = 1 + dp[next[i]];
    }
}
  
// answers all queries in O(1)
int answerQuery(int dp[], int index)
{

2189
Chapter 299. Number of NGEs to the right

    // returns the number of next greater


    // elements to the right.
    return dp[index];
}
  
// driver program to test the above function
int main()
{
    int a[] = { 3, 4, 2, 7, 5, 8, 10, 6 };
    int n = sizeof(a) / sizeof(a[0]);
  
    int dp[n];
  
    // calls the function to count the number
    // of greater elements to the right for
    // every element.
    count(a, dp, n);
  
    // query 1 answered
    cout << answerQuery(dp, 3) << endl;
  
    // query 2 answered
    cout << answerQuery(dp, 6) << endl;
  
    // query 3 answered
    cout << answerQuery(dp, 1) << endl;
  
    return 0;
}

Output:

2
0
3

Time complexity: O(1) to answer a query.


Auxiliary Space: O(n)

Source

https://www.geeksforgeeks.org/number-nges-right/

2190
Chapter 300

Number of Unique BST with a


given key | Dynamic
Programming

Number of Unique BST with a given key | Dynamic Programming - GeeksforGeeks


Given N, Find the total number of unique BSTs that can be made using values from 1 to
N.

Examples:

Input: n = 3
Output: 5
For n = 3, preorder traversal of Unique BSTs are:
1. 1 2 3
2. 1 3 2
3. 2 1 3
4. 3 1 2
5. 3 2 1

Input: 4
Output: 14

In the previous post a O(n) solution has been discussed. In this post we will discuss a
solution based on Dynamic Programming. For all possible values of i, consider i as root,
then [1….i-1] numbers will fall in the left subtree and [i+1….n] numbers will fall in the right
subtree. So, add (i-1)*(n-i) to the answer. The summation of the products will be the
answer to the number of unique BST.
Below is the implementation for above approach:

2191
Chapter 300. Number of Unique BST with a given key | Dynamic Programming

C++

// C++ code to find number of unique BSTs


// Dynamic Programming solution
#include <bits/stdc++.h>
using namespace std;
  
// Function to find number of unique BST
int numberOfBST(int n)
{
  
    // DP to store the number of unique BST with key i
    int dp[n + 1];
    fill_n(dp, n + 1, 0);
  
    // Base case
    dp[0] = 1;
    dp[1] = 1;
  
    // fill the dp table in top-down approach.
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= i; j++) {
  
            // n-i in right * i-1 in left
            dp[i] = dp[i] + (dp[i - j] * dp[j - 1]);
        }
    }
  
    return dp[n];
}
  
// Driver Code
int main()
{
    int n = 3;
    cout << "Number of structurally Unique BST with " << 
    n << " keys are : " << numberOfBST(n) << "\n";
  
    return 0;
}

Java

// Java code to find number


// of unique BSTs Dynamic 
// Programming solution
import java.io.*;

2192
Chapter 300. Number of Unique BST with a given key | Dynamic Programming

import java.util.Arrays;
  
class GFG
{
    static int numberOfBST(int n)
    {
  
    // DP to store the number 
    // of unique BST with key i
    int dp[] = new int[n + 1];
    Arrays.fill(dp, 0);
  
    // Base case
    dp[0] = 1;
    dp[1] = 1;
  
    // fill the dp table in
    // top-down approach.
    for (int i = 2; i <= n; i++) 
    {
        for (int j = 1; j <= i; j++) 
        {
  
            // n-i in right * i-1 in left
            dp[i] = dp[i] + (dp[i - j] * 
                             dp[j - 1]);
        }
    }
  
    return dp[n];
}
  
// Driver Code
public static void main (String[] args) 
{
    int n = 3;
    System.out.println("Number of structurally " + 
                           "Unique BST with "+ n +
                                  " keys are : " + 
                                  numberOfBST(n));
}
}
  
// This code is contributed
// by shiv_bhakt.

C#

2193
Chapter 300. Number of Unique BST with a given key | Dynamic Programming

// C# code to find number


// of unique BSTs Dynamic 
// Programming solution
using System;
  
class GFG
{
    static int numberOfBST(int n)
    {
  
    // DP to store the number 
    // of unique BST with key i
    int []dp = new int[n + 1];
      
    // Base case
    dp[0] = 1;
    dp[1] = 1;
  
    // fill the dp table in
    // top-down approach.
    for (int i = 2; i <= n; i++) 
    {
        for (int j = 1; j <= i; j++) 
        {
  
            // n-i in right * i-1 in left
            dp[i] = dp[i] + (dp[i - j] * 
                             dp[j - 1]);
        }
    }
    return dp[n];
}
  
// Driver Code
public static void Main () 
{
    int n = 3;
    Console.Write("Number of structurally " + 
                      "Unique BST with "+ n +
                             " keys are : " + 
                             numberOfBST(n));
}
}
  
// This code is contributed
// by shiv_bhakt.

PHP

2194
Chapter 300. Number of Unique BST with a given key | Dynamic Programming

<?php
// PHP code to find number 
// of unique BSTs Dynamic
// Programming solution
  
// Function to find number 
// of unique BST
function numberOfBST($n)
{
  
    // DP to store the number 
    // of unique BST with key i
    $dp = array($n + 1);
    for($i = 0; $i <= $n + 1; $i++)
    $dp[$i] = 0;
  
    // Base case
    $dp[0] = 1;
    $dp[1] = 1;
  
    // fill the dp table 
    // in top-down approach.
    for ($i = 2; $i <= $n; $i++) 
    {
        for ($j = 1; $j <= $i; $j++) 
        {
  
            // n-i in right * 
            // i-1 in left
            $dp[$i] += (($dp[$i - $j]) * 
                        ($dp[$j - 1]));
        }
    }
  
    return $dp[$n];
}
  
// Driver Code
$n = 3;
echo "Number of structurally ". 
           "Unique BST with " , 
          $n , " keys are : " , 
              numberOfBST($n) ;
  
// This code is contributed
// by shiv_bhakt.
?>

2195
Chapter 300. Number of Unique BST with a given key | Dynamic Programming

Output:

Number of structurally Unique BST with 3 keys are : 5

Time Complexity: O(n2 )


Improved By : shiv_bhakt

Source

https://www.geeksforgeeks.org/number-of-unique-bst-with-a-given-key-dynamic-programming/

2196
Chapter 301

Number of arrays of size N


whose elements are positive
integers and sum is K

Number of arrays of size N whose elements are positive integers and sum is K - GeeksforGeeks
Given two positive integers N and K. The task is to find the number of arrays of size N
that can be formed such that elements of the array should be positive integers and the sum
of elements is equal to K.
Examples:

Input : N = 2, K = 3
Output : 2
Explanation: [1, 2] and [2, 1] are the only arrays of size 2 whose sum is 3.

Input : n = 3, k = 7
Output : 15

Prerequisite: Stars and Bars


Suppose there are K identical objects which needs to be placed in N bins (N indices of
the array) such that each bin have at least one object. Instead of starting to place objects
into bins, we start placing the objects on a line, where the object for the first bin will be
taken from the left, followed by the objects for the second bin, and so forth. Thus, the
configuration will be determined once one knows what is the first object going to the second
bin, and the first object going to the third bin, and so on. We can indicate this by placing
N X 1 separating bars at some places between two objects; since no bin is allowed to be
empty, there can be at most one bar between a given pair of objects. So, we have K objects
in a line with K – 1 gaps. Now we have to choose N – 1 gaps to place bars from K – 1 gaps.
This can be chosen by K – 1 CN – 1 .

2197
Chapter 301. Number of arrays of size N whose elements are positive integers and sum is
K

Below is implementation of this approach:

C++

// CPP Program to find the number of arrays of


// size N whose elements are positive integers
// and sum is K
#include <bits/stdc++.h>
using namespace std;
  
// Return nCr
int binomialCoeff(int n, int k)
{
    int C[k + 1];
    memset(C, 0, sizeof(C));
  
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++) {
        // Compute next row of pascal triangle using
        // the previous row
        for (int j = min(i, k); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
    return C[k];
}
  
// Return the number of array that can be
// formed of size n and sum equals to k.
int countArray(int N, int K)
{
    return binomialCoeff(K - 1, N - 1);
}
  
// Driver Code
int main()
{
    int N = 2, K = 3;
  
    cout << countArray(N, K) << endl;
  
    return 0;
}

Java

// Java Program to find the 

2198
Chapter 301. Number of arrays of size N whose elements are positive integers and sum is
K

// number of arrays of size 


// N whose elements are positive 
// integers and sum is K
import java.io.*;
  
class GFG 
{
      
// Return nCr
static int binomialCoeff(int n, 
                         int k)
{
    int []C = new int[k + 1];
  
  
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++) 
    {
        // Compute next row of pascal 
        // triangle using the previous row
        for (int j = Math.min(i, k); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
    return C[k];
}
  
// Return the number of 
// array that can be 
// formed of size n and
// sum equals to k.
static int countArray(int N, int K)
{
    return binomialCoeff(K - 1, N - 1);
}
  
// Driver Code
public static void main (String[] args) 
{
        int N = 2, K = 3;
  
System.out.println( countArray(N, K));
}
}
  
// This code is contributed by anuj_67.

C#

2199
Chapter 301. Number of arrays of size N whose elements are positive integers and sum is
K

// C# Program to find the 


// number of arrays of size 
// N whose elements are positive 
// integers and sum is K
using System;
  
class GFG
{
// Return nCr
static int binomialCoeff(int n, 
                         int k)
{
    int []C = new int[k + 1];
  
  
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++) 
    {
        // Compute next row of 
        // pascal triangle using 
        // the previous row
        for (int j = Math.Min(i, k); 
                         j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
    return C[k];
}
  
// Return the number of 
// array that can be 
// formed of size n and
// sum equals to k.
static int countArray(int N, 
                      int K)
{
    return binomialCoeff(K - 1, 
                         N - 1);
}
  
// Driver Code
static public void Main ()
{
    int N = 2, K = 3;
  
    Console.WriteLine( 
            countArray(N, K));
}

2200
Chapter 301. Number of arrays of size N whose elements are positive integers and sum is
K

}
  
// This code is contributed by ajit

PHP

<?php
// PHP Program to find the 
// number of arrays of size 
// N whose elements are 
// positive integers and 
// sum is K
  
// Return nCr
function binomialCoeff($n, $k)
{
    $C = array_fill(0, ($k + 1), 0);
      
    $C[0] = 1; // nC0 is 1
  
    for ($i = 1; $i <= $n; $i++)
    {
        // Compute next row 
        // of pascal triangle 
        // using the previous row
        for ($j = min($i, $k); 
             $j > 0; $j--)
            $C[$j] = $C[$j] + 
                     $C[$j - 1];
    }
    return $C[$k];
}
  
// Return the number of 
// array that can be
// formed of size n and 
// sum equals to k.
function countArray($N, $K)
{
    return binomialCoeff($K - 1, 
                         $N - 1);
}
  
// Driver Code
$N = 2;
$K = 3;
  
echo countArray($N, $K);

2201
Chapter 301. Number of arrays of size N whose elements are positive integers and sum is
K

  
// This code is contributed by mits
?>

Output:

Improved By : vt_m, jit_t, Mithun Kumar

Source

https://www.geeksforgeeks.org/number-arrays-size-n-whose-elements-positive-integers-sum-k/

2202
Chapter 302

Number of circular tours that


visit all petrol pumps

Number of circular tours that visit all petrol pumps - GeeksforGeeks


Suppose there is a circular road. There are n petrol pumps on that road. You are given two
array, a[] and b[], and a positive integer c. where a[i] denote the amount of fuel we get on
reaching ith petrol pump, b[i] denote the amount of fuel used to travel from ith petrol pump
to (i + 1)th petrol pump and c denotes the capacity of the tank in the vehicle. The task is
to calculate the number of petrol pump from where the vehicle will be able to complete the
circle and come back to starting point.
This post is different from Find the first circular tour that visits all petrol pumps.
Examples:

Input : n = 3, c = 3
a[] = { 3, 1, 2 }
b[] = { 2, 2, 2 }
Output : 2
Explanation:
If we starts with 0th petrol pump, we will gain
3 (a[0]) litres of petrol and lose 2 litre (b[0] to travel
to 1st petrol pump.On refueling 1 litre (a[1])
of petrol on 1st petrol pump, we will lose 2
litres (b[0]) of petrol to reach 2nd petrol pump.
Now the tank is empty.On refueling 2 litres (a[2]) of petrol
at 2nd petrol pump, we can travel back 0th
petrol pump.
If we starts from 1st petrol pump, we will gain 1
litre of petrol but to travel to 2nd petrol pump
we need 2 litres of petrol, which we don’t have. So, we cannot
starts from 1st petrol pump.
If we starts from 2nd petrol pump, we will gain 2
litres of petrol and travel to 0th petrol pump by

2203
Chapter 302. Number of circular tours that visit all petrol pumps

losing 2 litres of petrol. On refueling 3 litres on 1st


petrol pump, we can travel to 1st petrol
pump by losing 2 litre petrol. On refueling 1 litre of petrol, we
will have 2 litres of petrol left which we can use by traveling to
2nd petrol pump.
Input : n = 3, c = 3
a[] = { 3, 1, 2 }
b[] = { 2, 2, 1 }
Output : 2

Approach:
The problem involves 2 parts, first involves if a valid starting petrol pump exists and second,
if such a petrol pump exists, check if the petrol pump before it can also be used as a starting
petrol pump.
First, lets start from a petrol pump s and travel to petrol pump, s + 1, s + 2, s + 3 till
s + j, suppose we run out of fuel before we go to petrol pump s + j + 1, then no petrol
pump between s and s + j can be used as starting petrol pump. Hence, we start over with
s + j + 1 as the starting petrol pump. If no such petrol pump exists after all petrol pumps
are exhausted, the answer is 0. This step takes O(n).
Second, lets visit one such valid petrol pump (lets call it s). The petrol pump before s i.e s
– 1 can also be a start petrol pump provided the vehicle can start at s – 1 and reach s.
If a[i] is take fuel available at petrol pump i, and c be the capacity of the fuel tank, and
b[i] is the amount of fuel the vehicle takes to travel from petrol pump i to i + 1, then lets
define need[i] as follows:

need[i] = max(0, need[i + 1] + b[i] - min(c, a[i]))

need[i] is the extra fuel, if present in the vehicle at the beginning of the journey at petrol
pump i (excluding a[i]_, it can be a valid petrol pump.
If need[i] = 0, then petrol pump i is a valid starting petrol pump. We know that need[s] =
0 from step 1. We can evaluate if s – 1, s – 2, … are starting petrol pumps are not. This
step also takes O(n).

// C++ Program to find the number of


// circular tour that visits all petrol pump
#include <bits/stdc++.h>
using namespace std;
#define N 100
  
// Return the number of pumps from where we
// can start the journey.
int count(int n, int c, int a[], int b[])
{
    int need[N];
  

2204
Chapter 302. Number of circular tours that visit all petrol pumps

    // Making Circular Array.


    for (int i = 0; i < n; i++) {
        a[i + n] = a[i];
        b[i + n] = b[i];
    }
  
    int s = 0;
    int tank = 0;
  
    // for each of the petrol pump.
    for (int i = 0; i < 2 * n; i++) {
        tank += a[i];
        tank = min(tank, c);
        tank -= b[i];
  
        // If tank is less than 0.
        if (tank < 0) {
            tank = 0;
            s = i + 1;
        }
    }
  
    // If starting pump is greater than n,
    // return ans as 0.
    if (s >= n)
        return 0;
  
    int ans = 1;
    need[s + n] = 0;
  
    // For each of the petrol pump
    for (int i = 1; i < n; i++) {
        int id = s + n - i;
  
        // Finding the need array
        need[id] = max(0, need[id + 1] + b[id]
                              - min(a[id], c));
  
        // If need is 0, increment the count.
        if (need[id] == 0)
            ans++;
    }
  
    return ans;
}
  
// Drivers code
int main()

2205
Chapter 302. Number of circular tours that visit all petrol pumps

{
    int n = 3;
    int c = 3;
    int a[2 * N] = { 3, 1, 2 };
    int b[2 * N] = { 2, 2, 2 };
  
    cout << count(n, c, a, b) << endl;
    return 0;
}

Output:

Time Complexity: O(n)


Reference:
https://stackoverflow.com/questions/24408371/dynamic-programming-find-possible-ways-to-reach-destination

Source

https://www.geeksforgeeks.org/number-of-circular-tours-that-visit-all-petrol-pumps/

2206
Chapter 303

Number of decimal numbers of


length k, that are strict
monotone

Number of decimal numbers of length k, that are strict monotone - GeeksforGeeks

We call decimal number a monotone if:


Write a program which takes positive number n on input and returns number of decimal
numbers of length n that are strict monotone. Number can’t start with 0.
Examples :

Input : 2
Output : 36
Numbers are 12, 13, ... 19, 23
24, ... 29, .... 89.

Input : 3
Output : 84

Explanations of this problem follows the same rules as applied on:


Number of decimal numbers of length k, that are monotone
The only difference is that now we cannot take duplicates, so previously computed values
are the one on the left and left top diagonal.
C++

// CPP program to count numbers of k


// digits that are strictly monotone.

2207
Chapter 303. Number of decimal numbers of length k, that are strict monotone

#include <cstring>
#include <iostream>
  
int static const DP_s = 9;
  
int getNumStrictMonotone(int len)
{
    // DP[i][j] is going to store monotone
    // numbers of length i+1 considering
    // j+1 digits (1, 2, 3, ..9)
    int DP[len][DP_s];
    memset(DP, 0, sizeof(DP));
   
    // Unit length numbers
    for (int i = 0; i < DP_s; ++i) 
        DP[0][i] = i + 1;    
  
    // Building dp[] in bottom up
    for (int i = 1; i < len; ++i) 
        for (int j = 1; j < DP_s; ++j) 
            DP[i][j] = DP[i - 1][j - 1] + DP[i][j - 1];        
      
    return DP[len - 1][DP_s - 1];
}
  
// Driver code
int main()
{
    std::cout << getNumStrictMonotone(2); 
    return 0;
}

Java

// Java program to count numbers of k


// digits that are strictly monotone.
import java.io.*;
import java.util.*;
  
class GFG {
  
    static int DP_s = 9;
      
    static int getNumStrictMonotone(int len) 
    {
        // DP[i][j] is going to store monotone
        // numbers of length i+1 considering
        // j+1 digits (1, 2, 3, ..9)

2208
Chapter 303. Number of decimal numbers of length k, that are strict monotone

        int[][] DP = new int[len][DP_s];


      
        // Unit length numbers
        for (int i = 0; i < DP_s; ++i)
        DP[0][i] = i + 1;
      
        // Building dp[] in bottom up
        for (int i = 1; i < len; ++i)
             for (int j = 1; j < DP_s; ++j)
                DP[i][j] = DP[i - 1][j - 1] 
                             + DP[i][j - 1];
      
        return DP[len - 1][DP_s - 1];
    }
    public static void main(String[] args) 
    {
        int n = 2;
        System.out.println(getNumStrictMonotone(n));
    }
}
  
// This code is contributed by Gitanjali.

Python3

# Python3 program to count numbers of k


# digits that are strictly monotone.
  
DP_s = 9
  
def getNumStrictMonotone(ln):
      
    # DP[i][j] is going to store monotone
    # numbers of length i+1 considering
    # j+1 digits (1, 2, 3, ..9)
    DP = [[0] * DP_s for _ in range(ln)]
  
    # Unit length numbers
    for i in range(DP_s):
        DP[0][i] = i + 1 
  
    # Building dp[] in bottom up
    for i in range(1, ln):
          
        for j in range(1, DP_s):
              
            DP[i][j] = DP[i - 1][j - 1] + DP[i][j - 1]     
      

2209
Chapter 303. Number of decimal numbers of length k, that are strict monotone

    return DP[ln - 1][DP_s - 1]


  
# Driver code
print(getNumStrictMonotone(2))
  
  
# This code is contributed by Ansu Kumari.

C#

// C# program to count numbers of k


// digits that are strictly monotone.
using System;
  
class GFG {
  
    static int DP_s = 9;
      
    static int getNumStrictMonotone(int len) 
    {
        // DP[i][j] is going to store monotone
        // numbers of length i+1 considering
        // j+1 digits (1, 2, 3, ..9)
        int[,] DP = new int[len,DP_s];
      
        // Unit length numbers
        for (int i = 0; i < DP_s; ++i)
        DP[0,i] = i + 1;
      
        // Building dp[] in bottom up
        for (int i = 1; i < len; ++i)
            for (int j = 1; j < DP_s; ++j)
                DP[i,j] = DP[i - 1,j - 1] 
                            + DP[i,j - 1];
      
        return DP[len - 1,DP_s - 1];
    }
      
    // Driver code
    public static void Main() 
    {
        int n = 2;
        Console.WriteLine(getNumStrictMonotone(n));
    }
}
  
// This code is contributed by vt_m.

2210
Chapter 303. Number of decimal numbers of length k, that are strict monotone

PHP

<?php
// PHP program to count 
// numbers of k digits
// that are strictly
// monotone.
$DP_s = 9;
  
function getNumStrictMonotone($len)
{
    global $DP_s;
      
    // DP[i][j] is going to
    // store monotone numbers
    // of length i+1 considering
    // j+1 digits (1, 2, 3, ..9)
    $DP = array(array());
    for($i = 0; $i < $len; $i++)
    {
        for($j = 0; $j < $DP_s; $j++)
            $DP[$i][$j] = 0;
    }
      
    // Unit length numbers
    for ($i = 0; $i < $DP_s; ++$i) 
        $DP[0][$i] = $i + 1; 
  
    // Building dp[]
    // in bottom up
    for ($i = 1; $i < $len; ++$i) 
        for ($j = 1; $j < $DP_s; ++$j) 
            $DP[$i][$j] = $DP[$i - 1][$j - 1] + 
                          $DP[$i][$j - 1];     
      
    return $DP[$len - 1][$DP_s - 1];
}
  
// Driver code
echo (getNumStrictMonotone(2));
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

Output :

2211
Chapter 303. Number of decimal numbers of length k, that are strict monotone

36

Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/number-decimal-numbers-length-k-strict-monotone/

2212
Chapter 304

Number of different cyclic paths


of length N in a tetrahedron

Number of different cyclic paths of length N in a tetrahedron - GeeksforGeeks


Given a tetrahedron(vertex are A, B, C, D), the task is to find the number of different cyclic
paths with length n from a vertex.
Note: Considering only a single vertex B i.e. to find the number of different cyclic paths
of length N from B to itself.
Examples:

Input: 2
Output: 3
The paths of length 2 which starts and ends at D are:
B-A-B
B-D-B
B-C-B

Input: 3
Output: 6

Approach: Dynamic Programming can be used to keep track of the number of paths for
previous values of N. Check for the number of moves which are left and where are we when
we are moving in a path. That is 4n states, each with 3 options. Observe that all the vertices
A, B, C are equivalent. Let zB be 1 initially and as at 0 steps, we can reach B itself only.
Let zACD be 1 as paths for reaching other vertexes A, C and D is 0. Hence the recurrence
relation formed will be:

Paths for N steps to reach b is = zADC*3

2213
Chapter 304. Number of different cyclic paths of length N in a tetrahedron

At every step, zADC gets multiplied by 2 (2 states) and it is added by zB since zB is the
number of paths at step n-1 which comprises of the remaining 2 states.
Below is the implementation of the above approach:
C++

// C++ program count total number of


// paths to reach B from B
#include <bits/stdc++.h>
#include <math.h>
using namespace std;
  
// Function to count the number of
// steps in a tetrahedron
int countPaths(int n)
{
    // initially coming to B is B->B
    int zB = 1;
  
    // cannot reach A, D or C
    int zADC = 0;
  
    // iterate for all steps
    for (int i = 1; i <= n; i++) {
  
        // recurrence relation
        int nzB = zADC * 3;
  
        int nzADC = (zADC * 2 + zB);
  
        // memoize previous values
        zB = nzB;
        zADC = nzADC;
    }
  
    // returns steps
    return zB;
}
  
// Driver Code
int main()
{
    int n = 3;
    cout << countPaths(n);
  
    return 0;
}

2214
Chapter 304. Number of different cyclic paths of length N in a tetrahedron

Java

// Java program count total 


// number of paths to reach
// B from B
import java.io.*;
  
class GFG 
{
      
// Function to count the
// number of steps in a
// tetrahedron
static int countPaths(int n)
{
    // initially coming 
    // to B is B->B
    int zB = 1;
  
    // cannot reach A, D or C
    int zADC = 0;
  
    // iterate for all steps
    for (int i = 1; i <= n; i++) 
    {
  
        // recurrence relation
        int nzB = zADC * 3;
  
        int nzADC = (zADC * 2 + zB);
  
        // memoize previous values
        zB = nzB;
        zADC = nzADC;
    }
  
    // returns steps
    return zB;
}
  
// Driver Code
public static void main (String[] args) 
{
    int n = 3;
    System.out.println(countPaths(n));
}
}
  

2215
Chapter 304. Number of different cyclic paths of length N in a tetrahedron

// This code is contributed by ajit

Output:

Improved By : jit_t

Source

https://www.geeksforgeeks.org/number-of-different-cyclic-paths-of-length-n-in-a-tetrahedron/

2216
Chapter 305

Number of n digit stepping


numbers

Number of n digit stepping numbers - GeeksforGeeks


Given n, find count of n digit Stepping numbers. A number is called stepping number if all
adjacent digits have an absolute difference of 1. 321 is a Stepping Number while 421 is not.
Examples :

Input : 2
Output : 17
Explanation: The numbers are 10, 12, 21,
23, 32, 34, 43, 45, 54, 56, 65, 67, 76,
78, 87, 89, 98.

Input : 1
Output : 10
Explanation: the numbers are 0, 1, 2, 3,
4, 5, 6, 7, 8, 9.

A naive approach is to run a loop for all n digit numbers and check for every number if
it is Stepping.
An efficient approach is to use dynamic programming.

In dp[i][j], i denotes number of


digits and j denotes last digit.

// If there is only one digit


if (i == 1)

2217
Chapter 305. Number of n digit stepping numbers

dp(i, j) = 1;

// If last digit is 0.
if (j == 0)
dp(i, j) = dp(i-1, j+1)

// If last digit is 9
else if (j == 9)
dp(i, j) = dp(i-1, j-1)

// If last digit is neither 0


// nor 9.
else
dp(i, j) = dp(i-1, j-1) +
dp(i-1, j+1)

Result is &Sum;dp(n, j) where j varies


from 1 to 9.

C++

// CPP program to calculate the number of


// n digit stepping numbers.
#include <bits/stdc++.h>
using namespace std;
  
// function that calculates the answer
long long answer(int n)
{
    // dp[i][j] stores count of i digit
    // stepping numbers ending with digit
    // j.
    int dp[n + 1][10];
  
    // if n is 1 then answer will be 10.
    if (n == 1)
        return 10;
  
    // Initialize values for count of
    // digits equal to 1.
    for (int j = 0; j <= 9; j++)
        dp[1][j] = 1;
  
    // Compute values for count of digits
    // more than 1.
    for (int i = 2; i <= n; i++) {
        for (int j = 0; j <= 9; j++) {
  

2218
Chapter 305. Number of n digit stepping numbers

            // If ending digit is 0


            if (j == 0)
                dp[i][j] = dp[i - 1][j + 1];
  
            // If ending digit is 9
            else if (j == 9)
                dp[i][j] = dp[i - 1][j - 1];
  
            // For other digits.
            else
                dp[i][j] = dp[i - 1][j - 1] + 
                           dp[i - 1][j + 1];
        }
    }
  
    // stores the final answer
    long long sum = 0;
    for (int j = 1; j <= 9; j++)
        sum += dp[n][j];
    return sum;
}
  
// driver program to test the above function
int main()
{
    int n = 2;
    cout << answer(n);
    return 0;
}

Java

// Java program to calculate the number of


// n digit stepping numbers.
  
class GFG {
          
    // function that calculates the answer
    static long answer(int n)
    {
        // dp[i][j] stores count of i 
        // digit stepping numbers ending 
        // with digit j.
        int dp[][] = new int[n+1][10];
       
        // if n is 1 then answer will be 10.
        if (n == 1)
            return 10;

2219
Chapter 305. Number of n digit stepping numbers

       
        // Initialize values for count of
        // digits equal to 1.
        for (int j = 0; j <= 9; j++)
            dp[1][j] = 1;
       
        // Compute values for count of 
        // digits more than 1.
        for (int i = 2; i <= n; i++) {
            for (int j = 0; j <= 9; j++) {
       
                // If ending digit is 0
                if (j == 0)
                    dp[i][j] = dp[i - 1][j + 1];
       
                // If ending digit is 9
                else if (j == 9)
                    dp[i][j] = dp[i - 1][j - 1];
       
                // For other digits.
                else
                    dp[i][j] = dp[i - 1][j - 1] + 
                               dp[i - 1][j + 1];
            }
        }
       
        // stores the final answer
        long sum = 0;
        for (int j = 1; j <= 9; j++)
            sum += dp[n][j];
        return sum;
    }
       
    // driver program to test the above function
    public static void main(String args[])
    {
        int n = 2;
        System.out.println(answer(n));
    }
}
  
/*This code is contributed by Nikita tiwari.*/

Python3

# Python3 program to calculate 


# the number of n digit
# stepping numbers.

2220
Chapter 305. Number of n digit stepping numbers

  
# function that calculates
# the answer
def answer(n):
      
    # dp[i][j] stores count of 
    # i digit stepping numbers 
    # ending with digit j.
    dp = [[0 for x in range(10)] 
             for y in range(n + 1)];
  
    # if n is 1 then answer
    # will be 10.
    if (n == 1):
        return 10;
    for j in range(10):
        dp[1][j] = 1;
  
    # Compute values for count 
    # of digits more than 1.
    for i in range(2, n + 1): 
        for j in range(10): 
              
            # If ending digit is 0
            if (j == 0):
                dp[i][j] = dp[i - 1][j + 1];
                  
            # If ending digit is 9
            elif (j == 9):
                dp[i][j] = dp[i - 1][j - 1];
                  
            # For other digits.
            else:
                dp[i][j] = (dp[i - 1][j - 1] + 
                            dp[i - 1][j + 1]);
                  
    # stores the final answer
    sum = 0;
    for j in range(1, 10):
        sum = sum + dp[n][j];
    return sum;
  
# Driver Code
n = 2;
print(answer(n));
  
# This code is contributed 
# by mits

2221
Chapter 305. Number of n digit stepping numbers

C#

// C# program to calculate the number of


// n digit stepping numbers.
using System;
  
class GFG {
          
    // function that calculates the answer
    static long answer(int n)
    {
          
        // dp[i][j] stores count of i 
        // digit stepping numbers ending 
        // with digit j.
        int [,]dp = new int[n+1,10];
      
        // if n is 1 then answer will be 10.
        if (n == 1)
            return 10;
      
        // Initialize values for count of
        // digits equal to 1.
        for (int j = 0; j <= 9; j++)
            dp[1,j] = 1;
      
        // Compute values for count of 
        // digits more than 1.
        for (int i = 2; i <= n; i++) {
            for (int j = 0; j <= 9; j++) {
      
                // If ending digit is 0
                if (j == 0)
                    dp[i,j] = dp[i - 1,j + 1];
      
                // If ending digit is 9
                else if (j == 9)
                    dp[i,j] = dp[i - 1,j - 1];
      
                // For other digits.
                else
                    dp[i,j] = dp[i - 1,j - 1] + 
                               dp[i - 1,j + 1];
            }
        }
      
        // stores the final answer
        long sum = 0;

2222
Chapter 305. Number of n digit stepping numbers

        for (int j = 1; j <= 9; j++)


            sum += dp[n,j];
              
        return sum;
    }
      
    // driver program to test the above function
    public static void Main()
    {
        int n = 2;
          
        Console.WriteLine(answer(n));
    }
}
  
/*This code is contributed by vt_m.*/

PHP

<?php
// PHP program to calculate 
// the number of n digit
// stepping numbers.
  
// function that calculates
// the answer
function answer($n)
{
    // dp[i][j] stores count of 
    // i digit stepping numbers 
    // ending with digit j.
  
    // if n is 1 then answer
    // will be 10.
    if ($n == 1)
        return 10;
    for ( $j = 0; $j <= 9; $j++)
        $dp[1][$j] = 1;
  
    // Compute values for count 
    // of digits more than 1.
    for ($i = 2; $i <= $n; $i++) 
    {
        for ($j = 0; $j <= 9; $j++) 
        {
  
            // If ending digit is 0
            if ($j == 0)

2223
Chapter 305. Number of n digit stepping numbers

                $dp[$i][$j] = $dp[$i - 1][$j + 1];


  
            // If ending digit is 9
            else if ($j == 9)
                $dp[$i][$j] = $dp[$i - 1][$j - 1];
  
            // For other digits.
            else
                $dp[$i][$j] = $dp[$i - 1][$j - 1] + 
                               $dp[$i - 1][$j + 1];
        }
    }
  
    // stores the final answer
    $sum = 0;
    for ($j = 1; $j <= 9; $j++)
        $sum += $dp[$n][$j];
    return $sum;
}
  
// Driver Code
$n = 2;
echo answer($n);
  
// This code is contributed by aj_36
?>

Output :

17

Time Complexity: O(n)


Auxiliary Space: O(n)
Improved By : jit_t, Mithun Kumar

Source

https://www.geeksforgeeks.org/number-n-digit-stepping-numbers/

2224
Chapter 306

Number of n-digits
non-decreasing integers

Number of n-digits non-decreasing integers - GeeksforGeeks


Given an integer n > 0, which denotes the number of digits, the task to find total number
of n-digit positive integers which are non-decreasing in nature.
A non-decreasing integer is a one in which all the digits from left to right are in non-
decreasing form. ex: 1234, 1135, ..etc.
Note :Leading zeros also count in non-decreasing integers such as 0000, 0001, 0023, etc are
also non-decreasing integers of 4-digits.
Examples :

Input : n = 1
Output : 10
Numbers are 0, 1, 2, ...9.

Input : n = 2
Output : 55

Input : n = 4
Output : 715

Naive Approach : We generate all possible n-digit numbers and then for each number we
check whether it is non-decreasing or not.
Time Complexity : (n*10^n), where 10^n is for generating all possible n-digits number and
n is for checking whether a particular number is non-decreasing or not.
Dynamic Programming :
If we fill digits one by one from left to right, following conditions hold.

2225
Chapter 306. Number of n-digits non-decreasing integers

1. If current last digit is 9, we can fill only 9s in remaining places. So only one solution
is possible if current last digit is 9.

2. If current last digit is less than 9, then we can recursively compute count using following
formula.

a[i][j] = a[i-1][j] + a[i][j + 1]


For every digit j smaller than 9.

We consider previous length count and count


to be increased by all greater digits.

We build a matrix a[][] where a[i][j] = count of all valid i-digit non-decreasing integers with
j or greater than j as the leading digit. The solution is based on below observations. We
fill this matrix column-wise, first calculating a[1][9] then using this value to compute a[2][8]
and so on.
At any instant if we wish to calculate a[i][j] means number of i-digits non-decreasing
integers with leading digit as j or digit greater than j, we should add up a[i-1][j] (number of
i-1 digit integers which should start from j or greater digit, because in this case if we place
j as its left most digit then our number will be i-digit non-decreasing number) and a[i][j+1]
(number of i-digit integers which should start with digit equals to greater than j+1). So,
a[i][j] = a[i-1][j] + a[i][j+1].

2226
Chapter 306. Number of n-digits non-decreasing integers

C/C++

// C++ program for counting n digit numbers with


// non decreasing digits
#include <bits/stdc++.h>
using namespace std;
  
// Returns count of non- decreasing numbers with
// n digits.
int nonDecNums(int n)
{
    /* a[i][j] = count of all possible number
       with i digits having leading digit as j */
    int a[n + 1][10];
  
    // Initialization of all 0-digit number
    for (int i = 0; i <= 9; i++)
        a[0][i] = 1;

2227
Chapter 306. Number of n-digits non-decreasing integers

  
    /* Initialization of all i-digit
      non-decreasing number leading with 9*/
    for (int i = 1; i <= n; i++)
        a[i][9] = 1;
  
    /* for all digits we should calculate
      number of ways depending upon leading
      digits*/
    for (int i = 1; i <= n; i++)
        for (int j = 8; j >= 0; j--)
            a[i][j] = a[i - 1][j] + a[i][j + 1];
  
    return a[n][0];
}
  
// driver program
int main()
{
    int n = 2;
    cout << "Non-decreasing digits = "
         << nonDecNums(n) << endl;
    return 0;
}

Java

// Java program for counting n digit numbers with


// non decreasing digits
import java.io.*;
  
class GFG {
  
    // Function that returns count of non- decreasing numbers
    // with n digits
    static int nonDecNums(int n)
    {
        // a[i][j] = count of all possible number
        // with i digits having leading digit as j
        int[][] a = new int[n + 1][10];
  
        // Initialization of all 0-digit number
        for (int i = 0; i <= 9; i++)
            a[0][i] = 1;
  
        // Initialization of all i-digit
        // non-decreasing number leading with 9
        for (int i = 1; i <= n; i++)

2228
Chapter 306. Number of n-digits non-decreasing integers

            a[i][9] = 1;
  
        // for all digits we should calculate
        // number of ways depending upon leading
        // digits
        for (int i = 1; i <= n; i++)
            for (int j = 8; j >= 0; j--)
                a[i][j] = a[i - 1][j] + a[i][j + 1];
  
        return a[n][0];
    }
  
    // driver program
    public static void main(String[] args)
    {
        int n = 2;
        System.out.println("Non-decreasing digits = " + nonDecNums(n));
    }
}
  
// Contributed by Pramod Kumar

C#

// C# function to find number of diagonals


// in n sided convex polygon
using System;
  
class GFG {
      
    // Function that returns count of non- 
    // decreasing numbers with n digits
    static int nonDecNums(int n)
    {
        // a[i][j] = count of all possible number
        // with i digits having leading digit as j
        int[, ] a = new int[n + 1, 10];
  
        // Initialization of all 0-digit number
        for (int i = 0; i <= 9; i++)
            a[0, i] = 1;
  
        // Initialization of all i-digit
        // non-decreasing number leading with 9
        for (int i = 1; i <= n; i++)
            a[i, 9] = 1;
  
        // for all digits we should calculate

2229
Chapter 306. Number of n-digits non-decreasing integers

        // number of ways depending upon leading


        // digits
        for (int i = 1; i <= n; i++)
            for (int j = 8; j >= 0; j--)
                a[i, j] = a[i - 1, j] + a[i, j + 1];
  
        return a[n, 0];
    }
  
    // driver program
    public static void Main()
    {
        int n = 2;
        Console.WriteLine("Non-decreasing digits = " + 
                                       nonDecNums(n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program for counting 
// n digit numbers with
// non decreasing digits
  
// Returns count of non- 
// decreasing numbers with
// n digits.
  
function nonDecNums($n)
{
    /* a[i][j] = count of 
    all possible number
    with i digits having 
    leading digit as j */
  
    // Initialization of 
    // all 0-digit number
    for ($i = 0; $i <= 9; $i++)
        $a[0][$i] = 1;
  
    /* Initialization of all 
    i-digit non-decreasing 
    number leading with 9*/
    for ($i = 1; $i <= $n; $i++)
        $a[$i][9] = 1;

2230
Chapter 306. Number of n-digits non-decreasing integers

  
    /* for all digits we should 
    calculate number of ways 
    depending upon leading digits*/
    for ($i = 1; $i <= $n; $i++)
        for ($j = 8; $j >= 0; $j--)
            $a[$i][$j] = $a[$i - 1][$j] + 
                         $a[$i][$j + 1];
  
    return $a[$n][0];
}
  
// Driver Code
$n = 2;
echo "Non-decreasing digits = ",
            nonDecNums($n),"\n";
  
// This code is contributed by m_kit
?>

Output :

Non-decreasing digits = 55

Time Complexity : O(10*n) equivalent to O(n).


Improved By : Sam007, jit_t

Source

https://www.geeksforgeeks.org/number-n-digits-non-decreasing-integers/

2231
Chapter 307

Number of non-negative integral


solutions of a + b + c = n

Number of non-negative integral solutions of a + b + c = n - GeeksforGeeks


Given a number n, find number of ways we can add 3 non-negative integers so that their
sum is n.
Examples :

Input : n = 1
Output : 3
There are four ways to get sum 1.
(1, 0, 0), (0, 1, 0) and (0, 0, 1)

Input : n = 2
Output : 6
There are six ways to get sum 2.
(2, 0, 0), (0, 2, 0), (0, 0, 2), (1, 1, 0)
(1, 0, 1) and (0, 1, 1)

Input : n = 3
Output : 10
There are ten ways to get sum 10.
(3, 0, 0), (0, 3, 0), (0, 0, 3), (1, 2, 0)
(1, 0, 2), (0, 1, 2), (2, 1, 0), (2, 0, 1),
(0, 2, 1) and (1, 1, 1)

Method 1 [ Brute Force : O(n3 ) ]


A simple solutions is to consider all triplets using three loops. For every triplet, check if its
sum is equal to n. If sum is n, increment count of solutions.

2232
Chapter 307. Number of non-negative integral solutions of a + b + c = n

Below is the implementation.

C++

// A naive C++ solution to count solutions of


// a + b + c = n
#include<bits/stdc++.h>
using namespace std;
  
// Returns count of solutions of a + b + c = n
int countIntegralSolutions(int n)
{
    // Initialize result
    int result = 0;
  
    // Consider all triplets and increment
    // result whenever sum of a triplet is n.
    for (int i=0; i<=n; i++)
      for (int j=0; j<=n-i; j++)
          for (int k=0; k<=(n-i-j); k++)
             if (i + j + k == n)
              result++;
  
    return result;
}
  
// Driver code
int main()
{
    int n = 3;
    cout <<  countIntegralSolutions(n);
    return 0;
}

Java

// A naive Java solution to count


// solutions of a + b + c = n
import java.io.*;
  
class GFG 
{
    // Returns count of solutions of a + b + c = n
    static int countIntegralSolutions(int n)
    {
        // Initialize result
        int result = 0;

2233
Chapter 307. Number of non-negative integral solutions of a + b + c = n

      
        // Consider all triplets and increment
        // result whenever sum of a triplet is n.
        for (int i = 0; i <= n; i++)
        for (int j = 0; j <= n - i; j++)
            for (int k = 0; k <= (n - i - j); k++)
                if (i + j + k == n)
                result++;
      
        return result;
    }
  
    // Driver code
    public static void main (String[] args) 
    {
        int n = 3;
        System.out.println( countIntegralSolutions(n));
      
    }
}
  
// This article is contributed by vt_m

Python3

# Python3 code to count 


# solutions of a + b + c = n
  
# Returns count of solutions
# of a + b + c = n
def countIntegralSolutions (n):
  
    # Initialize result
    result = 0
      
    # Consider all triplets and 
    # increment result whenever 
    # sum of a triplet is n.
    for i in range(n + 1):
        for j in range(n + 1):
            for k in range(n + 1):
                if i + j + k == n:
                    result += 1
      
    return result
      
# Driver code
n = 3

2234
Chapter 307. Number of non-negative integral solutions of a + b + c = n

print(countIntegralSolutions(n))
  
# This code is contributed by "Sharad_Bhardwaj".

C#

// A naive C# solution to count


// solutions of a + b + c = n
using System;
  
class GFG {
      
    // Returns count of solutions
    // of a + b + c = n
    static int countIntegralSolutions(int n)
    {
          
        // Initialize result
        int result = 0;
      
        // Consider all triplets and increment
        // result whenever sum of a triplet is n.
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= n - i; j++)
                for (int k = 0; k <= (n - i - j); k++)
                    if (i + j + k == n)
                    result++;
      
        return result;
    }
  
    // Driver code
    public static void Main () 
    {
        int n = 3;
        Console.Write(countIntegralSolutions(n));
      
    }
}
  
// This article is contributed by Smitha.

PHP

<?php
// A naive PHP solution
// to count solutions of

2235
Chapter 307. Number of non-negative integral solutions of a + b + c = n

// a + b + c = n
  
// Returns count of 
// solutions of a + b + c = n
function countIntegralSolutions( $n)
{
      
    // Initialize result
    $result = 0;
  
    // Consider all triplets and increment
    // result whenever sum of a triplet is n.
    for ($i = 0; $i <= $n; $i++)
        for ($j = 0; $j <= $n - $i; $j++)
            for ($k = 0; $k <= ($n - $i - $j); $k++)
            if ($i + $j + $k == $n)
            $result++;
  
    return $result;
}
  
    // Driver Code
    $n = 3;
    echo countIntegralSolutions($n);
  
// This code is contributed by anuj_67.
?>

Output :

10

Method 2 [ Direct Formula : O(1) ]


If we take a closer look at the pattern, we can find that the count of solutions is ((n+1) *
(n+2)) / 2. The problem is equivalent to distributing n + 1 identical balls (for 0 to n) in
three boxes and the solution is n+2 C2 . In general, if there are m variables (or boxes) and n
possible values, the formula becomes n+m-1 Cm-1 .

C++

// A naive C++ solution to count solutions of


// a + b + c = n
#include<bits/stdc++.h>
using namespace std;
  

2236
Chapter 307. Number of non-negative integral solutions of a + b + c = n

// Returns count of solutions of a + b + c = n


int countIntegralSolutions(int n)
{
    return ((n+1)*(n+2))/2;
}
  
// Driver code
int main()
{
    int n = 3;
    cout <<  countIntegralSolutions(n);
    return 0;
}

Java

// Java solution to count 


// solutions of a + b + c = n
import java.io.*;
  
class GFG 
{
    // Returns count of solutions 
    // of a + b + c = n
    static int countIntegralSolutions(int n)
    {
    return ((n + 1) * (n + 2)) / 2;
          
    }
      
    // Driver code
    public static void main (String[] args) 
    {
        int n = 3;
        System.out.println ( countIntegralSolutions(n));
          
    }
}
// This article is contributed by vt_m

Python3

# Python3 solution to count 


# solutions of a + b + c = n
  
# Returns count of solutions
# of a + b + c = n

2237
Chapter 307. Number of non-negative integral solutions of a + b + c = n

def countIntegralSolutions (n):


    return int(((n + 1) * (n + 2)) / 2)
      
# Driver code
n = 3
print(countIntegralSolutions(n))
  
# This code is contributed by "Sharad_Bhardwaj".

C#

// C# solution to count 
// solutions of a + b + c = n
using System;
  
class GFG {
      
    // Returns count of solutions 
    // of a + b + c = n
    static int countIntegralSolutions(int n)
    {
        return ((n + 1) * (n + 2)) / 2;
    }
      
    // Driver code
    public static void Main (String[] args) 
    {
        int n = 3;
        Console.Write ( countIntegralSolutions(n));
          
    }
}
  
// This code is contributed by parashar.

PHP

<?php
// A naive PHP solution 
// to count solutions of
// a + b + c = n
  
// Returns count of solutions
// of a + b + c = n
function countIntegralSolutions($n)
{
    return (($n + 1) * ($n + 2)) / 2;

2238
Chapter 307. Number of non-negative integral solutions of a + b + c = n

}
  
    // Driver Code
    $n = 3;
    echo countIntegralSolutions($n);
  
// This code is contributed by anuj_67.
?>

Output :

10

Improved By : parashar, Smitha Dinesh Semwal, vt_m

Source

https://www.geeksforgeeks.org/number-non-negative-integral-solutions-b-c-n/

2239
Chapter 308

Number of ordered pairs such


that (Ai & Aj) = 0

Number of ordered pairs such that (Ai & Aj) = 0 - GeeksforGeeks


Given an array A[] of n integers, find out the number of ordered pairs such that Ai &Aj is
zero, where 0<=(i,j)<n. Consider (i, j) and (j, i) to be different.
Constraints:
1<=n<=104
1<=Ai <=104
Examples:

Input : A[] = {3, 4, 2}


Output : 4
Explanation : The pairs are (3, 4) and (4, 2) which are
counted as 2 as (4, 3) and (2, 4) are considered different.

Input : A[]={5, 4, 1, 6}
Output : 4
Explanation : (4, 1), (1, 4), (6, 1) and (1, 6) are the pairs

Simple approach : A simple approach is to check for all possible pairs and count the
number of ordered pairs whose bitwise & returns 0.
Below is the implementation of above idea:

C++

// CPP program to calculate the number


// of ordered pairs such that thier bitwise

2240
Chapter 308. Number of ordered pairs such that (Ai & Aj) = 0

// and is zero
#include <bits/stdc++.h>
using namespace std;
  
// Naive function to count the number
// of ordered pairs such that their
// bitwise and is 0
int countPairs(int a[], int n)
{
    int count = 0;
  
    // check for all possible pairs
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++)
            if ((a[i] & a[j]) == 0)
  
                // add 2 as (i, j) and (j, i) are 
                // considered different
                count += 2; 
    }
  
    return count;
}
  
// Driver Code
int main()
{
    int a[] = { 3, 4, 2 };
    int n = sizeof(a) / sizeof(a[0]);    
    cout << countPairs(a, n);    
    return 0;
}

Java

// Java program to calculate the number


// of ordered pairs such that thier bitwise
// and is zero
  
class GFG {
      
    // Naive function to count the number
    // of ordered pairs such that their
    // bitwise and is 0
    static int countPairs(int a[], int n)
    {
        int count = 0;
  

2241
Chapter 308. Number of ordered pairs such that (Ai & Aj) = 0

        // check for all possible pairs


        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++)
                if ((a[i] & a[j]) == 0)
  
                    // add 2 as (i, j) and (j, i) are
                    // considered different
                    count += 2;
        }
  
        return count;
    }
  
    // Driver Code
    public static void main(String arg[])
    {
        int a[] = { 3, 4, 2 };
        int n = a.length;
        System.out.print(countPairs(a, n));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python3 program to calculate the number


# of ordered pairs such that thier
# bitwise and is zero
  
# Naive function to count the number
# of ordered pairs such that their
# bitwise and is 0
def countPairs(a, n):
    count = 0
  
    # check for all possible pairs
    for i in range(0, n):
        for j in range(i + 1, n):
            if (a[i] & a[j]) == 0:
  
                # add 2 as (i, j) and (j, i) are 
                # considered different
                count += 2 
    return count
  
# Driver Code
a = [ 3, 4, 2 ]

2242
Chapter 308. Number of ordered pairs such that (Ai & Aj) = 0

n = len(a) 
print (countPairs(a, n)) 
  
# This code is contributed
# by Shreyanshi Arun.

C#

// C# program to calculate the number


// of ordered pairs such that thier 
// bitwise and is zero
using System;
  
class GFG {
      
    // Naive function to count the number
    // of ordered pairs such that their
    // bitwise and is 0
    static int countPairs(int []a, int n)
    {
        int count = 0;
  
        // check for all possible pairs
        for (int i = 0; i < n; i++) 
        {
            for (int j = i + 1; j < n; j++)
                if ((a[i] & a[j]) == 0)
  
                    // add 2 as (i, j) and (j, i) 
                    // arev considered different
                    count += 2;
        }
  
        return count;
    }
  
    // Driver Code
    public static void Main()
    {
        int []a = { 3, 4, 2 };
        int n = a.Length;
        Console.Write(countPairs(a, n));
    }
}
  
// This code is contributed by nitin mittal.

PHP

2243
Chapter 308. Number of ordered pairs such that (Ai & Aj) = 0

<?php
// PHP program to calculate the number
// of ordered pairs such that their 
// bitwise and is zero
  
// Naive function to count the number
// of ordered pairs such that their
// bitwise and is 0
function countPairs($a, $n)
{
    $count = 0;
  
    // check for all possible pairs
    for ($i = 0; $i < $n; $i++) 
    {
        for ($j = $i + 1; $j < $n; $j++)
            if (($a[$i] & $a[$j]) == 0)
  
                // add 2 as (i, j) and (j, i) are 
                // considered different
                $count += 2; 
    }
  
    return $count;
}
  
// Driver Code
{
    $a = array(3, 4, 2);
    $n = sizeof($a) / sizeof($a[0]); 
    echo countPairs($a, $n); 
    return 0;
}
  
// This code is contributed by nitin mittal
?>

Output:

Time Complexity: O(n2 )


Efficient approach: An efficient approach is to use Sum over Subsets Dynamic Program-
ming method and count the number of ordered pairs. In the SOS DP we find out the pairs
whose bitwise & returned 0. Here we need to count the number of pairs.
Some key observations are the constraints, the maximum that an array element can be is
104 . Calculating the mask up to (1<<15) will give us our answer. Use hashing to count the

2244
Chapter 308. Number of ordered pairs such that (Ai & Aj) = 0

occurrence of every element. If the last bit is OFF, then relating to SOS dp, we will have a
base case since there is only one possibility of OFF bit.

dp[mask][0] = freq(mask)

If the last bit is set ON, then we will have the base case as:

dp[mask][0] = freq(mask) + freq(mask^1)

We add freq(mask^1) to add the other possibility of OFF bit.


Iterate over N=15 bits, which is the maximum possible.
Let’s consider the i-th bit to be 0, then no subset can differ from the mask in the i-th bit
as it would mean that the numbers will have a 1 at i-th bit where the mask has a 0 which
would mean that it is not a subset of the mask. Thus we conclude that the numbers now
differ in the first (i-1) bits only. Hence,

DP(mask, i) = DP(mask, i-1)

Now the second case, if the i-th bit is 1, it can be divided into two non-intersecting
sets. One containing numbers with i-th bit as 1 and differing from mask in the next (i-1)
bits. Second containing numbers with ith bit as 0 and differing from mask (2i ) in next
(i-1) bits. Hence,

DP(mask, i) = DP(mask, i-1) + DP(mask2i, i-1).

DP[mask][i] stores the number of subsets of mask which differ from mask only in first i
bits. Iterate for all array elements, and for every array element add the number of subsets
(dp[ ( ( 1<<N ) – 1 ) ^ a[i] ][ N ]) to the number of pairs. N = maximum number of bits.
Explanation of addition of dp[ ( ( 1<<N ) – 1 ) ^ a[i] ][N] to the number of pairs:
Take an example of A[i] being 5, which is 101 in binary. For better understanding, assume
N=3 in this case, therefore, the reverse of 101 will be 010 which on applying bitwise & gives
0. So (1<<3) gives 1000 which on subtraction from 1 gives 111. 111 101 gives 010 which
is the reversed bit.So dp[((1<<N)-1)^a[i]][N] will have the number of subsets that returns
0 on applying bitwise & operator.
Below is the implementation of the above idea:

// CPP program to calculate the number


// of ordered pairs such that thier bitwise
// and is zero
  
#include <bits/stdc++.h>

2245
Chapter 308. Number of ordered pairs such that (Ai & Aj) = 0

using namespace std;


  
const int N = 15;
  
// efficient function to count pairs
long long countPairs(int a[], int n)
{
    // stores the frequency of each number
    unordered_map<int, int> hash;
  
    long long dp[1 << N][N + 1];
      
    memset(dp, 0, sizeof(dp)); // initialize 0 to all
  
    // count the frequency of every element
    for (int i = 0; i < n; ++i)
        hash[a[i]] += 1;
  
    // iterate for al possible values that a[i] can be
    for (long long mask = 0; mask < (1 << N); ++mask) {
  
        // if the last bit is ON
        if (mask & 1)
            dp[mask][0] = hash[mask] + hash[mask ^ 1];
        else // is the last bit is OFF
            dp[mask][0] = hash[mask];
  
        // iterate till n
        for (int i = 1; i <= N; ++i) {
  
            // if mask's ith bit is set
            if (mask & (1 << i))
            {
                dp[mask][i] = dp[mask][i - 1] + 
                        dp[mask ^ (1 << i)][i - 1];
            }    
            else // if mask's ith bit is not set
                dp[mask][i] = dp[mask][i - 1];
        }
    }
  
    long long ans = 0;
  
    // iterate for all the array element
    // and count the number of pairs
    for (int i = 0; i < n; i++)
        ans += dp[((1 << N) - 1) ^ a[i]][N];
  

2246
Chapter 308. Number of ordered pairs such that (Ai & Aj) = 0

    // return answer


    return ans;
}
  
// Driver Code
int main()
{
    int a[] = { 5, 4, 1, 6 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << countPairs(a, n);
    return 0;
}

Output:

Time Complexity: O(N*2N ) where N=15 which is maximum number of bits possible,
since Amax =104 .
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/number-ordered-pairs-ai-aj-0/

2247
Chapter 309

Number of palindromic paths in


a matrix

Number of palindromic paths in a matrix - GeeksforGeeks


Given a matrix containing lower alphabetical characters only, we need to count number of
palindromic paths in given matrix. A path is defined as a sequence of cells starting from
top-left cell and ending at bottom-right cell. We are allowed to move to right and
down only from current cell.
Examples:

Input : mat[][] = {"aaab”,


"baaa”
“abba”}
Output : 3

Number of palindromic paths are 3 from top-left to


bottom-right.
aaaaaa (0, 0) -> (0, 1) -> (1, 1) -> (1, 2) ->
(1, 3) -> (2, 3)
aaaaaa (0, 0) -> (0, 1) -> (0, 2) -> (1, 2) ->
(1, 3) -> (2, 3)
abaaba (0, 0) -> (1, 0) -> (1, 1) -> (1, 2) ->
(2, 2) -> (2, 3)

We can solve this problem recursively, we start from two corners of a palindromic path(top-
left and bottom right). In each recursive call, we maintain a state which will constitute two
cells one from starting and one from end which should be equal for palindrome property. If
at a state, both cell characters are equal then we call recursively with all possible movements
in both directions.

2248
Chapter 309. Number of palindromic paths in a matrix

As this can lead to solving same subproblem multiple times, we have taken a map memo in
below code which stores the calculated result with key as indices of starting and ending cell
so if subproblem with same starting and ending cell is called again, result will be returned
by memo directly instead of recalculating again.
Please see below code for better understanding,

// C++ program to get number of palindrome


// paths in matrix
#include <bits/stdc++.h>
  
using namespace std;
  
#define R 3
#define C 4
  
// struct to represent state of recursion
// and key of map
struct cells
{
    //  indices of front cell
    int rs, cs;
  
    //  indices of end cell
    int re, ce;
    cells(int rs, int cs, int re, int ce) :
        rs(rs), cs(cs), re(re), ce(ce) { }
  
    // operator overloading to compare two
    // cells which rs needed for map
    bool operator <(const cells& other) const
    {
        return ((rs != other.rs) || (cs != other.cs) ||
               (re != other.re) || (ce != other.ce));
    }
};
  
// recursive method to return number of palindromic
// paths in matrix
// (rs, cs) ==> Indicies of current cell from a starting
//              point (First Row)
// (re, ce) ==> Indicies of current cell from a ending
//              point (Last Row)
// memo     ==> To store results of already computed
//              problems
int getPalindromicPathsRecur(char mat[R][C], int rs,
          int cs, int re, int ce, map<cells, int>& memo)
{
    // Base Case 1 : if any index rs out of boundry,

2249
Chapter 309. Number of palindromic paths in a matrix

    // return 0
    if (rs < 0 || rs >= R || cs < 0 || cs >= C)
        return 0;
    if (re < 0 || re < rs || ce < 0 || ce < cs)
        return 0;
  
    // Base case 2 : if values are not equal
    // then palindrome property rs not satisfied,
    // so return 0
    if (mat[rs][cs] != mat[re][ce])
        return 0;
  
    // If we reach here, then matrix cells are same.
  
    // Base Case 3 : if indices are adjacent then
    // return 1
    if (abs((rs - re) + (cs - ce)) <= 1)
        return 1;
  
    //  if result rs precalculated, return from map
    if (memo.find(cells(rs, cs, re, ce)) != memo.end())
        return memo[cells(rs, cs, re, ce)];
  
    int ret = 0; // Initialize result
  
    // calling recursively for all possible movements
    ret += getPalindromicPathsRecur(mat, rs + 1, cs,
                                    re - 1, ce, memo);
    ret += getPalindromicPathsRecur(mat, rs + 1, cs, re,
                                         ce - 1, memo);
    ret += getPalindromicPathsRecur(mat, rs, cs + 1,
                                     re - 1, ce, memo);
    ret += getPalindromicPathsRecur(mat, rs, cs + 1, re,
                                          ce - 1, memo);
  
    // storing the calculated result in map
    memo[cells(rs, cs, re, ce)] = ret;
  
    return ret;
}
  
//  method returns number of palindromic paths in matrix
int getPalindromicPaths(char mat[R][C])
{
    map<cells, int> memo;
    return getPalindromicPathsRecur(mat, 0, 0, R - 1,
                                          C - 1, memo);
}

2250
Chapter 309. Number of palindromic paths in a matrix

  
//  Driver code to test above methods
int main()
{
    char mat[R][C] =
    {
        'a', 'a', 'a', 'b',
        'b', 'a', 'a', 'a',
        'a', 'b', 'b', 'a'
    };
    printf("%d", getPalindromicPaths(mat));
  
    return 0;
}

Output:

Time Complexity : O(R x C)


Improved By : ImStark

Source

https://www.geeksforgeeks.org/number-of-palindromic-paths-in-a-matrix/

2251
Chapter 310

Number of palindromic
subsequences of length k where
k <= 3

Number of palindromic subsequences of length k where k


Given a string S of length n and a positive integer k. The task is to find number of
Palindromic Subsequences of length k where k <= 3. Examples:

Input : s = “aabab”, k = 2
Output : 4

Input : s = “aaa”, k = 3
Output : 1

For k = 1, we can easily say that number of characters in string will be the answer.
For k = 2, we can easily make pairs of same characters so we have to maintain the count
of each character in string and then calculate

sum = 0
for character 'a' to 'z'
cnt = count(characater)
sum = sum + cnt*(cnt-1)/2
sum is the answer.

Now as k increases, it became difficult to find. How to find answer for k = 3 ? So the idea
is to see that palindromes of length 3 will be of the format TZT, so we have to maintain
two matrices, one to calculate the prefix sum of each character, and one to calculate suffix

2252
Chapter 310. Number of palindromic subsequences of length k where k <= 3

sum of each character in the string.


Prefix sum for a character T at index i is L[T][i] i.e number of times T has occured in the
range [0, i](indices).
Suffix sum for a character T at index i is R[T] has occurred in the range [i, n – 1](indices).
Both the matrices will be 26*n and one can precompute both these matrices in complexity
O(26*n) where n is the length of the string.
Now how to compute the subsequence ? Think over this: for an index i suppose a character
X appears n1 times in the range [0, i – 1] and n2 times in the range [i + 1, n – 1] then the
answer for this character will be n1 * n2 i.e L[X][i-1] * R[X][i + 1], this will give the count
of subsequences of the format X-s[i]-X where s[i] is the character at i-th index. So for every
index i you will have to count the product of

L[X][i-1] * R[X][i+1],
where i is the range [1, n-2] and
X will be from 'a' to 'z'

Below is the implementation of this approach:

C++

// CPP program to count number of subsequences of


// given length.
#include <bits/stdc++.h>
#define MAX 100
#define MAX_CHAR 26
using namespace std;
  
// Precompute the prefix and suffix array.
void precompute(string s, int n, int l[][MAX], 
                                 int r[][MAX])
{
    l[s[0] - 'a'][0] = 1;
  
    // Precompute the prefix 2D array
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < MAX_CHAR; j++) 
            l[j][i] += l[j][i - 1];        
  
        l[s[i] - 'a'][i]++;
    }
  
    r[s[n - 1] - 'a'][n - 1] = 1;
  
    // Precompute the Suffix 2D array.
    for (int i = n - 2; i >= 0; i--) {
        for (int j = 0; j < MAX_CHAR; j++) 
            r[j][i] += r[j][i + 1];       

2253
Chapter 310. Number of palindromic subsequences of length k where k <= 3

  
        r[s[i] - 'a'][i]++;
    }
}
  
// Find the number of palindromic subsequence of 
// length k
int countPalindromes(int k, int n, int l[][MAX], 
                                   int r[][MAX])
{
    int ans = 0;
  
    // If k is 1.
    if (k == 1) {
        for (int i = 0; i < MAX_CHAR; i++) 
            ans += l[i][n - 1];  
        return ans;
    }
  
    // If k is 2
    if (k == 2) {
  
        // Adding all the products of prefix array
        for (int i = 0; i < MAX_CHAR; i++)             
            ans += ((l[i][n - 1] * (l[i][n - 1] - 1)) / 2);
        return ans;
    }
  
    // For k greater than 2. Adding all the products
    // of value of prefix and suffix array.
    for (int i = 1; i < n - 1; i++) 
        for (int j = 0; j < MAX_CHAR; j++)             
            ans += l[j][i - 1] * r[j][i + 1];  
  
    return ans;
}
  
// Driven Program
int main()
{
    string s = "aabab";
    int k = 2;
    int n = s.length();
    int l[MAX_CHAR][MAX] = { 0 }, r[MAX_CHAR][MAX] = { 0 };
    precompute(s, n, l, r);
    cout << countPalindromes(k, n, l, r) << endl;
    return 0;
}

2254
Chapter 310. Number of palindromic subsequences of length k where k <= 3

Java

// Java program to count number of subsequences of


// given length.
class GFG
{
      
static final int MAX=100;
static final int MAX_CHAR=26;
  
// Precompute the prefix and suffix array.
static void precompute(String s, int n, int l[][], 
                                int r[][])
{
    l[s.charAt(0) - 'a'][0] = 1;
  
    // Precompute the prefix 2D array
    for (int i = 1; i < n; i++) {
        for (int j = 0; j < MAX_CHAR; j++) 
            l[j][i] += l[j][i - 1];     
  
        l[s.charAt(i) - 'a'][i]++;
    }
  
    r[s.charAt(n - 1) - 'a'][n - 1] = 1;
  
    // Precompute the Suffix 2D array.
    for (int i = n - 2; i >= 0; i--) {
        for (int j = 0; j < MAX_CHAR; j++) 
            r[j][i] += r[j][i + 1];     
  
        r[s.charAt(i) - 'a'][i]++;
    }
}
  
// Find the number of palindromic subsequence of 
// length k
static int countPalindromes(int k, int n, int l[][], 
                                            int r[][])
{
    int ans = 0;
  
    // If k is 1.
    if (k == 1) {
        for (int i = 0; i < MAX_CHAR; i++) 
            ans += l[i][n - 1]; 
          
        return ans;

2255
Chapter 310. Number of palindromic subsequences of length k where k <= 3

    }
  
    // If k is 2
    if (k == 2) {
  
        // Adding all the products of prefix array
        for (int i = 0; i < MAX_CHAR; i++)             
            ans += ((l[i][n - 1] * (l[i][n - 1] - 1)) / 2);
          
        return ans;
    }
  
    // For k greater than 2. Adding all the products
    // of value of prefix and suffix array.
    for (int i = 1; i < n - 1; i++) 
        for (int j = 0; j < MAX_CHAR; j++)             
            ans += l[j][i - 1] * r[j][i + 1]; 
  
    return ans;

      
// Driver code 
public static void main (String[] args)
{
    String s = "aabab";
    int k = 2;
    int n = s.length();
    int l[][]=new int[MAX_CHAR][MAX];
    int r[][]=new int[MAX_CHAR][MAX];
      
    precompute(s, n, l, r);
      
    System.out.println(countPalindromes(k, n, l, r));
}
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python3 program to count number of 


# subsequences of given length.
  
MAX = 100
MAX_CHAR = 26
  
# Precompute the prefix and suffix array.
def precompute(s, n, l, r):

2256
Chapter 310. Number of palindromic subsequences of length k where k <= 3

    l[ord(s[0]) - ord('a')][0] = 1
  
    # Precompute the prefix 2D array
    for i in range(1, n):
        for j in range(MAX_CHAR):
            l[j][i] += l[j][i - 1]
          
        l[ord(s[i]) - ord('a')][i] += 1
  
    r[ord(s[n - 1]) - ord('a')][n - 1] = 1
  
    # Precompute the Suffix 2D array.
    k = n - 2
    while(k >= 0):
        for j in range(MAX_CHAR):
            r[j][k] += r[j][k + 1]
        r[ord(s[k]) - ord('a')][k] += 1
        k -= 1
  
# Find the number of palindromic 
# subsequence of length k
def countPalindromes(k, n, l, r):
    ans = 0
  
    # If k is 1.
    if (k == 1):
        for i in range(MAX_CHAR):
            ans += l[i][n - 1]
        return ans
  
    # If k is 2
    if (k == 2):
          
        # Adding all the products of 
        # prefix array
        for i in range(MAX_CHAR):
            ans += ((l[i][n - 1] * (l[i][n - 1] - 1)) / 2)
        return ans
      
    # For k greater than 2. Adding all 
    # the products of value of prefix 
    # and suffix array.
    for i in range(1, n - 1):
        for j in range(MAX_CHAR):
            ans += l[j][i - 1] * r[j][i + 1]
    return ans
  
# Driven Program

2257
Chapter 310. Number of palindromic subsequences of length k where k <= 3

s = "aabab"
k = 2
n = len(s)
  
l = [[0 for x in range(MAX)] for y in range(MAX_CHAR)]
r = [[0 for x in range(MAX)] for y in range(MAX_CHAR)]
  
precompute(s, n, l, r)
print (countPalindromes(k, n, l, r))
  
  
# This code is written by Sachin Bisht

C#

// C# program to count number of 


// subsequences of given length.
using System;
class GFG {
      
static int MAX=100;
static int MAX_CHAR=26;
  
// Precompute the prefix
// and suffix array.
static void precompute(string s, int n, 
                    int [,]l, int [,]r)
{
    l[s[0] - 'a',0] = 1;
  
    // Precompute the 
    // prefix 2D array
    for (int i = 1; i < n; i++) 
    {
        for (int j = 0; j < MAX_CHAR; j++) 
            l[j, i] += l[j,i - 1];     
  
        l[s[i] - 'a',i]++;
    }
  
    r[s[n - 1] - 'a',n - 1] = 1;
  
    // Precompute the Suffix 2D array.
    for (int i = n - 2; i >= 0; i--) 
    {
        for (int j = 0; j < MAX_CHAR; j++) 
            r[j, i] += r[j,i + 1];     
  

2258
Chapter 310. Number of palindromic subsequences of length k where k <= 3

        r[s[i] - 'a',i]++;
    }
}
  
// Find the number of palindromic
// subsequence of length k
static int countPalindromes(int k, int n, 
                      int [,]l, int [,]r)
{
    int ans = 0;
  
    // If k is 1.
    if (k == 1)
    {
        for (int i = 0; i < MAX_CHAR; i++) 
            ans += l[i,n - 1]; 
          
        return ans;
    }
  
    // If k is 2
    if (k == 2) {
  
        // Adding all the products
        // of prefix array
        for (int i = 0; i < MAX_CHAR; i++)             
            ans += ((l[i,n - 1] * 
                    (l[i,n - 1] - 1)) / 2);
          
        return ans;
    }
  
    // For k greater than 2. 
    // Adding all the products
    // of value of prefix and 
    // suffix array.
    for (int i = 1; i < n - 1; i++) 
        for (int j = 0; j < MAX_CHAR; j++)             
            ans += l[j,i - 1] * r[j, i + 1]; 
  
    return ans;

      
// Driver code 
public static void Main ()
{
    string s = "aabab";
    int k = 2;

2259
Chapter 310. Number of palindromic subsequences of length k where k <= 3

    int n = s.Length;
    int [,]l=new int[MAX_CHAR,MAX];
    int [,]r=new int[MAX_CHAR,MAX];
      
    precompute(s, n, l, r);
      
    Console.Write(countPalindromes(k, n, l, r));
}
}
  
// This code is contributed by Nitin Mittal.

Output:

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/number-of-palindromic-subsequences-of-length-k-where-k/

2260
Chapter 311

Number of paths from source to


destination in a directed acyclic
graph

Number of paths from source to destination in a directed acyclic graph - GeeksforGeeks


Given a Directed Acyclic Graph with n vertices and m edges. The task is to find the number
of different paths that exist from a source vertex to destination vertex.

Examples:

2261
Chapter 311. Number of paths from source to destination in a directed acyclic graph

Input: source = 0, destination = 4


Output: 3
Explanation:
0 -> 2 -> 3 -> 4
0 -> 3 -> 4
0 -> 4
Input: source = 0, destination = 1
Output: 1
Explanation: There exists only one path 0->1

Approach : Let f(u) be the number of ways one can travel from node u to destination vertex.
Hence, f(source) is required answer. As f(destination) = 1 here so there is just one path
from destination to itself. One can observe, f(u) depends on nothing other than the f values
of all the nodes which are possible to travel from u. It makes sense because the number of
different paths from u to the destination is the sum of all different paths from v1, v2, v3…
v-n to destination vertex where v1 to v-n are all the vertices that have a direct path from
vertex u. This approach, however, is too slow to be useful. Each function call branches out
into further calls, and that branches into further calls, until each and every path is explored
once.
The problem with this approach is the calculation of f(u) again and again each time the func-
tion is called with argument u. Since this problem exhibits both overlapping subproblems
and optimal substructure, dynamic programming is applicable here. In order to evaluate
f(u) for each u just once, evaluate f(v) for all v that can be visited from u before evaluating
f(u). This condition is satisfied by reverse topological sorted order of the nodes of the graph.
Below is the implementation of the above approach:

// C++ program for Number of paths 


// from one vertex to another vertex
//  in a Directed Acyclic Graph
#include <bits/stdc++.h>
using namespace std;
#define MAXN 1000005
  
// to make graph
vector<int> v[MAXN];
  
// function to add edge in graph
void add_edge(int a, int b, int fre[])
{
    // there is path from a to b.
    v[a].push_back(b);
    fre[b]++;
}
  
// function to make topological sorting
vector<int> topological_sorting(int fre[], int n)

2262
Chapter 311. Number of paths from source to destination in a directed acyclic graph

{
    queue<int> q;
  
    // insert all vertices which
    // don't have any parent.
    for (int i = 0; i < n; i++)
        if (!fre[i])
            q.push(i);
  
    vector<int> l;
  
    // using kahn's algorithm
    // for topological sorting
    while (!q.empty()) {
        int u = q.front();
        q.pop();
  
        // insert front element of queue to vector
        l.push_back(u);
  
        // go through all it's childs
        for (int i = 0; i < v[u].size(); i++) {
            fre[v[u][i]]--;
  
            // whenever the freqency is zero then add
            // this vertex to queue.
            if (!fre[v[u][i]])
                q.push(v[u][i]);
        }
    }
    return l;
}
  
// Function that returns the number of paths
int numberofPaths(int source, int destination, int n, int fre[])
{
  
// make topological sorting
    vector<int> s = topological_sorting(fre, n);
  
    // to store required answer.
    int dp[n] = { 0 };
  
    // answer from destination
    // to destination is 1.
    dp[destination] = 1;
  
    // traverse in reverse order

2263
Chapter 311. Number of paths from source to destination in a directed acyclic graph

    for (int i = s.size() - 1; i >= 0; i--) {


        for (int j = 0; j < v[s[i]].size(); j++) {
            dp[s[i]] += dp[v[s[i]][j]];
        }
    }
  
    return dp;
}
  
// Driver code
int main()
{
  
    // here vertices are numbered from 0 to n-1.
    int n = 5;
    int source = 0, destination = 4;
  
    // to count number of vertex which don't
    // have any parents.
    int fre[n] = { 0 };
  
    // to add all edges of graph
    add_edge(0, 1, fre);
    add_edge(0, 2, fre);
    add_edge(0, 3, fre);
    add_edge(0, 4, fre);
    add_edge(2, 3, fre);
    add_edge(3, 4, fre);
  
    // Function that returns the number of paths
    cout << numberofPaths(source, destination, n, fre);
}

Output:

Source

https://www.geeksforgeeks.org/number-of-paths-from-source-to-destination-in-a-directed-acyclic-graph/

2264
Chapter 312

Number of paths with exactly k


coins

Number of paths with exactly k coins - GeeksforGeeks


Given a matrix where every cell has some number of coins. Count number of ways to reach
bottom right from top left with exactly k coins. We can move to (i+1, j) and (i, j+1) from
a cell (i, j).
Example:

Input: k = 12
mat[][] = { {1, 2, 3},
{4, 6, 5},
{3, 2, 1}
};
Output: 2
There are two paths with 12 coins
1 -> 2 -> 6 -> 2 -> 1
1 -> 2 -> 3 -> 5 -> 1

The above problem can be recursively defined as below:

pathCount(m, n, k): Number of paths to reach mat[m][n] from mat[0][0]


with exactly k coins

If (m == 0 and n == 0)
return 1 if mat[0][0] == k else return 0
Else:
pathCount(m, n, k) = pathCount(m-1, n, k - mat[m][n]) +
pathCount(m, n-1, k - mat[m][n])

2265
Chapter 312. Number of paths with exactly k coins

Below is the implementation of above recursive algorithm.

C++

    
  
// A Naive Recursive C++ program to count paths with exactly
// 'k' coins
#include <bits/stdc++.h>
#define R 3
#define C 3
using namespace std;
  
// Recursive function to count paths with sum k from
// (0, 0) to (m, n)
int pathCountRec(int mat[][C], int m, int n, int k)
{
    // Base cases
    if (m < 0 || n < 0) return 0;
    if (m==0 && n==0) return (k == mat[m][n]);
  
    // (m, n) can be reached either through (m-1, n) or
    // through (m, n-1)
    return pathCountRec(mat, m-1, n, k-mat[m][n]) +
           pathCountRec(mat, m, n-1, k-mat[m][n]);
}
  
// A wrapper over pathCountRec()
int pathCount(int mat[][C], int k)
{
    return pathCountRec(mat, R-1, C-1, k);
}
  
// Driver program
int main()
{
    int k = 12;
    int mat[R][C] = { {1, 2, 3},
                      {4, 6, 5},
                      {3, 2, 1}
                  };
    cout << pathCount(mat, k);
    return 0;
}

Python3

# A Naive Recursive Python program to

2266
Chapter 312. Number of paths with exactly k coins

# count paths with exactly 'k' coins


  
R = 3
C = 3
  
# Recursive function to count paths
# with sum k from (0, 0) to (m, n)
def pathCountRec(mat, m, n, k):
  
    # Base cases
    if m < 0 or n < 0:
        return 0
    elif m == 0 and n == 0:
        return k == mat[m][n]
  
    # #(m, n) can be reached either
    # through (m-1, n) or through
    # (m, n-1)
    return (pathCountRec(mat, m-1, n, k-mat[m][n]) 
         + pathCountRec(mat, m, n-1, k-mat[m][n]))
  
# A wrapper over pathCountRec()
def pathCount(mat, k):
    return pathCountRec(mat, R-1, C-1, k)
  
# Driver Program
k = 12
mat = [[1, 2, 3],
       [4, 6, 5],
       [3, 2, 1]]
  
print(pathCount(mat, k))
  
# This code is contributed by Shrikant13.

PHP

<?php
// A Naive Recursive PHP program to
// count paths with exactly 'k' coins
  
$R = 3;
$C = 3;
  
// Recursive function to count paths
// with sum k from (0, 0) to (m, n)
function pathCountRec( $mat, $m, $n, $k)
{

2267
Chapter 312. Number of paths with exactly k coins

      
    // Base cases
    if ($m < 0 or $n < 0) 
        return 0;
    if ($m == 0 and $n == 0) 
        return ($k == $mat[$m][$n]);
  
    // (m, n) can be reached either 
    // through (m-1, n) or through 
    // (m, n-1)
    return pathCountRec($mat, $m - 1,
                $n, $k - $mat[$m][$n])
              + pathCountRec($mat, $m,
           $n - 1, $k - $mat[$m][$n]);
}
  
// A wrapper over pathCountRec()
function pathCount($mat, $k)
{
    global $R, $C;
    return pathCountRec($mat, $R-1, 
                            $C-1, $k);
}
  
// Driver program
  
    $k = 12;
    $mat = array(array(1, 2, 3),
                 array(4, 6, 5),
                 array(3, 2, 1) );
                   
    echo pathCount($mat, $k);
  
// This code is contributed by anuj_67.
?>

Output:

The time complexity of above solution recursive is exponential. We can solve this problem
in Pseudo Polynomial Time (time complexity is dependent on numeric value of input) using
Dynamic Programming. The idea is to use a 3 dimensional table dp[m][n][k] where m is row
number, n is column number and k is number of coins. Below is Dynamic Programming
based C++ implementation.

// A Dynamic Programming based C++ program to count paths with

2268
Chapter 312. Number of paths with exactly k coins

// exactly 'k' coins


#include <bits/stdc++.h>
#define R 3
#define C 3
#define MAX_K 1000
using namespace std;
  
int dp[R][C][MAX_K];
  
int pathCountDPRecDP(int mat[][C], int m, int n, int k)
{
    // Base cases
    if (m < 0 || n < 0) return 0;
    if (m==0 && n==0) return (k == mat[m][n]);
  
    // If this subproblem is already solved
    if (dp[m][n][k] != -1) return dp[m][n][k];
  
    // (m, n) can be reached either through (m-1, n) or
    // through (m, n-1)
    dp[m][n][k] = pathCountDPRecDP(mat, m-1, n, k-mat[m][n]) +
                  pathCountDPRecDP(mat, m, n-1, k-mat[m][n]);
  
    return dp[m][n][k];
}
  
// This function mainly initializes dp[][][] and calls
// pathCountDPRecDP()
int pathCountDP(int mat[][C], int k)
{
    memset(dp, -1, sizeof dp);
    return pathCountDPRecDP(mat, R-1, C-1, k);
}
  
// Driver Program to test above functions
int main()
{
    int k = 12;
    int mat[R][C] = { {1, 2, 3},
                      {4, 6, 5},
                      {3, 2, 1}
                  };
    cout << pathCountDP(mat, k);
    return 0;
}

Output:

2269
Chapter 312. Number of paths with exactly k coins

Time complexity of this solution is O(m*n*k).


Thanks to Gaurav Ahirwar for suggesting above solution.
Improved By : shrikanth13, vt_m

Source

https://www.geeksforgeeks.org/number-of-paths-with-exactly-k-coins/

2270
Chapter 313

Number of permutation with K


inversions

Number of permutation with K inversions - GeeksforGeeks


Given an array, an inversion is defined as a pair a[i], a[j] such that a[i] > a[j] and i < j. We
are given two numbers N and k, we need to tell how many permutation of first N number
have exactly K inversion.
Examples:

Input : N = 3, K = 1
Output : 2
Explanation :
Total Permutation of first N number,
123, 132, 213, 231, 312, 321
Permutation with 1 inversion : 132 and 213

Input : N = 4, K = 2
Output : 5

A Naïve way to solve this problem is noting down all permutation then checking count of
inversion in them but iterating through permutation itself will take O(N!) time, which is
too large.
We can solve this problem using dynamic programming approach. Below is recursive for-
mula.

If N is 0, Count(0, K) = 0

If K is 0, Count(N, 0) = 1 (Only sorted array)

2271
Chapter 313. Number of permutation with K inversions

In general case,
If we have N number and require K inversion,
Count(N, K) = Count(N - 1, K) +
Count(N – 1, K - 1) +
Count(N – 1, K – 2) +
.... +
Count(N – 1, 0)

How does above recursive formula work?


If we have N number and want to have K permutation and suppose all permutation of (N
– 1) number are written somewhere, the new number (Nth number and largest) need to be
placed in all permutation of (N – 1) number and those whose inversion count becomes K
after adding this number should be added in our answer. Now take those set of permutation
of (N – 1) number which has let (K – 3) inversion, now we can place this new largest number
at position 3 from last, then inversion count will be K, so count(N – 1, K – 3) should be
added to our answer, same argument can be given for other inversion also and we will reach
to above recursion as final answer.
Below code is written following above recursion in memorization way.

C++

// C++ program to find number of permutation 


// with K inversion using Memoization
#include <bits/stdc++.h>
using namespace std;
  
// Limit on N and K
const int M = 100;
  
// 2D array memo for stopping 
// solving same problem again
int memo[M][M];
  
// method recursively calculates 
// permutation with K inversion
int numberOfPermWithKInversion(int N, int K)
{
      
    // base cases
    if (N == 0)
        return 0;
    if (K == 0)
        return 1;
  
    // if already solved then 
    // return result directly
    if (memo[N][K] != 0)

2272
Chapter 313. Number of permutation with K inversions

        return memo[N][K];
  
    // calling recursively all subproblem 
    // of permutation size N - 1
    int sum = 0;
    for (int i = 0; i <= K; i++)
    {
  
        // Call recursively only
        // if total inversion
        // to be made are less 
        // than size
        if (i <= N - 1)
            sum += numberOfPermWithKInversion(N - 1, 
                                              K - i);
    }
  
    // store result into memo
    memo[N][K] = sum;
  
    return sum;
}
  
// Driver code 
int main()
{
    int N = 4;
    int K = 2;
    cout << numberOfPermWithKInversion(N, K);
    return 0;
}

Java

// Java program to find number of permutation with


// K inversion using Memoization
  
import java.io.*;
  
class GFG {
      
    // Limit on N and K
    static int M = 100;
  
    // 2D array memo for stopping solving same problem
    // again
    static int memo[][] = new int[M][M];
  

2273
Chapter 313. Number of permutation with K inversions

    // method recursively calculates permutation with


    // K inversion
    static int numberOfPermWithKInversion(int N, int K)
    {
          
        // base cases
        if (N == 0)
            return 0;
        if (K == 0)
            return 1;
  
        // if already solved then return result directly
        if (memo[N][K] != 0)
            return memo[N][K];
  
        // calling recursively all subproblem of
        // permutation size N - 1
        int sum = 0;
        for (int i = 0; i <= K; i++) {
              
            // Call recursively only if total inversion
            // to be made are less than size
            if (i <= N - 1)
                sum += numberOfPermWithKInversion(N - 1, 
                                                  K - i);
        }
  
        // store result into memo
        memo[N][K] = sum;
  
        return sum;
    }
  
    // Driver code to test above methods
    public static void main(String[] args)
    {
        int N = 4;
        int K = 2;
        System.out.println(numberOfPermWithKInversion(N, K));
    }
}
  
// This code is contributed by vt_m.

Python3

   
# Python3 program to find number of permutation

2274
Chapter 313. Number of permutation with K inversions

# with K inversion using Memoization


  
# Limit on N and K
M = 100
  
# 2D array memo for stopping  
# solving same problem again
memo = [[0 for i in range(M)] for j in range(M)]
   
# method recursively calculates 
# permutation with K inversion
def numberOfPermWithKInversion(N, K):
  
    # Base cases
    if (N == 0): return 0
    if (K == 0): return 1
  
    # If already solved then
    # return result directly
    if (memo[N][K] != 0):
        return memo[N][K]
  
    # Calling recursively all subproblem 
    # of permutation size N - 1
    sum = 0
    for i in range(K + 1):
      
        # Call recursively only if
        # total inversion to be made
        # are less than size
        if (i <= N - 1):
            sum += numberOfPermWithKInversion(N - 1, K - i)
      
    # store result into memo
    memo[N][K] = sum
  
    return sum
  
# Driver code
N = 4; K = 2
print(numberOfPermWithKInversion(N, K))
  
# This code is contributed by Anant Agarwal.

Output:

2275
Chapter 313. Number of permutation with K inversions

Improved By : jit_t

Source

https://www.geeksforgeeks.org/number-of-permutation-with-k-inversions/

2276
Chapter 314

Number of subsequences in a
string divisible by n

Number of subsequences in a string divisible by n - GeeksforGeeks


Given a string consisting of digits 0-9, count the number of subsequences in it divisible by
m.
Examples:

Input : str = "1234", n = 4


Output : 4
The subsequences 4, 12, 24 and 124 are
divisible by 4.

Input : str = "330", n = 6


Output : 4
The subsequences 30, 30, 330 and 0 are
divisible by n.

Input : str = "676", n = 6


Output : 3
The subsequences 6, 6 and 66

This problem can be recursively defined. Let remainder of a string with value x be ‘r’ when
divided with n. Adding one more character to this string changes its remainder to (r*10 +
newdigit) % n. For every new character, we have two choices, either add it in all current
subsequences or ignore it. Thus, we have an optimal substructure. Following shows the
brute force version of this:

2277
Chapter 314. Number of subsequences in a string divisible by n

string str = "330";


int n = 6

// idx is value of current index in str


// rem is current remainder
int count(int idx, int rem)
{
// If last character reached
if (idx == n)
return (rem == 0)? 1 : 0;

int ans = 0;

// we exclude it, thus remainder


// remains the same
ans += count(idx+1, rem);

// we include it and thus new remainder


ans += count(idx+1, (rem*10 + str[idx]-'0')%n);

return ans;
}

The above recursive solution has overlapping subproblems as shown in below recursion tree.

input string = "330"


(0,0) ===> at 0th index with 0 remainder
(exclude 0th / (include 0th character)
character) /
(1,0) (1,3) ======> at index 1 with 3 as
(E)/ (I) /(E) the current remainder
(2,0) (2,3) (2,3)
|-------|
These two subproblems overlap

Thus, we can apply Dynamic Programming. Below is implementation of same in C++.

// C++ program to count subsequences of a


// string divisble by n.
#include<bits/stdc++.h>
using namespace std;
  
// Returns count of subsequences of str
// divisble by n.
int countDivisibleSubseq(string str, int n)
{

2278
Chapter 314. Number of subsequences in a string divisible by n

    int len = str.length();


  
    // division by n can leave only n remainder
    // [0..n-1]. dp[i][j] indicates number of
    // subsequences in string [0..i] which leaves
    // remainder j after division by n.
    int dp[len][n];
    memset(dp, 0, sizeof(dp));
  
    // Filling value for first digit in str
    dp[0][(str[0]-'0')%n]++;
  
    for (int i=1; i<len; i++)
    {
        // start a new subsequence with index i
        dp[i][(str[i]-'0')%n]++;
  
        for (int j=0; j<n; j++)
        {
            // exclude i'th character from all the
            // current subsequences of string [0...i-1]
            dp[i][j] += dp[i-1][j];
  
            // include i'th character in all the current
            // subsequences of string [0...i-1]
            dp[i][(j*10 + (str[i]-'0'))%n] += dp[i-1][j];
        }
    }
  
    return dp[len-1][0];
}
  
// Driver code
int main()
{
    string str = "1234";
    int n = 4;
    cout << countDivisibleSubseq(str, n);
    return 0;
}

Output:

Time Complexity : O(len * n)


Auxiliary Space : O(len * n)

2279
Chapter 314. Number of subsequences in a string divisible by n

Source

https://www.geeksforgeeks.org/number-subsequences-string-divisible-n/

2280
Chapter 315

Number of subsequences of the


form a^i b^j c^k

Number of subsequences of the form a^i b^j c^k - GeeksforGeeks


Given a string, count number of subsequences of the form ai bj ck , i.e., it consists of i ’a’
characters, followed by j ’b’ characters, followed by k ’c’ characters where i >= 1, j >=1
and k >= 1.
Note: Two subsequences are considered different if the set of array indexes picked for the
2 subsequences are different.
Expected Time Complexity : O(n)
Examples:

Input : abbc
Output : 3
Subsequences are abc, abc and abbc

Input : abcabc
Output : 7
Subsequences are abc, abc, abbc, aabc
abcc, abc and abc

Asked in : Amazon
We traverse given string. For every character encounter, we do following:
1) Initialize counts of different subsequences caused by different combination of ‘a’. Let this
count be aCount.
2) Initialize counts of different subsequences caused by different combination of ‘b’. Let this
count be bCount.

2281
Chapter 315. Number of subsequences of the form a^i b^j c^k

3) Initialize counts of different subsequences caused by different combination of ‘c’. Let this
count be cCount.
4) Traverse all characters of given string. Do following for current character s[i]
If current character is ‘a’, then there are following possibilities :
a) Current character begins a new subsequence.
b) Current character is part of aCount subsequences.
c) Current character is not part of aCount subsequences.
Therefore we do aCount = (1 + 2 * aCount);
If current character is ‘b’, then there are following possibilities :
a) Current character begins a new subsequence of b’s with aCount subsequences.
b) Current character is part of bCount subsequences.
c) Current character is not part of bCount subsequences.
Therefore we do bCount = (aCount + 2 * bCount);
If current character is ‘c’, then there are following possibilities :
a) Current character begins a new subsequence of c’s with bCount subsequences.
b) Current character is part of cCount subsequences.
c) Current character is not part of cCount subsequences.
Therefore we do cCount = (bCount + 2 * cCount);
5) Finally we return cCount;
Below is the implementation of above idea :

C++

// C++ program to count subsequences of the


// form a^i b^j c^k
#include <bits/stdc++.h>
using namespace std;
  
// Returns count of subsequences of the form
// a^i b^j c^k
int countSubsequences(string s)
{
    // Initialize counts of different subsequences
    // caused by different combination of 'a'
    int aCount = 0;
  
    // Initialize counts of different subsequences
    // caused by different combination of 'a' and
    // different combination of 'b'
    int bCount = 0;
  
    // Initialize counts of different subsequences
    // caused by different combination of 'a', 'b'
    // and 'c'.
    int cCount = 0;

2282
Chapter 315. Number of subsequences of the form a^i b^j c^k

  
    // Traverse all characters of given string
    for (unsigned int i=0; i<s.size(); i++)
    {
        /* If current character is 'a', then
           there are following possibilities :
             a) Current character begins a new
                subsequence.
             b) Current character is part of aCount
                subsequences.
             c) Current character is not part of
                aCount subsequences. */
        if (s[i] == 'a')
            aCount = (1 + 2 * aCount);
  
        /* If current character is 'b', then
           there are following possibilities :
             a) Current character begins a new
                subsequence of b's with aCount
                subsequences.
             b) Current character is part of bCount
                subsequences.
             c) Current character is not part of
                bCount subsequences. */
        else if (s[i] == 'b')
            bCount = (aCount + 2 * bCount);
  
        /* If current character is 'c', then
           there are following possibilities :
             a) Current character begins a new
                subsequence of c's with bCount
                subsequences.
             b) Current character is part of cCount
                subsequences.
             c) Current character is not part of
                cCount subsequences. */
        else if (s[i] == 'c')
            cCount = (bCount + 2 * cCount);
    }
  
    return cCount;
}
  
// Driver code
int main()
{
    string s = "abbc";
    cout << countSubsequences(s) << endl;

2283
Chapter 315. Number of subsequences of the form a^i b^j c^k

    return 0;
}

Java

// Java program to count subsequences of the


// form a^i b^j c^k
public class No_of_subsequence {
       
    // Returns count of subsequences of the form
    // a^i b^j c^k
    static int countSubsequences(String s)
    {
        // Initialize counts of different subsequences
        // caused by different combination of 'a'
        int aCount = 0;
       
        // Initialize counts of different subsequences
        // caused by different combination of 'a' and
        // different combination of 'b'
        int bCount = 0;
       
        // Initialize counts of different subsequences
        // caused by different combination of 'a', 'b'
        // and 'c'.
        int cCount = 0;
       
        // Traverse all characters of given string
        for (int i=0; i< s.length(); i++)
        {
            /* If current character is 'a', then
               there are following possibilities :
                 a) Current character begins a new
                    subsequence.
                 b) Current character is part of aCount
                    subsequences.
                 c) Current character is not part of
                    aCount subsequences. */
            if (s.charAt(i) == 'a')
                aCount = (1 + 2 * aCount);
       
            /* If current character is 'b', then
               there are following possibilities :
                 a) Current character begins a new
                    subsequence of b's with aCount
                    subsequences.
                 b) Current character is part of bCount
                    subsequences.

2284
Chapter 315. Number of subsequences of the form a^i b^j c^k

                 c) Current character is not part of


                    bCount subsequences. */
            else if (s.charAt(i) == 'b')
                bCount = (aCount + 2 * bCount);
       
            /* If current character is 'c', then
               there are following possibilities :
                 a) Current character begins a new
                    subsequence of c's with bCount
                    subsequences.
                 b) Current character is part of cCount
                    subsequences.
                 c) Current character is not part of
                    cCount subsequences. */
            else if (s.charAt(i) == 'c')
                cCount = (bCount + 2 * cCount);
        }
       
        return cCount;
    }
       
    // Driver code
    public static void main(String args[])
    {
        String s = "abbc";
        System.out.println(countSubsequences(s));
    }
}
// This code is contributed by Sumit Ghosh

C#

// C# program to count subsequences 


// of the form a^i b^j c^k
using System;
  
public class GFG {
      
    // Returns count of subsequences 
    // of the form a^i b^j c^k
    static int countSubsequences(String s)
    {
        // Initialize counts of different
        // subsequences caused by different
        // combination of 'a'
        int aCount = 0;
      
        // Initialize counts of different

2285
Chapter 315. Number of subsequences of the form a^i b^j c^k

        // subsequences caused by different


        // combination of 'a' and
        // different combination of 'b'
        int bCount = 0;
      
        // Initialize counts of different 
        // subsequences caused by different
        // combination of 'a', 'b' and 'c'
        int cCount = 0;
      
        // Traverse all characters of given string
        for (int i = 0; i < s.Length; i++)
        {
              
            // If current character is 'a', then
            // there are following possibilities :
            // a) Current character begins a
            //    new subsequence.
            // b) Current character is part 
            //    of aCount subsequences
            // c) Current character is not part
            //    of aCount subsequences.
  
            if (s[i] == 'a')
                aCount = (1 + 2 * aCount);
      
            // If current character is 'b', then
            // there are following possibilities :
            // a) Current character begins a new
            //    subsequence of b's with aCount
            //    subsequences.
            // b) Current character is part of bCount
            //    subsequences.
            // c) Current character is not part of
            //    bCount subsequences.
            else if (s[i] == 'b')
                bCount = (aCount + 2 * bCount);
      
            // If current character is 'c', then
            // there are following possibilities :
            // a) Current character begins a new
            //      subsequence of c's with bCount
            //      subsequences.
            // b) Current character is part of cCount
            //      subsequences.
            // c) Current character is not part of
            //      cCount subsequences.
            else if (s[i] == 'c')

2286
Chapter 315. Number of subsequences of the form a^i b^j c^k

                cCount = (bCount + 2 * cCount);


        }
      
        return cCount;
    }
      
    // Driver code
    public static void Main()
    {
        String s = "abbc";
        Console.Write(countSubsequences(s));
    }
}
  
// This code is contributed by Nitin Mittal.

PHP

<?php
// PHP program to count subsequences
// of the form a^i b^j c^k
  
// Returns count of subsequences
// of the form a^i b^j c^k
function countSubsequences($s)
{
      
    // Initialize counts of
    // different subsequences
    // caused by different 
    // combination of 'a'
    $aCount = 0;
  
    // Initialize counts of 
    // different subsequences
    // caused by different
    // combination of 'a' and
    // different combination of 'b'
    $bCount = 0;
  
    // Initialize counts of 
    // different subsequences
    // caused by different 
    // combination of 'a', 'b'
    // and 'c'.
    $cCount = 0;
  
    // Traverse all characters 

2287
Chapter 315. Number of subsequences of the form a^i b^j c^k

    // of given string


    for($i = 0; $i < strlen($s); $i++)
    {
          
        /* If current character is 'a', then
        there are following possibilities :
            a) Current character begins a new
                subsequence.
            b) Current character is part of aCount
                subsequences.
            c) Current character is not part of
                aCount subsequences. */
        if ($s[$i] == 'a')
            $aCount = (1 + 2 * $aCount);
  
        /* If current character is 'b', then
        there are following possibilities :
            a) Current character begins a new
                subsequence of b's with aCount
                subsequences.
            b) Current character is part of bCount
                subsequences.
            c) Current character is not part of
                bCount subsequences. */
        else if ($s[$i] == 'b')
            $bCount = ($aCount + 2 * $bCount);
  
        /* If current character is 'c', then
        there are following possibilities :
            a) Current character begins a new
                subsequence of c's with bCount
                subsequences.
            b) Current character is part of cCount
                subsequences.
            c) Current character is not part of
                cCount subsequences. */
        else if ($s[$i] == 'c')
            $cCount = ($bCount + 2 * $cCount);
    }
  
    return $cCount;
}
  
    // Driver Code
    $s = "abbc";
    echo countSubsequences($s) ;
  
// This code is contributed by nitin mittal.

2288
Chapter 315. Number of subsequences of the form a^i b^j c^k

?>

Output:

Time Complexity : O(n)


Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/number-subsequences-form-ai-bj-ck/

2289
Chapter 316

Number of subsets with sum


divisible by m

Number of subsets with sum divisible by m - GeeksforGeeks


Given an array of integers, find number of subsequence such that the sum of the subsequence
is divisible by m. It is given that sum of array elements is small.
Examples:

Input : arr[] = {1, 2, 3};


m = 3;
Output : 3
Subsequence of given set are
{1}, {2}, {3}, {1, 2}, {2, 3}, {1, 3} and {1, 2, 3}.
And their sums are 1, 2, 3, 3, 5, 4 and 6.

Input : arr[] = {1, 2, 3, 4};


m = 2;
Output : 7
{2}, {4}, {1, 3}, {2, 4}, {1, 2, 3}, {1, 3, 4}
and {1, 2, 3, 4}

A simple solution is to generate all possible subsets. For every subset, compute its sum
and if sum is multiiple of m, increment result by 1. Time complexity of this approach is
O(2len ) where len is length of input array.
An efficient solution (for small values) is based on Dynamic Programming solution of
subset sum problem. We make a 2D array of size sum x n.

// C++ program which returns the Number of sub sequences 


// (or subsets) which are divisible by m.

2290
Chapter 316. Number of subsets with sum divisible by m

#include <bits/stdc++.h>
using namespace std;
  
// Use Dynamic Programming to find
// sum of subsequences.
int sumSubSequence(vector<int> arr, int len, int m)
{
    // Find sum pf array elements
    int sum = 0;
    for (auto x : arr)
       sum += x;
  
    // dp[i][j] would be > 0 if arr[0..i-1] has
    // a subsequence with sum equal to j.
    vector<vector<int> > dp(len + 1, vector<int>(sum + 1, 0));
  
    // There is always sum equals zero
    for (int i = 0; i <= len; i++) 
        dp[i][0]++;
   
    // Fill up the dp table
    for (int i = 1; i <= len; i++) {
  
        dp[i][arr[i - 1]]++;
        for (int j = 1; j <= sum; j++) {
  
            if (dp[i - 1][j] > 0) {
                dp[i][j]++;
                dp[i][j + arr[i - 1]]++;
            }
        }
    }
  
    // Initialize the counter
    int count = 0;
    for (int j = 1; j <= sum; j++)
  
        // Check if the sum exists
        if (dp[len][j] > 0)
  
            // check sum is divisible by m
            if (j % m == 0)
                count += dp[len][j];
  
    return count;
}
  
// Driver Code

2291
Chapter 316. Number of subsets with sum divisible by m

int main()
{
    vector<int> arr{ 1, 2, 3 };
    int m = 3;
    int len = arr.size();
    cout << sumSubSequence(arr, len, m) << endl;
    return 0;
}

Output:

Time complexity of the above approach is O(len*sum) where len is the size of the array
and sum is the sum of all the integers in the array.

Source

https://www.geeksforgeeks.org/number-of-subsets-with-sum-divisible-by-m/

2292
Chapter 317

Number of substrings divisible


by 8 but not by 3

Number of substrings divisible by 8 but not by 3 - GeeksforGeeks


Given a string of digits “0-9”. The task is find the number of substrings which are divisible
by 8 but not by 3.
Examples :

Input : str = "888"


Output : 5
Substring indexes : (1, 1), (1, 2), (2, 2),
(2, 3), (3, 3).

Input : str = "6564525600"


Output : 15

A number is divisible by 3 if sum of its digits is divisible by 3. And the number is divisible
by 8 if last three digits are divisible by 8.
Now, the idea is to store the prefix sum of the string i.e count of prefixes such that sum of
the digits of the prefix modulo 3 is either 0, 1, 2. Next we iterate over the string and for
each position i, count the number of substrings ending at i and divisible by 8. From this
value, we subtract the number of substrings ending at i and divisible by 3.
We define a |S| X 3 size 2D array, |S| is size of string, say dp[i][j].
dp[i][j] can be define as at any index i, number of substring starting from index 0 to index
i having output j
when digits from index 0 are added upto index i and modulo 3. Therefore 0 <= j <= 2,
since modulo 3. Now, we will iterate over string and check each one digit number, two
digit number and three digit number which are divisible by 8. For one digit, just check if
character at index is 8 or not. For two digit, check whether it is divisible by 8 and not

2293
Chapter 317. Number of substrings divisible by 8 but not by 3

divisible by 3. For three digit, form the number and check if it is divisible by 8 or not. If
the number is divisible then last three digits must be divisible by 8. So all the substring
ending at this index must be divisible by 8 i.e (i-3) substrings. But it will also contain those
substring which are divisible by 3, so simply remove them using dp[i][j].
C/C++

// CPP Program to count substrings which are


// divisible by 8 but not by 3
#include <bits/stdc++.h>
using namespace std;
#define MAX 1000
  
// Returns count of substrings divisible by 8
// but not by 3.
int count(char s[], int len)
{
    int cur = 0, dig = 0;
    int sum[MAX], dp[MAX][3];
  
    memset(sum, 0, sizeof(sum));
    memset(dp, 0, sizeof(dp));
  
    dp[0][0] = 1;
  
    // Iterating the string.
    for (int i = 1; i <= len; i++)
    {
        dig = int(s[i-1])-48;
        cur += dig;
        cur %= 3;
  
        sum[i] = cur;
  
        // Prefix sum of number of substrings whose
        // sum of digits mudolo 3 is 0, 1, 2.
        dp[i][0] = dp[i-1][0];
        dp[i][1] = dp[i-1][1];
        dp[i][2] = dp[i-1][2];
  
        dp[i][sum[i]]++;
    }
  
    int ans = 0, dprev = 0, value = 0, dprev2 = 0;
  
    // Iterating the string.
    for (int i = 1; i <= len; i++)
    {
        dig = int(s[i-1])-48;

2294
Chapter 317. Number of substrings divisible by 8 but not by 3

  
        // Since single digit 8 is divisible
        // by 8 and not by 3.
        if (dig == 8)
            ans++;
  
        // Taking two digit number.
        if (i-2 >= 0)
        {
            dprev = int(s[i-2])-48;  // 10th position
            value = dprev*10 + dig;  // Complete 2 digit
                                     // number
  
            if ((value%8 == 0) && (value%3 != 0))
                ans++;
        }
  
        // Taking 3 digit number.
        if (i-3 >= 0)
        {
            dprev2 = int(s[i-3])-48; // 100th position
            dprev  = int(s[i-2])-48;  // 10th position
  
            // Complete 3 digit number.
            value = dprev2*100 + dprev*10 + dig;
  
            if (value%8 != 0)
                continue;
  
            // If number formed is divisible by 8 then
            // last 3 digits are  also divisible by 8.
            // Then all the substring ending at this
            // index is divisible.
            ans += (i-2);
  
            // But those substring also contain number
            // which are not divisible by 3 so
            // remove them.
            ans -= (dp[i-3][sum[i]]);
        }
    }
  
    return ans;
}
  
// Driven Program
int main()
{

2295
Chapter 317. Number of substrings divisible by 8 but not by 3

    char str[] = "6564525600";


    int len = strlen(str);
    cout << count(str, len) <<endl;
    return 0;
}

Java

// Java program to count substrings which are


// divisible by 8 but not by 3
import java.io.*;
  
class GFG 
{
    // Function that returns count of substrings divisible by 8
    // but not by 3
    static int count(String s, int len)
    {
        int MAX = 1000;
        int cur = 0, dig = 0;
        int[] sum = new int[MAX];
        int[][] dp = new int[MAX][3];
  
        dp[0][0] = 1;
   
        // Iterating the string.
        for (int i = 1; i <= len; i++)
        {
            dig = (int)(s.charAt(i-1)) - 48;
            cur += dig;
            cur %= 3;
   
            sum[i] = cur;
   
            // Prefix sum of number of substrings whose
            // sum of digits mudolo 3 is 0, 1, 2.
            dp[i][0] = dp[i-1][0];
            dp[i][1] = dp[i-1][1];
            dp[i][2] = dp[i-1][2];
   
            dp[i][sum[i]]++;
        }
   
        int ans = 0, dprev = 0, value = 0, dprev2 = 0;
   
        // Iterating the string.
        for (int i = 1; i <= len; i++)
        {

2296
Chapter 317. Number of substrings divisible by 8 but not by 3

            dig = (int)(s.charAt(i-1)) - 48;


   
            // Since single digit 8 is divisible
            // by 8 and not by 3.
            if (dig == 8)
                ans++;
   
            // Taking two digit number.
            if (i-2 >= 0)
            {
                dprev = (int)(s.charAt(i-2)) - 48;  // 10th position
                value = dprev*10 + dig;  // Complete 2 digit
                                     // number
      
                if ((value%8 == 0) && (value%3 != 0))
                    ans++;
            }
   
            // Taking 3 digit number.
            if (i-3 >= 0)
            {
                dprev2 = (int)(s.charAt(i-3)) - 48; // 100th position
                dprev  = (int)(s.charAt(i-2)) - 48;  // 10th position
   
                // Complete 3 digit number.
                value = dprev2*100 + dprev*10 + dig;
   
                if (value%8 != 0)
                    continue;
   
                // If number formed is divisible by 8 then
                // last 3 digits are  also divisible by 8.
                // Then all the substring ending at this
                // index is divisible.
                ans += (i-2);
   
                // But those substring also contain number
                // which are not divisible by 3 so
                // remove them.
                ans -= (dp[i-3][sum[i]]);
            }
        }
   
        return ans;
    }
      
    // driver program
    public static void main (String[] args) 

2297
Chapter 317. Number of substrings divisible by 8 but not by 3

    {
        String str = "6564525600";
        int len = str.length();
        System.out.println(count(str, len));
    }
}
  
// Contributed by Pramod Kumar

C#

// C# program to count substrings which are


// divisible by 8 but not by 3
using System;
  
class GFG 
{
    // Function that returns count of substrings 
    // divisible by 8 but not by 3
    static int count(String s, int len)
    {
        int MAX = 1000;
        int cur = 0, dig = 0;
        int[] sum = new int[MAX];
        int[,] dp = new int[MAX,3];
  
        dp[0, 0] = 1;
  
        // Iterating the string.
        for (int i = 1; i <= len; i++)
        {
            dig = (int)(s[i-1]) - 48;
            cur += dig;
            cur %= 3;
  
            sum[i] = cur;
  
            // Prefix sum of number of substrings whose
            // sum of digits mudolo 3 is 0, 1, 2.
            dp[i, 0] = dp[i-1, 0];
            dp[i, 1] = dp[i-1, 1];
            dp[i, 2] = dp[i-1, 2];
  
            dp[i, sum[i]]++;
        }
  
        int ans = 0, dprev = 0, value = 0, dprev2 = 0;
  

2298
Chapter 317. Number of substrings divisible by 8 but not by 3

        // Iterating the string.


        for (int i = 1; i <= len; i++)
        {
            dig = (int)(s[i-1]) - 48;
  
            // Since single digit 8 is divisible
            // by 8 and not by 3.
            if (dig == 8)
                ans++;
  
            // Taking two digit number.
            if (i-2 >= 0)
            {
                dprev = (int)(s[i-2]) - 48; // 10th position
                value = dprev*10 + dig;     // Complete 2 digit number
      
                if ((value % 8 == 0) && (value % 3 != 0))
                    ans++;
            }
  
            // Taking 3 digit number.
            if (i - 3 >= 0)
            {
                dprev2 = (int)(s[i-3]) - 48; // 100th position
                dprev = (int)(s[i-2]) - 48; // 10th position
  
                // Complete 3 digit number.
                value = dprev2 * 100 + dprev * 10 + dig;
  
                if (value % 8 != 0)
                    continue;
  
                // If number formed is divisible by 8 then
                // last 3 digits are also divisible by 8.
                // Then all the substring ending at this
                // index is divisible.
                ans += (i - 2);
  
                // But those substring also contain number
                // which are not divisible by 3 so
                // remove them.
                ans -= (dp[i - 3,sum[i]]);
            }
        }
  
        return ans;
    }
      

2299
Chapter 317. Number of substrings divisible by 8 but not by 3

    // driver program


    public static void Main (String[] args) 
    {
        String str = "6564525600";
        int len = str.Length;
        Console.Write(count(str, len));
    }
}
  
// This code is contributed by parashar.

Output:

15

Improved By : parashar

Source

https://www.geeksforgeeks.org/number-substrings-divisible-8-not-3/

2300
Chapter 318

Number of ways a convex


polygon of n+2 sides can split
into triangles by connecting
vertices

Number of ways a convex polygon of n+2 sides can split into triangles by connecting vertices
- GeeksforGeeks
Given a convex polygon with n+2 sides. The task is to calculate the number of ways in
which triangles can be formed by connecting vertices with non-crossing line segments.
Examples:

Input: n = 1
Output: 1
It is already a triangle so it can only be formed in 1 way.
Input: n = 2
Output: 2
It can be cut into 2 triangles by using either pair of opposite vertices.

2301
Chapter 318. Number of ways a convex polygon of n+2 sides can split into triangles by
connecting vertices

The above problem is an application of a catalan numbers. So, the task is to only find the
n’th Catalan Number. First few catalan numbers are 1 1 2 5 14 42 132 429 1430 4862, …
(considered from 0th number)
Below is the program to find Nth catalan number:

C++

// C++ program to find the


// nth catalan number
#include <bits/stdc++.h>
using namespace std;
  
// Returns value of Binomial Coefficient C(n, k)
unsigned long int binomialCoeff(unsigned int n,
                                unsigned int k)
{
    unsigned long int res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if (k > n - k)
        k = n - k;
  
    // Calculate value of
    // [n*(n-1)*---*(n-k+1)] / [k*(k-1)*---*1]
    for (int i = 0; i < k; ++i) {
        res *= (n - i);
        res /= (i + 1);
    }
  
    return res;

2302
Chapter 318. Number of ways a convex polygon of n+2 sides can split into triangles by
connecting vertices

}
  
// A Binomial coefficient based function
// to find nth catalan
// number in O(n) time
unsigned long int catalan(unsigned int n)
{
    // Calculate value of 2nCn
    unsigned long int c = binomialCoeff(2 * n, n);
  
    // return 2nCn/(n+1)
    return c / (n + 1);
}
  
// Driver code
int main()
{
    int n = 3;
    cout << catalan(n) << endl;
  
    return 0;
}

Java

// Java program to find the


// nth catalan number
class GFG
{
  
// Returns value of Binomial
// Coefficient C(n, k)
static long binomialCoeff(int n,
                          int k)
{
    long res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if (k > n - k)
        k = n - k;
  
    // Calculate value of
    // [n*(n-1)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for (int i = 0; i < k; ++i) 
    {
        res *= (n - i);
        res /= (i + 1);

2303
Chapter 318. Number of ways a convex polygon of n+2 sides can split into triangles by
connecting vertices

    }
  
    return res;
}
  
// A Binomial coefficient 
// based function to find 
// nth catalan number in 
// O(n) time
static long catalan( int n)
{
    // Calculate value of 2nCn
    long c = binomialCoeff(2 * n, n);
  
    // return 2nCn/(n+1)
    return c / (n + 1);
}
  
// Driver code
public static void main(String[] args)
{
    int n = 3;
    System.out.println(catalan(n));
}
}
  
// This code is contributed 
// by Arnab Kundu

C#

// C# program to find the


// nth catalan number
using System;
  
class GFG
{
  
// Returns value of Binomial
// Coefficient C(n, k)
static long binomialCoeff(int n,
                          int k)
{
    long res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if (k > n - k)
        k = n - k;

2304
Chapter 318. Number of ways a convex polygon of n+2 sides can split into triangles by
connecting vertices

  
    // Calculate value of
    // [n*(n-1)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for (int i = 0; i < k; ++i) 
    {
        res *= (n - i);
        res /= (i + 1);
    }
  
    return res;
}
  
// A Binomial coefficient 
// based function to find 
// nth catalan number in 
// O(n) time
static long catalan( int n)
{
    // Calculate value of 2nCn
    long c = binomialCoeff(2 * n, n);
  
    // return 2nCn/(n+1)
    return c / (n + 1);
}
  
// Driver code
public static void Main()
{
    int n = 3;
    Console.WriteLine(catalan(n));
}
}
  
// This code is contributed 
// by Subhadeep

PHP
$n – $k)
$k = $n – $k;
// Calculate value of
// [n*(n-1)*—*(n-k+1)] /
// [k*(k-1)*—*1]
for ($i = 0; $i < $k; ++$i) { $res *= ($n - $i); $res /= ($i + 1); } return $res; } // A Binomial
coefficient based // function to find nth catalan // number in O(n) time function catalan($n)
{ // Calculate value of 2nCn $c = binomialCoeff(2 * $n, $n); // return 2nCn/(n+1) return
$c / ($n + 1); } // Driver code $n = 3; echo catalan($n); // This code is contributed // by

2305
Chapter 318. Number of ways a convex polygon of n+2 sides can split into triangles by
connecting vertices

chandan_jnu. ?>
Output:

Improved By : andrew1234, tufan_gupta2000, Chandan_Kumar

Source

https://www.geeksforgeeks.org/number-of-ways-a-convex-polygon-of-n2-sides-can-split-into-triangles-by-connecting

2306
Chapter 319

Number of ways to arrange N


items under given constraints

Number of ways to arrange N items under given constraints - GeeksforGeeks


We are given N items which are of total K different colors. Items of the same color are
indistinguishable and colors can be numbered from 1 to K and count of items of each color
is also given as k1, k2 and so on. Now we need to arrange these items one by one under
a constraint that the last item of color i comes before the last item of color (i + 1) for all
possible colors. Our goal is to find out how many ways this can be achieved.
Examples:

Input : N = 3
k1 = 1 k2 = 2
Output : 2
Explanation :
Possible ways to arrange are,
k1, k2, k2
k2, k1, k2

Input : N = 4
k1 = 2 k2 = 2
Output : 3
Explanation :
Possible ways to arrange are,
k1, k2, k1, k2
k1, k1, k2, k2
k2, k1, k1, k2

We can solve this problem using dynamic programming. Let dp[i] stores the number of ways
to arrange first i colored items. For one colored item answer will be one because there is

2307
Chapter 319. Number of ways to arrange N items under given constraints

only one way. Now Let’s assume all items are in a sequence. Now, to go from dp[i] to dp[i
+ 1], we need to put at least one item of color (i + 1) at the very end, but the other items
of color (i + 1) can go anywhere in the sequence. The number of ways to arrange the item
of color (i + 1) is combination of (k1 + k2 .. + ki + k(i + 1) – 1) over (k(i + 1) – 1) which
can be represented as (k1 + k2 .. + ki + k(i + 1) – 1)C(k(i + 1) – 1). In this expression
we subtracted one because we need to put one item at the very end.
In below code, first we have calculated the combination values, you can read more about
that from here. After that we looped over all different color and calculated the final value
using above relation.

// C++ program to find number of ways to arrange


// items under given constraint
#include <bits/stdc++.h>
using namespace std;
  
// method returns number of ways with which items 
// can be arranged
int waysToArrange(int N, int K, int k[])
{
    int C[N + 1][N + 1];
    int i, j;
  
    // Calculate value of Binomial Coefficient in 
    // bottom up manner
    for (i = 0; i <= N; i++) {
        for (j = 0; j <= i; j++) {
  
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
  
            // Calculate value using previously 
            // stored values
            else
                C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]);
        }
    }
  
    // declare dp array to store result up to ith 
    // colored item
    int dp[K];
  
    // variable to keep track of count of items 
    // considered till now
    int count = 0;
  
    dp[0] = 1;
  

2308
Chapter 319. Number of ways to arrange N items under given constraints

    // loop over all different colors


    for (int i = 0; i < K; i++) {
  
        // populate next value using current value 
        // and stated relation
        dp[i + 1] = (dp[i] * C[count + k[i] - 1][k[i] - 1]);
        count += k[i];
    }
  
    // return value stored at last index
    return dp[K];
}
  
// Driver code to test above methods
int main()
{
    int N = 4;
    int k[] = { 2, 2 };
  
    int K = sizeof(k) / sizeof(int);
    cout << waysToArrange(N, K, k) << endl;
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/number-of-ways-to-arrange-n-items-under-given-constraints/

2309
Chapter 320

Number of ways to form a heap


with n distinct integers

Number of ways to form a heap with n distinct integers - GeeksforGeeks


Given n, how many distinctMax Heapcan be made from n distinct integers?
Examples:

Input : n = 3
Output : Assume the integers are 1, 2, 3.
Then the 2 possible max heaps are:
3
/ \
1 2

3
/ \
2 1

Input : n = 4
Output : Assume the integers are 1, 2, 3, 4.
Then the 3 possible max heaps are:
4
/ \
3 2
/
1

4
/ \
2 3

2310
Chapter 320. Number of ways to form a heap with n distinct integers

/
1

4
/ \
3 1
/
2

Since there is only one element as the root, it must be the largest number. Now we have n-1
remaining elements. The main observation here is that because of the max heap properties,
the structure of the heap nodes will remain the same in all instances, but only the values
in the nodes will change.
Assume there are l elements in the left sub-tree and r elements in the right sub-tree.
Now for the root, l + r = n-1. From this we can see that we can choose any l of the
remaining n-1 elements for the left sub-tree as they are all smaller than the root.

We know the there are ways to do this. Next for each instance of these, we can
have many heaps with l elements and for each of those we can have many heaps with r
elements. Thus we can consider them as subproblems and recur for the final answer as:

T(n) = * T(L) * T(R).


Now we have to find the values for l and r for a given n. We know that the height of the

heap h = . Also the maximum number of elements that can be present in the h

th level of any heap, m = , where the root is at the 0th level. Moreover the number of

elements actually present in the last level of the heap p = n – ( – 1). (since
number of nodes present till the penultimate level). Thus, there can be two cases: when
the last level is more than or equal to half-filled:

l= – 1, if p >= m / 2
(or) the last level is less than half-filled:

l= – 1 – ((m / 2) – p), if p < m / 2

(we get – 1 here because left subtree has nodes.


From this we can also say that r = n – l – 1.
We can use the dynamic programming approach discussed in this post here to find the

values of . Similarly if we look at the recursion tree for the optimal substructure
recurrence formed above, we can see that it also has overlapping subproblems property,
hence can be solved using dynamic programming:

T(7)

2311
Chapter 320. Number of ways to form a heap with n distinct integers

/ \
T(3) T(3)
/ \ / \
T(1) T(1) T(1) T(1)

Following is the c++ implementation of the above approach:

// CPP program to count max heaps with n distinct keys


#include <iostream>
using namespace std;
  
#define MAXN 105 // maximum value of n here
  
// dp[i] = number of max heaps for i distinct integers
int dp[MAXN]; 
  
// nck[i][j] = number of ways to choose j elements
//             form i elements, no order */
int nck[MAXN][MAXN]; 
  
// log2[i] = floor of logarithm of base 2 of i
int log2[MAXN]; 
  
// to calculate nCk
int choose(int n, int k)
{
    if (k > n)
        return 0;
    if (n <= 1)
        return 1;
    if (k == 0)
        return 1;
  
    if (nck[n][k] != -1)
        return nck[n][k];
  
    int answer = choose(n - 1, k - 1) + choose(n - 1, k);
    nck[n][k] = answer;
    return answer;
}
  
// calculate l for give value of n
int getLeft(int n)
{
    if (n == 1)
        return 0;
  
    int h = log2[n];

2312
Chapter 320. Number of ways to form a heap with n distinct integers

  
    // max number of elements that can be present in the 
    // hth level of any heap
    int numh = (1 << h); //(2 ^ h)
  
    // number of elements that are actually present in
    // last level(hth level)
    // (2^h - 1)
    int last = n - ((1 << h) - 1);
  
    // if more than half-filled
    if (last >= (numh / 2))
        return (1 << h) - 1; // (2^h) - 1
    else
        return (1 << h) - 1 - ((numh / 2) - last);
}
  
// find maximum number of heaps for n
int numberOfHeaps(int n)
{
    if (n <= 1)
        return 1;
  
    if (dp[n] != -1)
        return dp[n];
  
    int left = getLeft(n);
    int ans = (choose(n - 1, left) * numberOfHeaps(left)) * 
                             (numberOfHeaps(n - 1 - left));
    dp[n] = ans;
    return ans;
}
  
// function to initialize arrays
int solve(int n)
{
    for (int i = 0; i <= n; i++)
        dp[i] = -1;
  
    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= n; j++)
            nck[i][j] = -1;
  
    int currLog2 = -1;
    int currPower2 = 1;
  
    // for each power of two find logarithm
    for (int i = 1; i <= n; i++) {

2313
Chapter 320. Number of ways to form a heap with n distinct integers

        if (currPower2 == i) {
            currLog2++;
            currPower2 *= 2;
        }
        log2[i] = currLog2;
    }
  
    return numberOfHeaps(n);
}
  
// driver function
int main()
{
    int n = 10;
    cout << solve(n) << endl;
    return 0;
}

Output:

3360

Asked in: Directi.


Improved By : rsatish1110

Source

https://www.geeksforgeeks.org/number-ways-form-heap-n-distinct-integers/

2314
Chapter 321

Number of ways to form an


array with distinct adjacent
elements

Number of ways to form an array with distinct adjacent elements - GeeksforGeeks


Given three integers N, M and X, the task is to find the number of ways to form an array,
such that all consecutive numbers of the array are distinct, and the value at any index of
the array from 2 to N – 1(Considering 1 based indexing) lies between 1 and M, while the
value at index 1 is X and the value at index N is 1.
Note: Value of X lies between 1 and M.
Examples:

Input: N = 4, M = 3, X = 2
Output: 3
The following arrays are possible:
1) 2, 1, 2, 1
2) 2, 1, 3, 1
3) 2, 3, 2, 1
Input: N = 2, M = 3, X = 2
Output: 1
The only possible array is: 2, 1

Approach: The problem can be solved using Dynamic Programming. Let, f(i) represent
the number of ways to form the array till the ith index, such that every consecutive element
of the array is distinct. Let f(i, One) represent the number of ways to form the array till
the i-th index such that every consecutive element of the array is distinct and arri = 1.
Similarly, let f(i, Non-One) represent the number of ways to form the array till the ith
index, such that every consecutive element of the array is distinct and arri is not equal to 1.
The following recurrence is formed:

2315
Chapter 321. Number of ways to form an array with distinct adjacent elements

f(i, Non-One) = f(i - 1, One) * (M - 1) + f(i - 1, Non-One) * (M - 2)

which means that the number of ways to form the array till the ith index with arrayi not
equal to 1 is formed using two cases:

1. If the number at arrayi – 1 is 1, then opt one number out of (M – 1) options to place
at the ith index, since arrayi is not equal to 1.
2. If the number at arrayi – 1 is not 1, then we need to opt one number out of (M – 2)
options, since arrayi is not equal to 1 and arrayi � arrayi – 1 .

Similarly, f(i, One) = f(i – 1, Non-One), since the number of ways to form the array
till the ith index with arrayi = 1, is same as number of ways to form the array till the (i –
1)th index with arrayi – 1 � 1, thus at the ith index there is only one option. At the end the
required answer if f(N, One) since arrayN needs to be equal to 1.
Below is the implementation of the above approach:

C++

// C++ program to count the number of ways


// to form arrays of N numbers such that the
// first and last numbers are fixed
// and all consecutive numbers are distinct
#include <bits/stdc++.h>
using namespace std;
  
// Returns the total ways to form arrays such that
// every consecutive element is different and each
// element except the first and last can take values
// from 1 to M
int totalWays(int N, int M, int X)
{
  
    // define the dp[][] array
    int dp[N + 1][2];
  
    // if the first element is 1
    if (X == 1) {
  
        // there is only one way to place
        // a 1 at the first index
        dp[0][0] = 1;
    }
    else {
  
        // the value at first index needs to be 1,
        // thus there is no way to place a non-one integer

2316
Chapter 321. Number of ways to form an array with distinct adjacent elements

        dp[0][1] = 0;
    }
  
    // if the first element was 1 then at index 1,
    // only non one integer can be placed thus
    // there are M - 1 ways to place a non one integer
    // at index 2 and 0 ways to place a 1 at the 2nd index
    if (X == 1) {
        dp[1][0] = 0;
        dp[1][1] = M - 1;
    }
  
    // Else there is one way to place a one at
    // index 2 and if a non one needs to be placed here,
    // there are (M - 2) options, i.e
    // neither the element at this index
    // should be 1, neither should it be
    // equal to the previous element
    else {
        dp[1][0] = 1;
        dp[1][1] = (M - 2);
    }
  
    // Build the dp array in bottom up manner
    for (int i = 2; i < N; i++) {
  
        // f(i, one) = f(i - 1, non-one)
        dp[i][0] = dp[i - 1][1];
  
        // f(i, non-one) = f(i - 1, one) * (M - 1) +
        // f(i - 1, non-one) * (M - 2)
        dp[i][1] = dp[i - 1][0] * (M - 1) + dp[i - 1][1] * (M - 2);
    }
  
    // last element needs to be one, so return dp[n - 1][0]
    return dp[N - 1][0];
}
  
// Driver Code
int main()
{
  
    int N = 4, M = 3, X = 2;
    cout << totalWays(N, M, X) << endl;
  
    return 0;
}

2317
Chapter 321. Number of ways to form an array with distinct adjacent elements

Java

// Java program to count the 


// number of ways to form 
// arrays of N numbers such 
// that the first and last 
// numbers are fixed and all 
// consecutive numbers are 
// distinct
import java.io.*;
  
class GFG 
{
  
// Returns the total ways to 
// form arrays such that every 
// consecutive element is 
// different and each element 
// except the first and last 
// can take values from 1 to M
static int totalWays(int N, 
                     int M, int X)
{
  
    // define the dp[][] array
    int dp[][] = new int[N + 1][2];
  
    // if the first element is 1
    if (X == 1) 
    {
  
        // there is only one 
        // way to place a 1 
        // at the first index
        dp[0][0] = 1;
    }
    else 
    {
  
        // the value at first index 
        // needs to be 1, thus there 
        // is no way to place a 
        // non-one integer
        dp[0][1] = 0;
    }
  
    // if the first element was 1 
    // then at index 1, only non 

2318
Chapter 321. Number of ways to form an array with distinct adjacent elements

    // one integer can be placed 


    // thus there are M - 1 ways 
    // to place a non one integer
    // at index 2 and 0 ways to 
    // place a 1 at the 2nd index
    if (X == 1)
    {
        dp[1][0] = 0;
        dp[1][1] = M - 1;
    }
  
    // Else there is one way to 
    // place a one at index 2 
    // and if a non one needs to 
    // be placed here, there are 
    // (M - 2) options, i.e neither
    // the element at this index
    // should be 1, neither should 
    // it be equal to the previous 
    // element
    else 
    {
        dp[1][0] = 1;
        dp[1][1] = (M - 2);
    }
  
    // Build the dp array
    // in bottom up manner
    for (int i = 2; i < N; i++) 
    {
  
        // f(i, one) = f(i - 1, 
        // non-one)
        dp[i][0] = dp[i - 1][1];
  
        // f(i, non-one) = 
        // f(i - 1, one) * (M - 1) +
        // f(i - 1, non-one) * (M - 2)
        dp[i][1] = dp[i - 1][0] * (M - 1) + 
                   dp[i - 1][1] * (M - 2);
    }
  
    // last element needs to be
    // one, so return dp[n - 1][0]
    return dp[N - 1][0];
}
  
// Driver Code

2319
Chapter 321. Number of ways to form an array with distinct adjacent elements

public static void main (String[] args)


{
    int N = 4, M = 3, X = 2;
    System.out.println(totalWays(N, M, X));
}
}
  
// This code is contributed by anuj_67.

C#

// C# program to count the 


// number of ways to form 
// arrays of N numbers such 
// that the first and last 
// numbers are fixed and all 
// consecutive numbers are 
// distinct
using System;
  
class GFG 
{
  
// Returns the total ways to 
// form arrays such that every 
// consecutive element is 
// different and each element 
// except the first and last 
// can take values from 1 to M
static int totalWays(int N, 
                     int M, int X)
{
  
    // define the dp[][] array
    int [,]dp = new int[N + 1, 2];
  
    // if the first element is 1
    if (X == 1) 
    {
  
        // there is only one 
        // way to place a 1 
        // at the first index
        dp[0, 0] = 1;
    }
    else
    {
  

2320
Chapter 321. Number of ways to form an array with distinct adjacent elements

        // the value at first index 


        // needs to be 1, thus there 
        // is no way to place a 
        // non-one integer
        dp[0, 1] = 0;
    }
  
    // if the first element was 1 
    // then at index 1, only non 
    // one integer can be placed 
    // thus there are M - 1 ways 
    // to place a non one integer
    // at index 2 and 0 ways to 
    // place a 1 at the 2nd index
    if (X == 1)
    {
        dp[1, 0] = 0;
        dp[1, 1] = M - 1;
    }
  
    // Else there is one way to 
    // place a one at index 2 
    // and if a non one needs to 
    // be placed here, there are 
    // (M - 2) options, i.e neither
    // the element at this index
    // should be 1, neither should 
    // it be equal to the previous 
    // element
    else
    {
        dp[1, 0] = 1;
        dp[1, 1] = (M - 2);
    }
  
    // Build the dp array
    // in bottom up manner
    for (int i = 2; i < N; i++) 
    {
  
        // f(i, one) = f(i - 1, 
        // non-one)
        dp[i, 0] = dp[i - 1, 1];
  
        // f(i, non-one) = 
        // f(i - 1, one) * (M - 1) +
        // f(i - 1, non-one) * (M - 2)
        dp[i, 1] = dp[i - 1, 0] * (M - 1) + 

2321
Chapter 321. Number of ways to form an array with distinct adjacent elements

                   dp[i - 1, 1] * (M - 2);
    }
  
    // last element needs to be
    // one, so return dp[n - 1][0]
    return dp[N - 1, 0];
}
  
// Driver Code
public static void Main ()
{
    int N = 4, M = 3, X = 2;
    Console.WriteLine(totalWays(N, M, X));
}
}
  
// This code is contributed
// by anuj_67.

PHP

<?php
// PHP program to count the 
// number of ways to form 
// arrays of N numbers such 
// that the first and last 
// numbers are fixed and all 
// consecutive numbers are distinct
  
// Returns the total ways to 
// form arrays such that every
// consecutive element is 
// different and each element 
// except the first and last 
// can take values from 1 to M
function totalWays($N, $M, $X)
{
  
    // define the dp[][] array
    $dp = array(array());
  
    // if the first element is 1
    if ($X == 1) 
    {
  
        // there is only one 
        // way to place a 1
        // at the first index

2322
Chapter 321. Number of ways to form an array with distinct adjacent elements

        $dp[0][0] = 1;
    }
    else 
    {
  
        // the value at first 
        // index needs to be 1,
        // thus there is no way 
        // to place a non-one integer
        $dp[0][1] = 0;
    }
  
    // if the first element was 
    // 1 then at index 1, only 
    // non one integer can be 
    // placed thus there are M - 1 
    // ways to place a non one 
    // integer at index 2 and 0 ways
    // to place a 1 at the 2nd index
    if ($X == 1) 
    {
        $dp[1][0] = 0;
        $dp[1][1] = $M - 1;
    }
  
    // Else there is one way 
    // to place a one at index 
    // 2 and if a non one needs 
    // to be placed here, there 
    // are (M - 2) options, i.e
    // neither the element at 
    // this index should be 1,
    // neither should it be equal 
    // to the previous element
    else 
    {
        $dp[1][0] = 1;
        $dp[1][1] = ($M - 2);
    }
  
    // Build the dp array
    // in bottom up manner
    for ($i = 2; $i <$N; $i++) 
    {
  
        // f(i, one) = 
        // f(i - 1, non-one)
        $dp[$i][0] = $dp[$i - 1][1];

2323
Chapter 321. Number of ways to form an array with distinct adjacent elements

  
        // f(i, non-one) = 
        // f(i - 1, one) * (M - 1) +
        // f(i - 1, non-one) * (M - 2)
        $dp[$i][1] = $dp[$i - 1][0] * 
                           ($M - 1) + 
                     $dp[$i - 1][1] * 
                           ($M - 2);
    }
  
    // last element needs to 
    // be one, so return dp[n - 1][0]
    return $dp[$N - 1][0];
}
  
// Driver Code
$N = 4; $M = 3; $X = 2;
echo totalWays($N, $M, $X);
  
// This code is contributed
// by anuj_67.
?>

Output:

Time Complexity: O(N), where N is the size of the array


Improved By : vt_m

Source

https://www.geeksforgeeks.org/number-of-ways-to-form-an-array-with-distinct-adjacent-elements/

2324
Chapter 322

Number of ways to insert a


character to increase the LCS
by one

Number of ways to insert a character to increase the LCS by one - GeeksforGeeks


Given two strings A and B. The task is to count the number of ways to insert a character
in string A to increase the length of Longest Common Subsequence between string A and
string B by 1.
Examples:

Input : A = “aa”, B = “baaa”


Output : 4
The longest common subsequence shared by string A and string B is “aa”, which
has a length of 2.
There are two ways that the length of the longest common subsequence can be
increased to 3 by adding a single character to string A:

1. There are 3 different positions in string A where we could insert an addi-


tional ‘a’ to create longest common subsequence “aaa” (i.e at the beginning,
middle, and end of the string).
2. We can insert a ‘b’ at the beginning of the string for a new longest common
subsequence of “baaa”. So, we have 3 + 1 = 4 ways to insert an alphanu-
meric character into string A and increase the length of the longest common
subsequence by one.

Let say for a given string A and string B, the length of their LCS is k. Let’s insert a
single character ‘c’ after the ith character in string A and denote the string formed after the
insertion as string Anew , which looks like:
Anew = A1, i . c . Ai + 1, n

2325
Chapter 322. Number of ways to insert a character to increase the LCS by one

where Ai, j denotes a substring of string A from the ith to the jth characters and ‘.’ denotes
a concatenation of two strings.
Let’s define knew to be the length of the LCS of Anew and B. Now we want to know if knew
= k + 1.
The crucial observation is that the newly inserted character ‘c’ must be a part of any common
subsequence of Anew and B having length > k. We know this because if there is any common
subsequence of Anew and B, this is a contradiction, because it would mean the length of the
LCS of A and B is > k.
Using the above observation, we can try the following approach. For each possible character
‘c’(there are 52 upper and lower case English letters and 10 arabic digits, so there are 62
possible characters to insert) and for every possible insertion possible i in String A (there
are |a| + 1 insertion positions), let’s try to insert ‘c’ after the ith character in string A and
match it with every occurance of ‘c’ in string B, we can try to match these ‘c’ characters
such that:
A1, i . c . Ai+1, n
A1, j-1 . c . Ai+1, m
Now, in order to check if such an insertion produces an LCS of length k + 1, it’s sufficienet
to check if the length of the LCS of A1, i and B1, j-1 plus the length of the LCS Ai+1, n
and Bj+1, m is equal to k. In this case, the lCS of Anew and B is k + 1 because there is
both a match between the fixed occurances of character ‘c’ and there is no longer common
subsequence between them.
If we can quickly get the length of the LCS between every two prefixes of A nad B as
well as between every two of their suffixes, we can compute the result. The length of the
LCS between their prefixes can be read from from a Dynamic Programming table used in
computing the LCS of string A and string B. In this method, dp[i][j] stores the length of
longest common subsequence of A, i and Bi, j . Similarly, the length of the LCS between their
suffixes can be read from an analogous dp tables which can be computed during computation
of the LCS of Areversed and Breversed where Sreversed denotes the reversed string S.

// CPP Program to Number of ways to insert a


// character to increase LCS by one
#include <bits/stdc++.h>
#define MAX 256
using namespace std;
  
// Return the Number of ways to insert a
// character to increase the Longest
// Common Subsequence by one
int numberofways(string A, string B, int N, int M)
{
    vector<int> pos[MAX];
  
    // Insert all positions of all characters
    // in string B.
    for (int i = 0; i < M; i++)
        pos[B[i]].push_back(i + 1);
  

2326
Chapter 322. Number of ways to insert a character to increase the LCS by one

    // Longest Common Subsequence


    int dpl[N + 2][M + 2];
    memset(dpl, 0, sizeof(dpl));
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= M; j++) {
            if (A[i - 1] == B[j - 1])
                dpl[i][j] = dpl[i - 1][j - 1] + 1;
            else
                dpl[i][j] = max(dpl[i - 1][j],
                                dpl[i][j - 1]);
        }
    }
    int LCS = dpl[N][M];
  
    // Longest Common Subsequence from reverse
    int dpr[N + 2][M + 2];
    memset(dpr, 0, sizeof(dpr));
    for (int i = N; i >= 1; i--) {
        for (int j = M; j >= 1; j--) {
            if (A[i - 1] == B[j - 1])
                dpr[i][j] = dpr[i + 1][j + 1] + 1;
            else
                dpr[i][j] = max(dpr[i + 1][j],
                                dpr[i][j + 1]);
        }
    }
  
    // inserting character between position
    // i and i+1
    int ans = 0;
    for (int i = 0; i <= N; i++) {
        for (int j = 0; j < MAX; j++) {
            for (auto x : pos[j]) {
                if (dpl[i][x - 1] + dpr[i + 1][x + 1] == LCS) {
                    ans++;
                    break;
                }
            }
        }
    }
  
    return ans;
}
  
// Driven Program
int main()
{
    string A = "aa", B = "baaa";

2327
Chapter 322. Number of ways to insert a character to increase the LCS by one

    int N = A.length(), M = B.length();


    cout << numberofways(A, B, N, M) << endl;
    return 0;
}

Output:

Time Complexity: O(N x M)

Source

https://www.geeksforgeeks.org/number-ways-insert-character-increase-lcs-one/

2328
Chapter 323

Number of ways to reach Nth


floor by taking at-most K leaps

Number of ways to reach Nth floor by taking at-most K leaps - GeeksforGeeks


Given N number of stairs. Also given the number of steps that one can cover at most
in one leap (K). The task is to find the number of possible ways one (only consider
combinations) can climb to the top of the building in K leaps or less from the ground
floor.
Examples:

Input: N = 5, K = 3
Output: 5
To reach stair no-5 we can choose following combination of leaps:
11111
1112
122
113
23
Therefore the answer is 5.
Input: N = 29, K = 5
Output: 603

Let combo[i] be the number of ways to reach the i-th floor. Hence the number of ways to reach
combo[i] from combo[j] by taking a leap of i-j will be combo[i] += combo[j]. So iterate
for all possible leaps, and for each possible leaps keep adding the possible combinations to
the combo array. The final answer will be stored in combo[N].
Below is the implementation of the above approach.

C++

2329
Chapter 323. Number of ways to reach Nth floor by taking at-most K leaps

// C++ program to reach N-th stair 


// by taking a maximum of K leap 
#include <bits/stdc++.h> 
  
using namespace std; 
  
int solve(int N, int K) 

  
    // elements of combo[] stores the no of 
    // possible ways to reach it by all 
    // combinations of k leaps or less 
  
    int combo[N + 1] = { 0 }; 
  
    // assuming leap 0 exist and assigning 
    // its value to 1 for calculation 
    combo[0] = 1; 
  
    // loop to iterate over all 
    // possible leaps upto k; 
    for (int i = 1; i <= K; i++) { 
  
        // in this loop we count all possible 
        // leaps to reach the jth stair with 
        // the help of ith leap or less 
        for (int j = 0; j <= N; j++) { 
  
            // if the leap is not more than the i-j 
            if (j >= i) { 
  
                // calculate the value and 
                // store in combo[j] 
                // to reuse it for next leap 
                // calculation for the jth stair 
                combo[j] += combo[j - i]; 
            } 
        } 
    } 
  
    // returns the no of possible number 
    // of leaps to reach the top of 
    // building of n stairs 
    return combo[N]; 

  
// Driver Code 
int main() 

2330
Chapter 323. Number of ways to reach Nth floor by taking at-most K leaps


    // N i the no of total stairs 
    // K is the value of the greatest leap 
    int N = 29; 
    int K = 5; 
  
    cout << solve(N, K); 
  
    solve(N, K); 
    return 0; 

Java

// Java program to reach N-th 


// stair by taking a maximum 
// of K leap
class GFG
{
static int solve(int N, int K)
{
  
    // elements of combo[] stores 
    // the no. of possible ways 
    // to reach it by all combinations
    // of k leaps or less
    int[] combo;
    combo = new int[50];
  
    // assuming leap 0 exist 
    // and assigning its value
    // to 1 for calculation
    combo[0] = 1;
  
    // loop to iterate over all
    // possible leaps upto k;
    for (int i = 1; i <= K; i++) 
    {
  
        // in this loop we count all
        // possible leaps to reach
        // the jth stair with the 
        // help of ith leap or less
        for (int j = 0; j <= N; j++) 
        {
  
            // if the leap is not
            // more than the i-j

2331
Chapter 323. Number of ways to reach Nth floor by taking at-most K leaps

            if (j >= i)
            {
  
                // calculate the value and 
                // store in combo[j] to 
                // reuse it for next leap
                // calculation for the 
                // jth stair
                combo[j] += combo[j - i];
            }
        }
    }
  
    // returns the no of possible 
    // number of leaps to reach 
    // the top of building of 
    // n stairs
    return combo[N];
}
  
// Driver Code
public static void main(String args[])
{
    // N i the no of total stairs
    // K is the value of the 
    // greatest leap
    int N = 29;
    int K = 5;
  
    System.out.println(solve(N, K));
  
    solve(N, K);
}
}
  
// This code is contributed 
// by ankita_saini

C#

// C# program to reach N-th 


// stair by taking a maximum 
// of K leap
using System;
  
class GFG
{
static int solve(int N, int K)

2332
Chapter 323. Number of ways to reach Nth floor by taking at-most K leaps

{
  
    // elements of combo[] stores 
    // the no. of possible ways 
    // to reach it by all combinations
    // of k leaps or less
    int[] combo;
    combo = new int[50];
  
    // assuming leap 0 exist 
    // and assigning its value
    // to 1 for calculation
    combo[0] = 1;
  
    // loop to iterate over all
    // possible leaps upto k;
    for (int i = 1; i <= K; i++) 
    {
  
        // in this loop we count all
        // possible leaps to reach
        // the jth stair with the 
        // help of ith leap or less
        for (int j = 0; j <= N; j++) 
        {
  
            // if the leap is not
            // more than the i-j
            if (j >= i)
            {
  
                // calculate the value and 
                // store in combo[j] to 
                // reuse it for next leap
                // calculation for the 
                // jth stair
                combo[j] += combo[j - i];
            }
        }
    }
  
    // returns the no of possible 
    // number of leaps to reach 
    // the top of building of 
    // n stairs
    return combo[N];
}
  

2333
Chapter 323. Number of ways to reach Nth floor by taking at-most K leaps

// Driver Code
public static void Main()
{
    // N i the no of total stairs
    // K is the value of the 
    // greatest leap
    int N = 29;
    int K = 5;
  
    Console.WriteLine(solve(N, K));
    solve(N, K);
}
}
  
// This code is contributed 
// by Akanksha Rai(Abby_akku)

PHP

<?php
error_reporting(0);
// PHP program to reach N-th 
// stair by taking a maximum 
// of K leap 
function solve($N, $K) 

  
    // elements of combo[] stores 
    // the no of possible ways to 
    // reach it by all combinations
    // of k leaps or less 
    $combo[$N + 1] = array(); 
  
    // assuming leap 0 exist and 
    // assigning its value to 1 
    // for calculation 
    $combo[0] = 1; 
      
    // loop to iterate over all 
    // possible leaps upto k; 
    for ($i = 1; $i <= $K; $i++) 
    { 
  
        // in this loop we count 
        // all possible leaps to 
        // reach the jth stair with 
        // the help of ith leap or less 
        for ($j = 0; $j <= $N; $j++)

2334
Chapter 323. Number of ways to reach Nth floor by taking at-most K leaps

        { 
            // if the leap is not
            // more than the i-j 
            if ($j >= $i)
            { 
  
                // calculate the value and 
                // store in combo[j] 
                // to reuse it for next leap 
                // calculation for the jth stair 
                $combo[$j] += $combo[$j - $i]; 
            } 
        } 
    } 
  
    // returns the no of possible 
    // number of leaps to reach 
    // the top of building of n stairs 
    return $combo[$N]; 

  
// Driver Code 
  
// N i the no of total stairs 
// K is the value of the greatest leap 
$N = 29; 
$K = 5; 
  
echo solve($N, $K); 
  
solve($N, $K); 
  
// This code is contributed 
// by Akanksha Rai(Abby_akku) 
?>

Output:

603

Time Complexity: O(N*K)


Auxiliary Space: O(N)
Improved By : ankita_saini, Abby_akku

2335
Chapter 323. Number of ways to reach Nth floor by taking at-most K leaps

Source

https://www.geeksforgeeks.org/number-of-ways-to-reach-nth-floor-by-taking-at-most-k-leaps/

2336
Chapter 324

Number of ways to represent a


number as sum of k fibonacci
numbers

Number of ways to represent a number as sum of k fibonacci numbers - GeeksforGeeks


Given two numbers N and K. Find the number of ways to represent N as the sum of K
Fibonacci numbers.
Examples:

Input : n = 12, k = 1
Output : 0

Input : n = 13, k = 3
Output : 2
Explanation : 2 + 3 + 8, 3 + 5 + 5.

Approach: The Fibonacci series is f(0)=1, f(1)=2 and f(i)=f(i-1)+f(i-2) for i>1. Let’s
suppose F(x, k, n) be the number of ways to form the sum x using exactly k numbers
from f(0), f(1), …f(n-1). To find a recurrence for F(x, k, n), notice that there are two cases:
whether f(n-1) in the sum or not.

• If f(n-1) is not in the sum, then x is formed as a sum using exactly k numbers
from f(0), f(1), …, f(n-2).
• If f(n-1) is in the sum, then the remaining x-f(n-1) is formed using exactly k-
1 numbers from f(0), f(1), …, f(n-1). (Notice that f(n-1) is still included because
duplicate numbers are allowed.).

So the recurrence relation will be:

2337
Chapter 324. Number of ways to represent a number as sum of k fibonacci numbers

F(x, k, n)= F(x, k, n-1)+F(x-f(n-1), k-1, n)

Base cases:

• If k=0, then there are zero numbers from the series, so the sum can only be 0. Hence,
F(0, 0, n)=1.
• F(x, 0, n)=0, if x is not equals to 0.

Also, there are other cases that make F(x, k, n)=0, like the following:

• If k>0 and x=0 because having at least one positive number must result in a positive
sum.
• If k>0 and n=0 because there’s no possible choice of numbers left.
• If x<0 because there’s no way to form a negative sum using a finite number of non-
negative numbers.

Below is the implementation of above approach:

#include <bits/stdc++.h>
using namespace std;
  
// to store fibonacci numbers
// 42 second number in fibonacci series
// largest possible integer
int fib[43] = { 0 };
  
// Function to generate fibonacci series
void fibonacci()
{
    fib[0] = 1;
    fib[1] = 2;
    for (int i = 2; i < 43; i++)
        fib[i] = fib[i - 1] + fib[i - 2];
}
  
// Recursive function to return the 
// number of ways 
int rec(int x, int y, int last)
{
    // base condition
    if (y == 0) {
        if (x == 0)
            return 1;
        return 0;
    }
    int sum = 0;

2338
Chapter 324. Number of ways to represent a number as sum of k fibonacci numbers

    // for recursive function call


    for (int i = last; i >= 0 and fib[i] * y >= x; i--) {
        if (fib[i] > x)
            continue;
        sum += rec(x - fib[i], y - 1, i);
    }
    return sum;
}
  
// Driver code
int main()
{
    fibonacci();
    int n = 13, k = 3;
    cout << "Possible ways are: "
         << rec(n, k, 42);
  
    return 0;
}

Output:

Possible ways are: 2

Source

https://www.geeksforgeeks.org/number-of-ways-to-represent-a-number-as-sum-of-k-fibonacci-numbers/

2339
Chapter 325

Padovan Sequence

Padovan Sequence - GeeksforGeeks


Padovan Sequence similar to Fibonacci sequence with similar recursive structure. The re-
cursive formula is,

P(n) = P(n-2) + P(n-3)


P(0) = P(1) = P(2) = 1

Fibonacci Sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55……


Spiral of squares with side lengths which follow the Fibonacci sequence.

Padovan Sequence: 1, 1, 1, 2, 2, 3, 4, 5, 7, 9, 12, 16, 21, 28, 37,…..


Spiral of equilateral triangles with side lengths which follow the Padovan sequence.

2340
Chapter 325. Padovan Sequence

Examples:

For Padovan Sequence:


P0 = P1 = P2 = 1 ,
P(7) = P(5) + P(4)
= P(3) + P(2) + P(2) + P(1)
= P(2) + P(1) + 1 + 1 + 1
= 1 + 1 + 1 + 1 + 1
= 5

C++

// C++ program to find n'th term in Padovan Sequence


// using Dynamic Programming
#include<iostream>
using namespace std;
  
/* Function to calculate padovan number P(n) */
int pad(int n)
{
    /* 0th ,1st and 2nd number of the series are 1*/
    int pPrevPrev = 1, pPrev = 1, pCurr = 1, pNext = 1;
  
    for (int i=3; i<=n; i++)
    {
        pNext = pPrevPrev + pPrev;
        pPrevPrev = pPrev;
        pPrev = pCurr;
        pCurr = pNext;
    }
  
    return pNext;

2341
Chapter 325. Padovan Sequence

}
  
/* Driver Program */
int main()
{
    int n = 12;
    cout << pad(n);
    return 0;
}

Java

// Java program to find n'th term


// in Padovan Sequence using
// Dynamic Programming
import java.io.*;
  
class GFG {
      
    /* Function to calculate
    padovan number P(n) */
    static int pad(int n)
    {
        /* 0th, 1st and 2nd number 
        of the series are 1*/
        int pPrevPrev = 1, pPrev = 1,
            pCurr = 1, pNext = 1;
  
        for (int i = 3; i <= n; i++) {
            pNext = pPrevPrev + pPrev;
            pPrevPrev = pPrev;
            pPrev = pCurr;
            pCurr = pNext;
        }
  
        return pNext;
    }
  
    /* Driver Program */
    public static void main(String args[])
    {
        int n = 12;
        System.out.println(pad(n));
    }
}
  
/*This code is contributed by Nikita Tiwari.*/

2342
Chapter 325. Padovan Sequence

Python

# Python program to find n'th term in Padovan


# Sequence using Dynamic Programming
  
# Function to calculate padovan number P(n)
def pad(n):
  
    # 0th ,1st and 2nd number of the series are 1
    pPrevPrev, pPrev, pCurr, pNext = 1, 1, 1, 1
  
    # Find n'th Padovan number using recursive
    # formula.
    for i in range(3, n+1):
        pNext = pPrevPrev + pPrev
        pPrevPrev = pPrev
        pPrev = pCurr
        pCurr = pNext
  
    return pNext;
  
# Driver Code
print pad(12)

C#

// C# program to find n'th term


// in Padovan Sequence using
// Dynamic Programming
using System;
  
class GFG {
  
    /* Function to calculate
    padovan number P(n) */
    static int pad(int n)
    {
          
        /* 0th, 1st and 2nd number 
        of the series are 1*/
        int pPrevPrev = 1, pPrev = 1,
            pCurr = 1, pNext = 1;
  
        for (int i = 3; i <= n; i++) {
            pNext = pPrevPrev + pPrev;
            pPrevPrev = pPrev;
            pPrev = pCurr;

2343
Chapter 325. Padovan Sequence

            pCurr = pNext;
        }
  
        return pNext;
    }
  
    /* Driver Program */
    public static void Main()
    {
        int n = 12;
          
        Console.WriteLine(pad(n));
    }
}
  
/*This code is contributed by vt_m.*/

PHP

<?php
// PHP program to find n'th 
// term in Padovan Sequence
// using Dynamic Programming
  
// Function to calculate 
// padovan number P(n)
function pad($n)
{
      
    // 0th ,1st and 2nd number
    // of the series are 1
    $pPrevPrev = 1; $pPrev = 1; 
    $pCurr = 1; $pNext = 1;
  
    for ($i = 3; $i <= $n; $i++)
    {
        $pNext = $pPrevPrev + $pPrev;
        $pPrevPrev = $pPrev;
        $pPrev = $pCurr;
        $pCurr = $pNext;
    }
  
    return $pNext;
}
  
// Driver Code
$n = 12;
echo(pad($n));

2344
Chapter 325. Padovan Sequence

  
// This code is contributed by Ajit.
?>

Output:

21

Improved By : jit_t

Source

https://www.geeksforgeeks.org/padovan-sequence/

2345
Chapter 326

Painting Fence Algorithm

Painting Fence Algorithm - GeeksforGeeks


Given a fence with n posts and k colors, find out the number of ways of painting the fence
such that at most 2 adjacent posts have the same color. Since answer can be large return it
modulo 10^9 + 7.
Examples:

Input : n = 2 k = 4
Output : 16
We have 4 colors and 2 posts.
Ways when both posts have same color : 4
Ways when both posts have diff color :
4*(choices for 1st post) * 3(choices for
2nd post) = 12

Input : n = 3 k = 2
Output : 6

2346
Chapter 326. Painting Fence Algorithm

Following image depicts the 6 possible ways of painting 3 posts with 2 colors:
Consider the following image in which c, c’ and c” are respective colors of posts i, i-1 and i
-2.

According to the constraint of the problem, c = c’ = c” is not possible simultaneously, so


either c’ != c or c” != c or both. There are k – 1 possibilities for c’ != c and k – 1 for c” !=
c.

diff = no of ways when color of last


two posts is different

2347
Chapter 326. Painting Fence Algorithm

same = no of ways when color of last


two posts is same
total ways = diff + sum

for n = 1
diff = k, same = 0
total = k

for n = 2
diff = k * (k-1) //k choices for
first post, k-1 for next
same = k //k choices for common
color of two posts
total = k + k * (k-1)

for n = 3
diff = [k + k * (k-1)] * (k-1)
(k-1) choices for 3rd post
to not have color of 2nd
post.
same = k * (k-1)
c'' != c, (k-1) choices for it

Hence we deduce that,


total[i] = same[i] + diff[i]
same[i] = diff[i-1]
diff[i] = (diff[i-1] + diff[i-2]) * (k-1)
= total[i-1] * (k-1)

Below is the C++ implementation of the problem:

// C++ program for Painting Fence Algorithm


#include<bits/stdc++.h>
using namespace std;
  
// Returns count of ways to color k posts
// using k colors
long countWays(int n, int k)
{
    // To store results for subproblems
    long dp[n + 1];
    memset(dp, 0, sizeof(dp));
  
    // There are k ways to color first post
    dp[1] = k;
  
    // There are 0 ways for single post to
    // violate (same color_ and k ways to

2348
Chapter 326. Painting Fence Algorithm

    // not violate (different color)


    int same = 0, diff = k;
  
    // Fill for 2 posts onwards
    for (int i = 2; i <= n; i++)
    {
        // Current same is same as previous diff
        same = diff;
  
        // We always have k-1 choices for next post
        diff = dp[i-1] * (k-1);
  
        // Total choices till i.
        dp[i] = (same + diff);
    }
  
    return dp[n];
}
  
// Driver code
int main()
{
    int n = 3, k = 2;
    cout << countWays(n, k) << endl;
    return 0;
}

Output:

Space optimization :
We can optimize above solution to use one variable instead of a table.
Below is the C++ implementation of the problem:

// C++ program for Painting Fence Algorithm


#include<bits/stdc++.h>
using namespace std;
  
// Returns count of ways to color k posts
// using k colors
long countWays(int n, int k)
{
    // There are k ways to color first post
    long total = k;
  

2349
Chapter 326. Painting Fence Algorithm

    // There are 0 ways for single post to


    // violate (same color_ and k ways to
    // not violate (different color)
    int same = 0, diff = k;
  
    // Fill for 2 posts onwards
    for (int i = 2; i <= n; i++)
    {
        // Current same is same as previous diff
        same = diff;
  
        // We always have k-1 choices for next post
        diff = total * (k-1);
  
        // Total choices till i.
        total = (same + diff);
    }
  
    return total;
}
  
// Driver code
int main()
{
    int n = 3, k = 2;
    cout << countWays(n, k) << endl;
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/painting-fence-algorithm/

2350
Chapter 327

Paper Cut into Minimum


Number of Squares | Set 2

Paper Cut into Minimum Number of Squares | Set 2 - GeeksforGeeks


Given a paper of size A x B. Task is to cut the paper into squares of any size. Find the
minimum number of squares that can be cut from the paper.
Examples:

Input : 36 x 30
Output : 5
Explanation :
3 (squares of size 12x12) +
2 (squares of size 18x18)

Input : 4 x 5
Output : 5
Explanation :
1 (squares of size 4x4) +
4 (squares of size 1x1)

Asked in : Google

We have already discussed the Greedy approach to solve this problem in previous article.
But the previous approach doesn’t always work. For example, it fails for the above first test
case. So, in this article we solve this problem using Dynamic Programming.
We know that if we want to cut minimum number of squares from the paper then we would
have to cut largest square possible from the paper first and largest square will have same
side as smaller side of the paper. For example if paper have the size 13 x 29, then maximum
square will be of side 13. so we can cut 2 square of size 13 x 13 (29/13 = 2). Now remaining

2351
Chapter 327. Paper Cut into Minimum Number of Squares | Set 2

paper will have size 3 x 13. Similarly we can cut remaining paper by using 4 squares of size
3 x 3 and 3 squares of 1 x 1. So minimum 9 squares can be cut from the Paper of size 13 x
29.

2352
Chapter 327. Paper Cut into Minimum Number of Squares | Set 2

Explanation:
minimumSquare is a function which tries to split the rectangle at some position. The
function is called recursively for both parts. Try all possible splits and take the one with
minimum result. The base case is when both sides are equal i.e the input is already a square,
in which case the result is 1. We are trying to find the cut which is nearest to the center
which will lead us to our minimum result.
Assuming we have a rectangle with width is N and height is M.

• if (N == M), so it is a square and nothing need to be done.


• Otherwise, we can divide the rectangle into two other smaller one (N – x, M) and (x,
M), so it can be solved recursively.
• Similarly, we can also divide it into (N, M – x) and (N, x)

Below is the implementation of above idea using Dynamic Programming.

C++

// C++ program to find minimum number of squares


// to cut a paper using Dynamic Programming
#include<bits/stdc++.h>
using namespace std;
  
const int MAX = 300;
int dp[MAX][MAX];
  
// Returns min number of squares needed
int minimumSquare(int m, int n)
{
    // Initializing max values to vertical_min 
    // and horizontal_min
    int vertical_min = INT_MAX;
    int horizontal_min = INT_MAX;
      
    // If the given rectangle is already a square
    if (m == n)
        return 1;
      
    // If the answer for the given rectangle is 
    // previously calculated return that answer
    if (dp[m][n])
            return dp[m][n];
      
    /* The rectangle is cut horizontally and 
       vertically into two parts and the cut 
       with minimum value is found for every 
       recursive call. 

2353
Chapter 327. Paper Cut into Minimum Number of Squares | Set 2

    */
      
    for (int i = 1;i<= m/2;i++)
    {
        // Calculating the minimum answer for the 
        // rectangles with width equal to n and length 
        // less than m for finding the cut point for 
        // the minimum answer
        horizontal_min = min(minimumSquare(i, n) + 
                minimumSquare(m-i, n), horizontal_min); 
    }
      
    for (int j = 1;j<= n/2;j++)
    {
        // Calculating the minimum answer for the 
        // rectangles with width less than n and 
        // length equal to m for finding the cut 
        // point for the minimum answer
        vertical_min = min(minimumSquare(m, j) + 
                minimumSquare(m, n-j), vertical_min);
    }
          
    // Minimum of the vertical cut or horizontal 
    // cut to form a square is the answer
    dp[m][n] = min(vertical_min, horizontal_min); 
          
    return dp[m][n];
}
  
// Driver code
int main()
{
    int m = 30, n = 35;
    cout << minimumSquare(m, n);
    return 0;
}
  
// This code is contributed by Utkarsh Gupta

Java

// Java program to find minimum number of


// squares to cut a paper using Dynamic
// Programming
import java.io.*;
  
class GFG {
  

2354
Chapter 327. Paper Cut into Minimum Number of Squares | Set 2

    static int dp[][] = new int[300][300];


  
    // Returns min number of squares needed
    static int minimumSquare(int m, int n)
    {
        // Initializing max values to
        // vertical_min and horizontal_min
        int vertical_min = Integer.MAX_VALUE;
        int horizontal_min = Integer.MAX_VALUE;
      
        // If the given rectangle is 
        // already a square
        if (m == n)
            return 1;
      
        // If the answer for the given 
        // rectangle is previously 
        // calculated return that answer
        if (dp[m][n] != 0)
                return dp[m][n];
          
        /* The rectangle is cut horizontally
        and vertically into two parts and 
        the cut with minimum value is found
        for every recursive call. 
        */
      
        for (int i = 1; i <= m / 2; i++)
        {
            // Calculating the minimum answer 
            // for the rectangles with width 
            // equal to n and length less than
            // m for finding the cut point for 
            // the minimum answer
            horizontal_min = Math.min(
                            minimumSquare(i, n) + 
                            minimumSquare(m-i, n),
                            horizontal_min); 
        }
      
        for (int j = 1; j <= n / 2; j++)
        {
            // Calculating the minimum answer 
            // for the rectangles with width 
            // less than n and length equal to
            // m for finding the cut point for
            // the minimum answer
            vertical_min = Math.min(

2355
Chapter 327. Paper Cut into Minimum Number of Squares | Set 2

                           minimumSquare(m, j) + 
                           minimumSquare(m, n-j),
                           vertical_min);
        }
          
        // Minimum of the vertical cut or 
        // horizontal cut to form a square
        // is the answer
        dp[m][n] = Math.min(vertical_min,
                         horizontal_min); 
          
        return dp[m][n];
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int m = 30, n = 35;
        System.out.println(minimumSquare(m, n));
    }
}
// This code is contributed by Prerna Saini

C#

// C# program to find minimum number of


// squares to cut a paper using Dynamic
// Programming
using System;
  
class GFG {
  
    static int [,]dp = new int[300,300];
  
    // Returns min number of squares needed
    static int minimumSquare(int m, int n)
    {
        // Initializing max values to
        // vertical_min and horizontal_min
        int vertical_min = int.MaxValue;
        int horizontal_min = int.MaxValue;
      
        // If the given rectangle is 
        // already a square
        if (m == n)
            return 1;
      
        // If the answer for the given 

2356
Chapter 327. Paper Cut into Minimum Number of Squares | Set 2

        // rectangle is previously 


        // calculated return that answer
        if (dp[m,n] != 0)
                return dp[m,n];
          
        /* The rectangle is cut horizontally
        and vertically into two parts and 
        the cut with minimum value is found
        for every recursive call. 
        */
      
        for (int i = 1; i <= m / 2; i++)
        {
            // Calculating the minimum answer 
            // for the rectangles with width 
            // equal to n and length less than
            // m for finding the cut point for 
            // the minimum answer
            horizontal_min = Math.Min(
                            minimumSquare(i, n) + 
                            minimumSquare(m-i, n),
                            horizontal_min); 
        }
      
        for (int j = 1; j <= n / 2; j++)
        {
            // Calculating the minimum answer 
            // for the rectangles with width 
            // less than n and length equal to
            // m for finding the cut point for
            // the minimum answer
            vertical_min = Math.Min(
                        minimumSquare(m, j) + 
                        minimumSquare(m, n-j),
                        vertical_min);
        }
          
        // Minimum of the vertical cut or 
        // horizontal cut to form a square
        // is the answer
        dp[m,n] = Math.Min(vertical_min,
                        horizontal_min); 
          
        return dp[m,n];
    }
  
    // Driver code
    public static void Main()

2357
Chapter 327. Paper Cut into Minimum Number of Squares | Set 2

    {
        int m = 30, n = 35;
        Console.WriteLine(minimumSquare(m, n));
    }
}
  
// This code is contributed by anuj_67.

Output:

Improved By : vt_m

Source

https://www.geeksforgeeks.org/paper-cut-minimum-number-squares-set-2/

2358
Chapter 328

Partition a set into two subsets


such that the difference of
subset sums is minimum

Partition a set into two subsets such that the difference of subset sums is minimum - Geeks-
forGeeks
Given a set of integers, the task is to divide it into two sets S1 and S2 such that the absolute
difference between their sums is minimum.
If there is a set S with n elements, then if we assume Subset1 has m elements, Subset2 must
have n-m elements and the value of abs(sum(Subset1) – sum(Subset2)) should be minimum.
Example:

Input: arr[] = {1, 6, 11, 5}


Output: 1
Explanation:
Subset1 = {1, 5, 6}, sum of Subset1 = 12
Subset2 = {11}, sum of Subset2 = 11

This problem is mainly an extension to the Dynamic Programming| Set 18 (Partition Prob-
lem).
Recursive Solution
The recursive approach is to generate all possible sums from all the values of array and to
check which solution is the most optimal one.
To generate sums we either include the i’th item in set 1 or don’t include, i.e., include in set 2.

2359
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

// A Recursive C program to solve minimum sum partition


// problem.
#include <bits/stdc++.h>
using namespace std;
  
// Function to find the minimum sum
int findMinRec(int arr[], int i, int sumCalculated, int sumTotal)
{
    // If we have reached last element.  Sum of one
    // subset is sumCalculated, sum of other subset is
    // sumTotal-sumCalculated.  Return absolute difference
    // of two sums.
    if (i==0)
        return abs((sumTotal-sumCalculated) - sumCalculated);
  
  
    // For every item arr[i], we have two choices
    // (1) We do not include it first set
    // (2) We include it in first set
    // We return minimum of two choices
    return min(findMinRec(arr, i-1, sumCalculated+arr[i-1], sumTotal),
               findMinRec(arr, i-1, sumCalculated, sumTotal));
}
  
// Returns minimum possible difference between sums
// of two subsets
int findMin(int arr[], int n)
{
    // Compute total sum of elements
    int sumTotal = 0;
    for (int i=0; i<n; i++)
        sumTotal += arr[i];
  
    // Compute result using recursive function
    return findMinRec(arr, n, 0, sumTotal);
}
  
// Driver program to test above function
int main()
{
    int arr[] = {3, 1, 4, 2, 2, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "The minimum difference between two sets is "
         << findMin(arr, n);
    return 0;
}

Java

2360
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

// JAVA code to partition a set into two subsets


// such that the difference of subset sums
// is minimum
import java.util.*;
  
class GFG {
      
    // Function to find the minimum sum
    public static int findMinRec(int arr[], int i,
                                int sumCalculated,
                                 int sumTotal)
    {
        // If we have reached last element.
        // Sum of one subset is sumCalculated,
        // sum of other subset is sumTotal-
        // sumCalculated.  Return absolute 
        // difference of two sums.
        if (i == 0)
            return Math.abs((sumTotal-sumCalculated) -
                                   sumCalculated);
       
       
        // For every item arr[i], we have two choices
        // (1) We do not include it first set
        // (2) We include it in first set
        // We return minimum of two choices
        return Math.min(findMinRec(arr, i - 1, sumCalculated 
                                   + arr[i-1], sumTotal),
                                 findMinRec(arr, i-1,
                                  sumCalculated, sumTotal));
    }
       
    // Returns minimum possible difference between
    // sums of two subsets
    public static int findMin(int arr[], int n)
    {
        // Compute total sum of elements
        int sumTotal = 0;
        for (int i = 0; i < n; i++)
            sumTotal += arr[i];
       
        // Compute result using recursive function
        return findMinRec(arr, n, 0, sumTotal);
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {

2361
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

        int arr[] = {3, 1, 4, 2, 2, 1};


        int n = arr.length;
        System.out.print("The minimum difference"+
                        " between two sets is " + 
                         findMin(arr, n));
    }
}
    
// This code is contributed by Arnav Kr. Mandal.

C#

// C# code to partition a set into two subsets


// such that the difference of subset sums
// is minimum
using System; 
  
class GFG {
      
    // Function to find the minimum sum
    public static int findMinRec(int []arr, int i,
                                int sumCalculated,
                                     int sumTotal)
    {
        // If we have reached last element.
        // Sum of one subset is sumCalculated,
        // sum of other subset is sumTotal-
        // sumCalculated. Return absolute 
        // difference of two sums.
        if (i == 0)
            return Math.Abs((sumTotal-sumCalculated)
                                    - sumCalculated);
      
      
        // For every item arr[i], we have two choices
        // (1) We do not include it first set
        // (2) We include it in first set
        // We return minimum of two choices
        return Math.Min(findMinRec(arr, i - 1, 
                  sumCalculated + arr[i-1], sumTotal),
                   findMinRec(arr, i-1, sumCalculated, 
                                           sumTotal));
    }
      
    // Returns minimum possible difference between
    // sums of two subsets
    public static int findMin(int []arr, int n)
    {

2362
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

          
        // Compute total sum of elements
        int sumTotal = 0;
        for (int i = 0; i < n; i++)
            sumTotal += arr[i];
      
        // Compute result using recursive function
        return findMinRec(arr, n, 0, sumTotal);
    }
      
    /* Driver program to test above function */
    public static void Main() 
    {
        int []arr = {3, 1, 4, 2, 2, 1};
        int n = arr.Length;
        Console.Write("The minimum difference"+
                        " between two sets is " + 
                               findMin(arr, n));
    }
}
      
// This code is contributed by nitin mittal.

Output:

The minimum difference between two sets is 1

Time Complexity:

All the sums can be generated by either


(1) including that element in set 1.
(2) without including that element in set 1.
So possible combinations are :-
arr[0] (1 or 2) -> 2 values
arr[1] (1 or 2) -> 2 values
.
.
.
arr[n] (2 or 2) -> 2 values
So time complexity will be 2*2*..... *2 (For n times),
that is O(2^n).

Dynamic Programming
The problem can be solved using dynamic programming when the sum of the elements is not
too big. We can create a 2D array dp[n+1][sum+1] where n is number of elements in given
set and sum is sum of all elements. We can construct the solution in bottom up manner.

2363
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

The task is to divide the set into two parts.


We will consider the following factors for dividing it.
Let
dp[n+1][sum+1] = {1 if some subset from 1st to i'th has a sum
equal to j
0 otherwise}

i ranges from {1..n}


j ranges from {0..(sum of all elements)}

So
dp[n+1][sum+1] will be 1 if
1) The sum j is achieved including i'th item
2) The sum j is achieved excluding i'th item.

Let sum of all the elements be S.

To find Minimum sum difference, w have to find j such


that Min{sum - j*2 : dp[n][j] == 1 }
where j varies from 0 to sum/2

The idea is, sum of S1 is j and it should be closest


to sum/2, i.e., 2*j should be closest to sum.

Below is the implementation of above code.

C++

// A Recursive C program to solve minimum sum partition


// problem.
#include <bits/stdc++.h>
using namespace std;
  
// Returns the minimum value of the difference of the two sets.
int findMin(int arr[], int n)
{
    // Calculate sum of all elements
    int sum = 0; 
    for (int i = 0; i < n; i++)
        sum += arr[i];
  
    // Create an array to store results of subproblems
    bool dp[n+1][sum+1];
  
    // Initialize first column as true. 0 sum is possible 
    // with all elements.

2364
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

    for (int i = 0; i <= n; i++)


        dp[i][0] = true;
  
    // Initialize top row, except dp[0][0], as false. With
    // 0 elements, no other sum except 0 is possible
    for (int i = 1; i <= sum; i++)
        dp[0][i] = false;
  
    // Fill the partition table in bottom up manner
    for (int i=1; i<=n; i++)
    {
        for (int j=1; j<=sum; j++)
        {
            // If i'th element is excluded
            dp[i][j] = dp[i-1][j];
  
            // If i'th element is included
            if (arr[i-1] <= j)
                dp[i][j] |= dp[i-1][j-arr[i-1]];
        }
    }
   
    // Initialize difference of two sums. 
    int diff = INT_MAX;
      
    // Find the largest j such that dp[n][j]
    // is true where j loops from sum/2 t0 0
    for (int j=sum/2; j>=0; j--)
    {
        // Find the 
        if (dp[n][j] == true)
        {
            diff = sum-2*j;
            break;
        }
    }
    return diff;
}
  
// Driver program to test above function
int main()
{
    int arr[] = {3, 1, 4, 2, 2, 1};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "The minimum difference between 2 sets is "
         << findMin(arr, n);
    return 0;
}

2365
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

Java

// A Recursive java program to solve 


// minimum sum partition problem.
import java.io.*;
  
class GFG 
{
    // Returns the minimum value of 
    //the difference of the two sets.
    static int findMin(int arr[], int n)
    {
        // Calculate sum of all elements
        int sum = 0; 
        for (int i = 0; i < n; i++)
            sum += arr[i];
      
        // Create an array to store 
        // results of subproblems
        boolean dp[][] = new boolean[n + 1][sum + 1];
      
        // Initialize first column as true. 
        // 0 sum is possible  with all elements.
        for (int i = 0; i <= n; i++)
            dp[i][0] = true;
      
        // Initialize top row, except dp[0][0], 
        // as false. With 0 elements, no other 
        // sum except 0 is possible
        for (int i = 1; i <= sum; i++)
            dp[0][i] = false;
      
        // Fill the partition table 
        // in bottom up manner
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= sum; j++)
            {
                // If i'th element is excluded
                dp[i][j] = dp[i - 1][j];
      
                // If i'th element is included
                if (arr[i - 1] <= j)
                    dp[i][j] |= dp[i - 1][j - arr[i - 1]];
            }
        }
      
        // Initialize difference of two sums. 

2366
Chapter 328. Partition a set into two subsets such that the difference of subset sums is
minimum

        int diff = Integer.MAX_VALUE;


          
        // Find the largest j such that dp[n][j]
        // is true where j loops from sum/2 t0 0
        for (int j = sum / 2; j >= 0; j--)
        {
            // Find the 
            if (dp[n][j] == true)
            {
                diff = sum - 2 * j;
                break;
            }
        }
        return diff;
    }
      
    // Driver program 
    public static void main (String[] args) 
    {
        int arr[] = {3, 1, 4, 2, 2, 1};
        int n = arr.length;
        System.out.println ("The minimum difference between 2 sets is "
                            + findMin(arr, n));
      
    }
}
// This code is contributed by vt_m

Output:

The minimum difference between 2 sets is 1

Time Complexity = O(n*sum) where n is number of elements and sum is sum of all elements.
Note that the above solution is in Pseudo Polynomial Time (time complexity is dependent
on numeric value of input).
This article is contributed by Abhiraj Smit. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Improved By : nitin mittal

Source
https://www.geeksforgeeks.org/partition-a-set-into-two-subsets-such-that-the-difference-of-subset-sums-is-minimum

2367
Chapter 329

Partitioning into two contiguous


element subarrays with equal
sums

Partitioning into two contiguous element subarrays with equal sums - GeeksforGeeks
Given an array of n positive integers. Find a minimum positive element to be added to one
of the indexes in the array such that it can be partitioned into two contiguous sub arrays of
equal sums. Output the minimum element to be added and the position where it is to be
added. If multiple positions are possible then return the least one.
Examples:

Input : arr[] = { 10, 1, 2, 3, 4 }


Output : 0 0
Explanation: The array can already be partitioned into two contiguous sub-
arrays i.e. {10} and {1, 2, 3, 4} with equal sums. So we need to add 0 at any
position. (least position is 0)

Input : arr[] = { 5, 4 }
Output : 1 1
Explanation: We need to add 1 to 4 so that two sub arrays are {5},{5} hence
output is 1 1 (minimum element and it’s positon where it is to be added.

Prerequisites: Prefix Sums


Method 1 (Simple): A naive approach is to calculate the sum of elements from (arr[0]
to arr[i]) and (arr[i+1] to arr[n-1]), and at each step find the difference between these two
sums, minimum difference will give the element to be added.
Method 2 (Efficient): Careful analysis suggests that we can use the concept of prefix
sums and suffix sums. Calculate both of them and find the absolute difference between pre-
fixSum[i] (where prefixSum[i] is the sum of array elements upto ith position) and suffixSum[i

2368
Chapter 329. Partitioning into two contiguous element subarrays with equal sums

+ 1] (where suffixSum[i + 1] is the sum of array elements from (i + 1)th position to last
position).
For e.g.

arr 10 1 2 3 4
prefixSum 10 11 13 16 20
suffixSum 20 10 9 7 4

Absolute difference between suffixSum[i + 1] and prefixSum[i]


10 - 10 = 0 // minimum
11 - 9 = 1
13 - 7 = 6
16 - 4 = 12
Thus, minimum element is 0, for position,
if prefixSum[i] is greater than suffixSum[i + 1], then position is "i + 1".
else it's is "i".

Below is the implementation of above approach.

// CPP Program to find the minimum element to 


// be added such that the array can be partitioned 
// into two contiguous subarrays with equal sums
#include <bits/stdc++.h>
  
using namespace std;
  
// Structure to store the minimum element
// and its position 
struct data {
    int element;
    int position;
};
  
struct data findMinElement(int arr[], int n)
{
    struct data result; 
      
    // initialize prefix and suffix sum arrays with 0
    int prefixSum[n] = { 0 }; 
    int suffixSum[n] = { 0 };
  
    prefixSum[0] = arr[0];
    for (int i = 1; i < n; i++) {
        // add current element to Sum
        prefixSum[i] = prefixSum[i - 1] + arr[i];
    }

2369
Chapter 329. Partitioning into two contiguous element subarrays with equal sums

  
    suffixSum[n - 1] = arr[n - 1];
    for (int i = n - 2; i >= 0; i--) {
        // add current element to Sum
        suffixSum[i] = suffixSum[i + 1] + arr[i];
    }
      
    // initialize the minimum element to be a large value
    int min = suffixSum[0]; 
    int pos;
  
    for (int i = 0; i < n - 1; i++) {
        // check for the minimum absolute difference 
        // between current prefix sum and the next 
        // suffix sum element
        if (abs(suffixSum[i + 1] - prefixSum[i]) < min) {
            min = abs(suffixSum[i + 1] - prefixSum[i]);
  
            // if prefixsum has a greater value then position 
            // is the next element, else it's the same element.
            if (suffixSum[i + 1] < prefixSum[i]) pos = i + 1;
            else     pos = i;
        }
    }
  
    // return the data in struct.
    result.element = min;
    result.position = pos;
    return result;
}
  
// Driver Code 
int main()
{
    int arr[] = { 10, 1, 2, 3, 4 };
    int n = sizeof(arr) / sizeof(arr[0]);
    struct data values;
  
    values = findMinElement(arr, n);
    cout << "Minimum element : " << values.element 
        << endl << "Position : " << values.position;
    return 0;
}

Output:

Minimum element : 0

2370
Chapter 329. Partitioning into two contiguous element subarrays with equal sums

Position : 0

Improved By : shubham bhuyan

Source

https://www.geeksforgeeks.org/partitioning-into-two-contiguous-element-subarray-with-equal-sums/

2371
Chapter 330

Path with maximum average


value

Path with maximum average value - GeeksforGeeks


Given a square matrix of size N*N, where each cell is associated with a specific cost. A path
is defined as a specific sequence of cells which starts from top left cell move only right or
down and ends on bottom right cell. We want to find a path with maximum average over
all existing paths. Average is computed as total cost divided by number of cells visited in
path.
Examples:

Input : Matrix = [1, 2, 3


4, 5, 6
7, 8, 9]
Output : 5.8
Path with maximum average is, 1 -> 4 -> 7 -> 8 -> 9
Sum of the path is 29 and average is 29/5 = 5.8

One interesting observation is, the only allowed moves are down and right, we need N-1
down moves and N-1 right moves to reach destination (bottom rightmost). So any path
from from top left corner to bottom right corner requires 2N – 1 cells. In average value,
denominator is fixed and we need to just maximize numerator. Therefore we basically need
to to find maximum sum path. Calculating maximum sum of path is a classic dynamic
programming problem, if dp[i][j] represents maximum sum till cell (i, j) from (0, 0) then at
each cell (i, j), we update dp[i][j] as below,

for all i, 1 <= i <= N


dp[i][0] = dp[i-1][0] + cost[i][0];
for all j, 1 <= j <= j

2372
Chapter 330. Path with maximum average value

dp[0][j] = dp[0][j-1] + cost[0][j];


otherwise
dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + cost[i][j];

Once we get maximum sum of all paths we will divide this sum by (2N – 1) and we will get
our maximum average.

C++

//    C/C++ program to find maximum average cost path


#include <bits/stdc++.h>
using namespace std;
  
// Maximum number of rows and/or columns
const int M = 100;
  
// method returns maximum average of all path of
// cost matrix
double maxAverageOfPath(int cost[M][M], int N)
{
    int dp[N+1][N+1];
    dp[0][0] = cost[0][0];
  
    /* Initialize first column of total cost(dp) array */
    for (int i = 1; i < N; i++)
        dp[i][0] = dp[i-1][0] + cost[i][0];
  
    /* Initialize first row of dp array */
    for (int j = 1; j < N; j++)
        dp[0][j] = dp[0][j-1] + cost[0][j];
  
    /* Construct rest of the dp array */
    for (int i = 1; i < N; i++)
        for (int j = 1; j <= N; j++)
            dp[i][j] = max(dp[i-1][j],
                          dp[i][j-1]) + cost[i][j];
  
    // divide maximum sum by constant path
    // length : (2N - 1) for getting average
    return (double)dp[N-1][N-1] / (2*N-1);
}
  
/* Driver program to test above functions */
int main()
{
    int cost[M][M] = { {1, 2, 3},
        {6, 5, 4},

2373
Chapter 330. Path with maximum average value

        {7, 3, 9}
    };
    printf("%f", maxAverageOfPath(cost, 3));
    return 0;
}

Java

// JAVA Code for Path with maximum average


// value
class GFG {
      
    // method returns maximum average of all
    // path of cost matrix
    public static double maxAverageOfPath(int cost[][],
                                               int N)
    {
        int dp[][] = new int[N+1][N+1];
        dp[0][0] = cost[0][0];
       
        /* Initialize first column of total cost(dp)
           array */
        for (int i = 1; i < N; i++)
            dp[i][0] = dp[i-1][0] + cost[i][0];
       
        /* Initialize first row of dp array */
        for (int j = 1; j < N; j++)
            dp[0][j] = dp[0][j-1] + cost[0][j];
       
        /* Construct rest of the dp array */
        for (int i = 1; i < N; i++)
            for (int j = 1; j < N; j++)
                dp[i][j] = Math.max(dp[i-1][j],
                           dp[i][j-1]) + cost[i][j];
       
        // divide maximum sum by constant path
        // length : (2N - 1) for getting average
        return (double)dp[N-1][N-1] / (2 * N - 1);
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int cost[][] = {{1, 2, 3},
                        {6, 5, 4},
                        {7, 3, 9}};
                  
        System.out.println(maxAverageOfPath(cost, 3));

2374
Chapter 330. Path with maximum average value

    }
}
// This code is contributed by Arnav Kr. Mandal.

Python3

# Python program to find 


# maximum average cost path
  
# Maximum number of rows 
# and/or columns
M = 100
  
# method returns maximum average of 
# all path of cost matrix
def maxAverageOfPath(cost, N):
      
    dp = [[0 for i in range(N + 1)] for j in range(N + 1)]
    dp[0][0] = cost[0][0]
  
    # Initialize first column of total cost(dp) array
    for i in range(1, N):
        dp[i][0] = dp[i - 1][0] + cost[i][0]
  
    # Initialize first row of dp array
    for j in range(1, N):
        dp[0][j] = dp[0][j - 1] + cost[0][j]
  
    # Construct rest of the dp array
    for i in range(1, N):
        for j in range(1, N):
            dp[i][j] = max(dp[i - 1][j],
                        dp[i][j - 1]) + cost[i][j]
  
    # divide maximum sum by costant path
    # length : (2N - 1) for getting average
    return dp[N - 1][N - 1] / (2 * N - 1)
  
# Driver program to test above function
cost = [[1, 2, 3],
        [6, 5, 4],
        [7, 3, 9]]
  
print(maxAverageOfPath(cost, 3))
  
# This code is contributed by Soumen Ghosh.

C#

2375
Chapter 330. Path with maximum average value

// C# Code for Path with maximum average


// value
using System;
class GFG {
      
    // method returns maximum average of all
    // path of cost matrix
    public static double maxAverageOfPath(int [,]cost,
                                               int N)
    {
        int [,]dp = new int[N+1,N+1];
        dp[0,0] = cost[0,0];
      
        /* Initialize first column of total cost(dp)
           array */
        for (int i = 1; i < N; i++)
            dp[i, 0] = dp[i - 1,0] + cost[i, 0];
      
        /* Initialize first row of dp array */
        for (int j = 1; j < N; j++)
            dp[0, j] = dp[0,j - 1] + cost[0, j];
      
        /* Construct rest of the dp array */
        for (int i = 1; i < N; i++)
            for (int j = 1; j < N; j++)
                dp[i, j] = Math.Max(dp[i - 1, j],
                        dp[i,j - 1]) + cost[i, j];
      
        // divide maximum sum by constant path
        // length : (2N - 1) for getting average
        return (double)dp[N - 1, N - 1] / (2 * N - 1);
    }
      
    // Driver Code
    public static void Main() 
    {
        int [,]cost = {{1, 2, 3},
                       {6, 5, 4},
                       {7, 3, 9}};
                  
        Console.Write(maxAverageOfPath(cost, 3));
    }
}
  
// This code is contributed by nitin mittal.

Output:

2376
Chapter 330. Path with maximum average value

5.2

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/path-maximum-average-value/

2377
Chapter 331

Perfect Sum Problem (Print all


subsets with given sum)

Perfect Sum Problem (Print all subsets with given sum) - GeeksforGeeks
Given an array of integers and a sum, the task is to print all subsets of given array with
sum equal to given sum.
Examples:

Input : arr[] = {2, 3, 5, 6, 8, 10}


sum = 10
Output : 5 2 3
2 8
10

Input : arr[] = {1, 2, 3, 4, 5}


sum = 10
Output : 4 3 2 1
5 3 2
5 4 1

Asked in Tesco
This problem is mainly an extension of Subset Sum Problem. Here we not only need to find
if there is a subset with given sum, but also need to print all subsets with given sum.
Like previous post, we build a 2D array dp[][] such that dp[i][j] stores true if sum j is possible
with array elements from 0 to i.
After filling dp[][], we recursively traverse it from dp[n-1][sum]. For cell being traversed, we
store path before reaching it and consider two possibilities for the element.
1) Element is included in current path.
2) Element is not included in current path.

2378
Chapter 331. Perfect Sum Problem (Print all subsets with given sum)

Whenever sum becomes 0, we stop the recursive calls and print current path.
Below is implementation of above idea.
C++

// C++ program to count all subsets with


// given sum.
#include <bits/stdc++.h>
using namespace std;
  
// dp[i][j] is going to store true if sum j is
// possible with array elements from 0 to i.
bool** dp;
  
void display(const vector<int>& v)
{
    for (int i = 0; i < v.size(); ++i)
        printf("%d ", v[i]);
    printf("\n");
}
  
// A recursive function to print all subsets with the
// help of dp[][]. Vector p[] stores current subset.
void printSubsetsRec(int arr[], int i, int sum, vector<int>& p)
{
    // If we reached end and sum is non-zero. We print
    // p[] only if arr[0] is equal to sun OR dp[0][sum]
    // is true.
    if (i == 0 && sum != 0 && dp[0][sum])
    {
        p.push_back(arr[i]);
        display(p);
        return;
    }
  
    // If sum becomes 0
    if (i == 0 && sum == 0)
    {
        display(p);
        return;
    }
  
    // If given sum can be achieved after ignoring
    // current element.
    if (dp[i-1][sum])
    {
        // Create a new vector to store path
        vector<int> b = p;

2379
Chapter 331. Perfect Sum Problem (Print all subsets with given sum)

        printSubsetsRec(arr, i-1, sum, b);


    }
  
    // If given sum can be achieved after considering
    // current element.
    if (sum >= arr[i] && dp[i-1][sum-arr[i]])
    {
        p.push_back(arr[i]);
        printSubsetsRec(arr, i-1, sum-arr[i], p);
    }
}
  
// Prints all subsets of arr[0..n-1] with sum 0.
void printAllSubsets(int arr[], int n, int sum)
{
    if (n == 0 || sum < 0)
       return;
  
    // Sum 0 can always be achieved with 0 elements
    dp = new bool*[n];
    for (int i=0; i<n; ++i)
    {
        dp[i] = new bool[sum + 1];
        dp[i][0] = true;
    }
  
    // Sum arr[0] can be achieved with single element
    if (arr[0] <= sum)
       dp[0][arr[0]] = true;
  
    // Fill rest of the entries in dp[][]
    for (int i = 1; i < n; ++i)
        for (int j = 0; j < sum + 1; ++j)
            dp[i][j] = (arr[i] <= j) ? dp[i-1][j] ||
                                       dp[i-1][j-arr[i]]
                                     : dp[i - 1][j];
    if (dp[n-1][sum] == false)
    {
        printf("There are no subsets with sum %d\n", sum);
        return;
    }
  
    // Now recursively traverse dp[][] to find all
    // paths from dp[n-1][sum]
    vector<int> p;
    printSubsetsRec(arr, n-1, sum, p);
}
  

2380
Chapter 331. Perfect Sum Problem (Print all subsets with given sum)

// Driver code
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int n = sizeof(arr)/sizeof(arr[0]);
    int sum = 10;
    printAllSubsets(arr, n, sum);
    return 0;
}

Java

// A Java program to count all subsets with given sum.


import java.util.ArrayList;
public class SubSet_sum_problem
{
    // dp[i][j] is going to store true if sum j is
    // possible with array elements from 0 to i.
    static boolean[][] dp;
       
    static void display(ArrayList<Integer> v)
    {
       System.out.println(v);
    }
       
    // A recursive function to print all subsets with the
    // help of dp[][]. Vector p[] stores current subset.
    static void printSubsetsRec(int arr[], int i, int sum, 
                                         ArrayList<Integer> p)
    {
        // If we reached end and sum is non-zero. We print
        // p[] only if arr[0] is equal to sun OR dp[0][sum]
        // is true.
        if (i == 0 && sum != 0 && dp[0][sum])
        {
            p.add(arr[i]);
            display(p);
            p.clear();
            return;
        }
       
        // If sum becomes 0
        if (i == 0 && sum == 0)
        {
            display(p);
            p.clear();
            return;
        }

2381
Chapter 331. Perfect Sum Problem (Print all subsets with given sum)

       
        // If given sum can be achieved after ignoring
        // current element.
        if (dp[i-1][sum])
        {
            // Create a new vector to store path
            ArrayList<Integer> b = new ArrayList<>();
            b.addAll(p);
            printSubsetsRec(arr, i-1, sum, b);
        }
       
        // If given sum can be achieved after considering
        // current element.
        if (sum >= arr[i] && dp[i-1][sum-arr[i]])
        {
            p.add(arr[i]);
            printSubsetsRec(arr, i-1, sum-arr[i], p);
        }
    }
       
    // Prints all subsets of arr[0..n-1] with sum 0.
    static void printAllSubsets(int arr[], int n, int sum)
    {
        if (n == 0 || sum < 0)
           return;
       
        // Sum 0 can always be achieved with 0 elements
        dp = new boolean[n][sum + 1];
        for (int i=0; i<n; ++i)
        {
            dp[i][0] = true;  
        }
       
        // Sum arr[0] can be achieved with single element
        if (arr[0] <= sum)
           dp[0][arr[0]] = true;
       
        // Fill rest of the entries in dp[][]
        for (int i = 1; i < n; ++i)
            for (int j = 0; j < sum + 1; ++j)
                dp[i][j] = (arr[i] <= j) ? (dp[i-1][j] ||
                                           dp[i-1][j-arr[i]])
                                         : dp[i - 1][j];
        if (dp[n-1][sum] == false)
        {
            System.out.println("There are no subsets with" + 
                                                  " sum "+ sum);
            return;

2382
Chapter 331. Perfect Sum Problem (Print all subsets with given sum)

        }
       
        // Now recursively traverse dp[][] to find all
        // paths from dp[n-1][sum]
        ArrayList<Integer> p = new ArrayList<>();
        printSubsetsRec(arr, n-1, sum, p);
    }
      
    //Driver Program to test above functions
    public static void main(String args[])
    {
        int arr[] = {1, 2, 3, 4, 5};
        int n = arr.length;
        int sum = 10;
        printAllSubsets(arr, n, sum);
    }
}
//This code is contributed by Sumit Ghosh

Output :

4 3 2 1
5 3 2
5 4 1

Source

https://www.geeksforgeeks.org/perfect-sum-problem-print-subsets-given-sum/

2383
Chapter 332

Permutation Coefficient

Permutation Coefficient - GeeksforGeeks


Permutation refers to the process of arranging all the members of a given set to form a
sequence. The number of permutations on a set of n elements is given by n! , where “!”
represents factorial.
The Permutation Coefficient represented by P(n, k) is used to represent the number of
ways to obtain an ordered subset having k elements from a set of n elements.
Mathematically it’s given as:

Image Source : Wiki


Examples :

P(10, 2) = 90
P(10, 3) = 720
P(10, 0) = 1
P(10, 1) = 10

The coefficient can also be computed recursively using the below recursive formula:

2384
Chapter 332. Permutation Coefficient

P(n, k) = P(n-1, k) + k* P(n-1, k-1)

If we observe closely, we can analyze that the problem has overlapping substructure, hence
we can apply dynamic programming here. Below is a program implementing the same idea.

// A Dynamic Programming based 


// solution that uses table P[][]
// to calculate the Permutation
// Coefficient
#include<bits/stdc++.h>
  
// Returns value of Permutation
// Coefficient P(n, k)
int permutationCoeff(int n, int k)
{
    int P[n + 1][k + 1];
  
    // Caculate value of Permutation 
    // Coefficient in bottom up manner
    for (int i = 0; i <= n; i++)
    {
        for (int j = 0; j <= std::min(i, k); j++)
        {
            // Base Cases
            if (j == 0)
                P[i][j] = 1;
  
            // Calculate value using
            // previosly stored values
            else
                P[i][j] = P[i - 1][j] + 
                          (j * P[i - 1][j - 1]);
  
            // This step is important
            // as P(i,j)=0 for j>i
            P[i][j + 1] = 0;
        }
    }
    return P[n][k];
}
  
// Driver Code
int main()
{

2385
Chapter 332. Permutation Coefficient

    int n = 10, k = 2;
    printf("Value of P(%d, %d) is %d ",
            n, k, permutationCoeff(n, k));
    return 0;
}

Java

// Java code for Dynamic Programming based 


// solution that uses table P[][] to 
// calculate the Permutation Coefficient
import java.io.*;
import java.math.*;
  
class GFG 
{
      
    // Returns value of Permutation 
    // Coefficient P(n, k)
    static int permutationCoeff(int n, 
                                int k)
    {
        int P[][] = new int[n + 2][k + 2];
      
        // Caculate value of Permutation 
        // Coefficient in bottom up manner
        for (int i = 0; i <= n; i++)
        {
            for (int j = 0; 
                 j <= Math.min(i, k); 
                 j++)
            {
                // Base Cases
                if (j == 0)
                    P[i][j] = 1;
      
                // Calculate value using previosly 
                // stored values
                else
                    P[i][j] = P[i - 1][j] + 
                               (j * P[i - 1][j - 1]);
      
                // This step is important 
                // as P(i,j)=0 for j>i
                P[i][j + 1] = 0;
            }
        }
        return P[n][k];

2386
Chapter 332. Permutation Coefficient

    }
      
    // Driver Code
    public static void main(String args[])
    {
        int n = 10, k = 2;
        System.out.println("Value of P( " + n + ","+ k +")" + 
                           " is " + permutationCoeff(n, k) );
    }
}
  
// This code is contributed by Nikita Tiwari.

Python3

# A Dynamic Programming based


# solution that uses
# table P[][] to calculate the
# Permutation Coefficient
  
# Returns value of Permutation
# Coefficient P(n, k)
def permutationCoeff(n, k):
  
    P = [[0 for i in range(k + 1)] 
            for j in range(n + 1)]
  
    # Calculate value of Permutation
    # Coefficient in
    # bottom up manner
    for i in range(n + 1):
        for j in range(min(i, k) + 1):
  
            # Base cases
            if (j == 0):
                P[i][j] = 1
  
            # Calculate value using 
            # previously stored values
            else:
                P[i][j] = P[i - 1][j] + (
                           j * P[i - 1][j - 1])
  
            # This step is important 
            # as P(i, j) = 0 for j>i
            if (j < k):
                P[i][j + 1] = 0
    return P[n][k]

2387
Chapter 332. Permutation Coefficient

  
# Driver Code
n = 10
k = 2
print("Value fo P(", n, ", ", k, ") is ",
       permutationCoeff(n, k), sep = "")
  
# This code is contributed by Soumen Ghosh.

C#

// C# code for Dynamic Programming based 


// solution that uses table P[][] to 
// calculate the Permutation Coefficient
using System;
  
class GFG 
{
      
    // Returns value of Permutation 
    // Coefficient P(n, k)
    static int permutationCoeff(int n, 
                                int k)
    {
        int [,]P = new int[n + 2,k + 2];
      
        // Caculate value of Permutation 
        // Coefficient in bottom up manner
        for (int i = 0; i <= n; i++)
        {
            for (int j = 0; 
                j <= Math.Min(i, k); 
                j++)
            {
                // Base Cases
                if (j == 0)
                    P[i,j] = 1;
      
                // Calculate value using previosly 
                // stored values
                else
                    P[i,j] = P[i - 1,j] + 
                            (j * P[i - 1,j - 1]);
      
                // This step is important 
                // as P(i,j)=0 for j>i
                P[i,j + 1] = 0;
            }

2388
Chapter 332. Permutation Coefficient

        }
        return P[n,k];
    }
      
    // Driver Code
    public static void Main()
    {
        int n = 10, k = 2;
        Console.WriteLine("Value of P( " + n + 
                        ","+ k +")" + " is " + 
                        permutationCoeff(n, k) );
    }
}
  
// This code is contributed by anuj_67..

PHP

<?php
// A Dynamic Programming based 
// solution that uses table P[][]
// to calculate the Permutation
// Coefficient
  
// Returns value of Permutation
// Coefficient P(n, k)
function permutationCoeff( $n, $k)
{
    $P = array(array());
  
    // Caculate value of Permutation 
    // Coefficient in bottom up manner
    for($i = 0; $i <= $n; $i++)
    {
        for($j = 0; $j <= min($i, $k); $j++)
        {
              
            // Base Cases
            if ($j == 0)
                $P[$i][$j] = 1;
  
            // Calculate value using
            // previosly stored values
            else
                $P[$i][$j] = $P[$i - 1][$j] + 
                            ($j * $P[$i - 1][$j - 1]);
  
            // This step is important

2389
Chapter 332. Permutation Coefficient

            // as P(i,j)=0 for j>i


            $P[$i][$j + 1] = 0;
        }
    }
    return $P[$n][$k];
}
  
    // Driver Code
    $n = 10; $k = 2;
    echo "Value of P(",$n," ,",$k,") is ",
               permutationCoeff($n, $k);
  
// This code is contributed by anuj_67.
?>

Output :

Value of P(10, 2) is 90

Here as we can see the time complexity is O(n*k) and space complexity is O(n*k) as the
program uses an auxiliary matrix to store the result.
Can we do it in O(n) time ?
Let us suppose we maintain a single 1D array to compute the factorials up to n. We can
use computed factorial value and apply the formula P(n, k) = n! / (n-k)!. Below is a
program illustrating the same concept.

// A O(n) solution that uses 


// table fact[] to calculate 
// the Permutation Coefficient
#include<bits/stdc++.h>
  
// Returns value of Permutation
// Coefficient P(n, k)
int permutationCoeff(int n, int k)
{
    int fact[n + 1];
  
    // base case
    fact[0] = 1;
  
    // Caculate value 
    // factorials up to n

2390
Chapter 332. Permutation Coefficient

    for (int i = 1; i <= n; i++)


        fact[i] = i * fact[i - 1];
  
    // P(n,k) = n! / (n - k)!
    return fact[n] / fact[n - k];
}
  
// Driver Code
int main()
{
    int n = 10, k = 2;
    printf ("Value of P(%d, %d) is %d ",
             n, k, permutationCoeff(n, k) );
    return 0;
}

Java

// A O(n) solution that uses 


// table fact[] to calculate 
// the Permutation Coefficient
import java .io.*;
  
public class GFG {
      
    // Returns value of Permutation
    // Coefficient P(n, k)
    static int permutationCoeff(int n, 
                                int k)
    {
        int []fact = new int[n+1];
      
        // base case
        fact[0] = 1;
      
        // Caculate value 
        // factorials up to n
        for (int i = 1; i <= n; i++)
            fact[i] = i * fact[i - 1];
      
        // P(n,k) = n! / (n - k)!
        return fact[n] / fact[n - k];
    }
      
    // Driver Code
    static public void main (String[] args)
    {
        int n = 10, k = 2;

2391
Chapter 332. Permutation Coefficient

        System.out.println("Value of"
        + " P( " + n + ", " + k + ") is "
        + permutationCoeff(n, k) );
    }
}
  
// This code is contributed by anuj_67.

Python3

# A O(n) solution that uses 


# table fact[] to calculate 
# the Permutation Coefficient
  
# Returns value of Permutation
# Coefficient P(n, k)
def permutationCoeff(n, k):
    fact = [0 for i in range(n + 1)]
  
    # base case
    fact[0] = 1
  
    # Calculate value 
    # factorials up to n
    for i in range(1, n + 1):
        fact[i] = i * fact[i - 1]
  
    # P(n, k) = n!/(n-k)!
    return int(fact[n] / fact[n - k])
  
# Driver Code
n = 10
k = 2
print("Value of P(", n, ", ", k, ") is ",
        permutationCoeff(n, k), sep = "")
  
# This code is contributed
# by Soumen Ghosh

C#

// A O(n) solution that uses 


// table fact[] to calculate 
// the Permutation Coefficient
using System;
  
public class GFG {

2392
Chapter 332. Permutation Coefficient

      
    // Returns value of Permutation
    // Coefficient P(n, k)
    static int permutationCoeff(int n, 
                                int k)
    {
        int []fact = new int[n+1];
      
        // base case
        fact[0] = 1;
      
        // Caculate value 
        // factorials up to n
        for (int i = 1; i <= n; i++)
            fact[i] = i * fact[i - 1];
      
        // P(n,k) = n! / (n - k)!
        return fact[n] / fact[n - k];
    }
      
    // Driver Code
    static public void Main ()
    {
        int n = 10, k = 2;
        Console.WriteLine("Value of"
        + " P( " + n + ", " + k + ") is "
         + permutationCoeff(n, k) );
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// A O(n) Solution that 
// uses table fact[] to 
// calculate the Permutation 
// Coefficient
  
// Returns value of Permutation
// Coefficient P(n, k)
function permutationCoeff($n, $k)
{
    $fact = array();
  
    // base case
    $fact[0] = 1;

2393
Chapter 332. Permutation Coefficient

  
    // Calculate value 
    // factorials up to n
    for ($i = 1; $i <= $n; $i++)
        $fact[$i] = $i * $fact[$i - 1];
  
    // P(n,k)= n!/(n-k)!
    return $fact[$n] / $fact[$n - $k];
}
  
    // Driver Code
    $n = 10;
    $k = 2;
    echo"Value of P(",$n," ", $k,") is ",
            permutationCoeff($n, $k) ;
              
// This code is contributed by anuj_67.             
?>

Output :

Value of P(10, 2) is 90

A O(n) time and O(1) Extra Space Solution

// A O(n) time and O(1) extra


// space solution to calculate
// the Permutation Coefficient
#include <iostream>
using namespace std;
  
int PermutationCoeff(int n, int k)
{
    int Fn = 1, Fk;
  
    // Compute n! and (n-k)!
    for (int i = 1; i <= n; i++)
    {
        Fn *= i;
        if (i == n - k)
        Fk = Fn;
    }
    int coeff = Fn / Fk;
    return coeff;
}

2394
Chapter 332. Permutation Coefficient

  
// Driver Code
int main()
{
    int n = 10, k = 2;
    cout << "Value of P(" << n << ", " << k
         << ") is " << PermutationCoeff(n, k);
  
    return 0;
}

Java

// A O(n) time and O(1) extra 


// space solution to calculate
// the Permutation Coefficient
import java.io.*;
  
class GFG 
{
    static int PermutationCoeff(int n, 
                                int k)
    {
        int Fn = 1, Fk = 1;
      
        // Compute n! and (n-k)!
        for (int i = 1; i <= n; i++)
        {
            Fn *= i;
            if (i == n - k)
            Fk = Fn;
        }
        int coeff = Fn / Fk;
        return coeff;
    }
      
    // Driver Code 
    public static void main(String args[])
    {
        int n = 10, k = 2;
        System.out.println("Value of P( " + n + "," + 
                                         k +") is " + 
                            PermutationCoeff(n, k) );
    }
}
      
// This code is contributed by Nikita Tiwari.

2395
Chapter 332. Permutation Coefficient

Python3

# A O(n) time and O(1) extra 


# space solution to calculate
# the Permutation Coefficient
  
def PermutationCoeff(n, k):
    Fn = 1
  
    # Compute n! and (n-k)!
    for i in range(1, n + 1):
        Fn *= i
        if (i == n - k):
            Fk = Fn
  
    coeff = Fn // Fk
    return coeff
  
# Driver Code
n = 10
k = 2
print("Value of P(", n, ", ", k, ") is ",
       PermutationCoeff(n, k), sep = "")
  
# This code is contributed
# by Soumen Ghosh.

C#

// A O(n) time and O(1) extra 


// space solution to calculate
// the Permutation Coefficient
using System;
  
class GFG {
      
    static int PermutationCoeff(int n, 
                                int k)
    {
        int Fn = 1, Fk = 1;
      
        // Compute n! and (n-k)!
        for (int i = 1; i <= n; i++)
        {
            Fn *= i;
            if (i == n - k)
                Fk = Fn;

2396
Chapter 332. Permutation Coefficient

        }
        int coeff = Fn / Fk;
          
        return coeff;
    }
      
    // Driver Code 
    public static void Main()
    {
        int n = 10, k = 2;
        Console.WriteLine("Value of P( "
                   + n + "," + k +") is "
              + PermutationCoeff(n, k) );
    }
}
      
// This code is contributed by anuj_67.

PHP

<?php
// A O(n) time and O(1) extra 
// space PHP solution to calculate 
// the Permutation Coefficient
  
function PermutationCoeff( $n, $k)
{
    $Fn = 1; $Fk;
  
    // Compute n! and (n-k)!
    for ( $i = 1; $i <= $n; $i++)
    {
        $Fn *= $i;
        if ($i == $n - $k)
        $Fk = $Fn;
    }
    $coeff = $Fn / $Fk;
    return $coeff;
}
  
// Driver Code
$n = 10; $k = 2;
echo "Value of P(" , $n , ", " , $k , ")
        is " , PermutationCoeff($n, $k);
  
// This code is contributed by anuj_67. 
?>

2397
Chapter 332. Permutation Coefficient

Output :

Value of P(10, 2) is 90

Thanks to Shiva Kumar for suggesting this solution.


This article is contributed by Ashutosh Kumar. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Improved By : vt_m

Source

https://www.geeksforgeeks.org/permutation-coefficient/

2398
Chapter 333

Prefix Sum of Matrix (Or 2D


Array)

Prefix Sum of Matrix (Or 2D Array) - GeeksforGeeks


Given a matrix (or 2D array) a[][] of integers, find prefix sum matrix for it. Let prefix sum
matrix be psa[][]. The value of psa[i][j] contains sum of all values which are above it or on
left of it.

Prerequisite: Prefix Sum – 1D


A simple solution is to find psa[i][j] by traversing and adding values from a[0][0] to a[i][j].
Time complexity o this solution is O(R * C * R * C).
An efficient solution is to use previously computed values to compute psa[i][j]. Unlike 1D
array prefix sum, this is tricky, here if we simply add psa[i][j-1] and psa[i-1][j], we get sum
of elements from a[0][0] to a[i-1][j-1] twice, so we subtract psa[i-1][j-1].

2399
Chapter 333. Prefix Sum of Matrix (Or 2D Array)

Example :

psa[3][3] = psa[2][3] + psa[3][2] -


psa[2][2] + a[2][2]
= 6 + 6 - 4 + 1
= 9
The general formula:
psa[i][j] = psa[i-1][j] + psa[i][j-1] -
psa[i-1][j-1] + a[i][j]

Corner Cases (First row and first column)


If i = 0 and j = 0
psa[i][j] = a[i][j]
If i = 0 and j > 0
psa[i][j] = psa[i][j-1] + a[i][j]
If i > 0 and j = 0
psa[i][j] = psa[i-1][j] + a[i][j]

Below is the implementation of the above approach

C++

// C++ Program to find prefix sum of 2d array


#include <bits/stdc++.h>
using namespace std;
  
#define R 4
#define C 5
  
// calculating new array
void prefixSum2D(int a[][C])
{
    int psa[R][C];
    psa[0][0] = a[0][0];
  
    // Filling first row and first column
    for (int i = 1; i < C; i++)
        psa[0][i] = psa[0][i - 1] + a[0][i];
    for (int i = 0; i < R; i++)
        psa[i][0] = psa[i - 1][0] + a[i][0];
  
    // updating the values in the cells
    // as per the general formula
    for (int i = 1; i < R; i++) {
        for (int j = 1; j < C; j++)
  

2400
Chapter 333. Prefix Sum of Matrix (Or 2D Array)

            // values in the cells of new


            // array are updated
            psa[i][j] = psa[i - 1][j] + psa[i][j - 1]
                        - psa[i - 1][j - 1] + a[i][j];
    }
  
    // displaying the values of the new array
    for (int i = 0; i < R; i++) {
        for (int j = 0; j < C; j++)
            cout << psa[i][j] << " ";
        cout << "\n";
    }
}
  
// driver code
int main()
{
    int a[R][C] = { { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1 } };
  
    prefixSum2D(a);
  
    return 0;
}

Java

// Java program to find prefix sum of 2D array


import java.util.*;
  
class GFG {
  
    // calculating new array
    public static void prefixSum2D(int a[][])
    {
        int R = a.length;
        int C = a[0].length;
  
        int psa[][] = new int[R][C];
  
        psa[0][0] = a[0][0];
  
        // Filling first row and first column
        for (int i = 1; i < C; i++)
            psa[0][i] = psa[0][i - 1] + a[0][i];
        for (int i = 1; i < R; i++)

2401
Chapter 333. Prefix Sum of Matrix (Or 2D Array)

            psa[i][0] = psa[i - 1][0] + a[i][0];


  
        // updating the values in the
        // cells as per the general formula.
        for (int i = 1; i < R; i++)
            for (int j = 1; j < C; j++)
  
                // values in the cells of new array
                // are updated
                psa[i][j] = psa[i - 1][j] + psa[i][j - 1]
                            - psa[i - 1][j - 1] + a[i][j];
  
        for (int i = 0; i < R; i++) {
            for (int j = 0; j < C; j++)
                System.out.print(psa[i][j] + " ");
            System.out.println();
        }
    }
  
    // driver code
    public static void main(String[] args)
    {
        int a[][] = { { 1, 1, 1, 1, 1 },
                      { 1, 1, 1, 1, 1 },
                      { 1, 1, 1, 1, 1 },
                      { 1, 1, 1, 1, 1 } };
        prefixSum2D(a);
    }
}

Python3

# Python Program to find 


# prefix sum of 2d array
R = 4
C = 5
  
# calculating new array
def prefixSum2D(a) :
    global C, R
    psa = [[0 for x in range(C)] 
              for y in range(R)] 
    psa[0][0] = a[0][0]
  
    # Filling first row 
    # and first column
    for i in range(1, C) :
        psa[0][i] = (psa[0][i - 1] + 

2402
Chapter 333. Prefix Sum of Matrix (Or 2D Array)

                       a[0][i])
    for i in range(0, R) :
        psa[i][0] = (psa[i - 1][0] + 
                       a[i][0])
  
    # updating the values in 
    # the cells as per the 
    # general formula
    for i in range(1, R) :
        for j in range(1, C) :
  
            # values in the cells of 
            # new array are updated
            psa[i][j] = (psa[i - 1][j] + 
                         psa[i][j - 1] - 
                         psa[i - 1][j - 1] + 
                           a[i][j])
  
    # displaying the values
    # of the new array
    for i in range(0, R) :
        for j in range(0, C) :
            print (psa[i][j], 
                   end = " ")
        print ()
  
# Driver Code
a = [[ 1, 1, 1, 1, 1 ],
     [ 1, 1, 1, 1, 1 ],
     [ 1, 1, 1, 1, 1 ],
     [ 1, 1, 1, 1, 1 ]]
  
prefixSum2D(a)
  
# This code is contributed by 
# Manish Shaw(manishshaw1)

C#

// C# program to find prefix


// sum of 2D array
using System;
  
class GFG 
{
  
    // calculating new array
    static void prefixSum2D(int [,]a)

2403
Chapter 333. Prefix Sum of Matrix (Or 2D Array)

    {
        int R = a.GetLength(0);
        int C = a.GetLength(1);
  
        int [,]psa = new int[R, C];
  
        psa[0, 0] = a[0, 0];
  
        // Filling first row
        // and first column
        for (int i = 1; i < C; i++)
            psa[0, i] = psa[0, i - 1] + 
                               a[0, i];
        for (int i = 1; i < R; i++)
            psa[i, 0] = psa[i - 1, 0] + 
                               a[i, 0];
   
        // updating the values in the
        // cells as per the general formula.
        for (int i = 1; i < R; i++)
            for (int j = 1; j < C; j++)
  
                // values in the cells of 
                // new array are updated
                psa[i, j] = psa[i - 1, j] + 
                            psa[i, j - 1] - 
                            psa[i - 1, j - 1] + 
                            a[i, j];
  
        for (int i = 0; i < R; i++) 
        {
            for (int j = 0; j < C; j++)
                Console.Write(psa[i, j] + " ");
            Console.WriteLine();
        }
    }
  
    // Driver Code
    static void Main()
    {
        int [,]a = new int[,]{{1, 1, 1, 1, 1},
                              {1, 1, 1, 1, 1},
                              {1, 1, 1, 1, 1},
                              {1, 1, 1, 1, 1}};
        prefixSum2D(a);
    }
}
  

2404
Chapter 333. Prefix Sum of Matrix (Or 2D Array)

// This code is contributed by manishshaw1

PHP

<?php
// PHP Program to find 
// prefix sum of 2d array
$R = 4;
$C = 5;
  
// calculating new array
function prefixSum2D($a)
{
    global $C, $R;
    $psa = array();
    $psa[0][0] = $a[0][0];
  
    // Filling first row 
    // and first column
    for ($i = 1; $i < $C; $i++)
        $psa[0][$i] = $psa[0][$i - 1] + 
                             $a[0][$i];
    for ($i = 0; $i < $R; $i++)
        $psa[$i][0] = $psa[$i - 1][0] + 
                             $a[$i][0];
  
    // updating the values in 
    // the cells as per the 
    // general formula
    for ($i = 1; $i < $R; $i++)
    {
        for ($j = 1; $j < $C; $j++)
  
            // values in the cells of 
            // new array are updated
            $psa[$i][$j] = $psa[$i - 1][$j] + 
                           $psa[$i][$j - 1] - 
                           $psa[$i - 1][$j - 1] + 
                           $a[$i][$j];
    }
  
    // displaying the values
    // of the new array
    for ($i = 0; $i < $R; $i++) 
    {
        for ($j = 0; $j < $C; $j++)
            echo ($psa[$i][$j]. " ");
        echo ("\n");

2405
Chapter 333. Prefix Sum of Matrix (Or 2D Array)

    }
}
  
// Driver Code
$a = array(array( 1, 1, 1, 1, 1 ),
           array( 1, 1, 1, 1, 1 ),
           array( 1, 1, 1, 1, 1 ),
           array( 1, 1, 1, 1, 1 ));
  
prefixSum2D($a);
  
// This code is contributed by 
// Manish Shaw(manishshaw1)
?>

Output :

1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20

Time Complexity : O(R*C)


Auxiliary Space : O(R*C)
Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/prefix-sum-2d-array/

2406
Chapter 334

Print Fibonacci Series in


reverse order

Print Fibonacci Series in reverse order - GeeksforGeeks


Given a number n then print n terms of fibonacci series in reverse order.
Examples:

Input : n = 5
Output : 3 2 1 1 0

Input : n = 8
Output : 13 8 5 3 2 1 1 0

Algorithm

1) Declare an array of size n.


2) Initialize a[0] and a[1] to 0 and 1 respectively.
3) Run a loop from 2 to n-1 and store
sum of a[i-2] and a[i-1] in a[i].
4) Print the array in the reverse order.

C++

// CPP Program to print Fibonacci


// series in reverse order
#include <bits/stdc++.h>
using namespace std;
  
void reverseFibonacci(int n)

2407
Chapter 334. Print Fibonacci Series in reverse order

{
    int a[n];
  
    // assigning first and second elements
    a[0] = 0;
    a[1] = 1;
  
    for (int i = 2; i < n; i++) {
  
        // storing sum in the
        // preceding location
        a[i] = a[i - 2] + a[i - 1];
    }
  
    for (int i = n - 1; i >= 0; i--) {
  
        // printing array in
        // reverse order
        cout << a[i] << " ";
    }
}
  
// Driver function
int main()
{
    int n = 5;
    reverseFibonacci(n);
    return 0;
}

Java

// Java Program to print Fibonacci


// series in reverse order
import java.io.*;
  
class GFG {
      
    static void reverseFibonacci(int n)
    {
        int a[] = new int[n];
      
        // assigning first and second elements
        a[0] = 0;
        a[1] = 1;
      
        for (int i = 2; i < n; i++)
        {

2408
Chapter 334. Print Fibonacci Series in reverse order

      
            // storing sum in the
            // preceding location
            a[i] = a[i - 2] + a[i - 1];
        }
      
        for (int i = n - 1; i >= 0; i--) 
        {
      
            // printing array in
            // reverse order
            System.out.print(a[i] +" ");
        }
    }
      
    // Driver function
    public static void main(String[] args)
    {
        int n = 5;
        reverseFibonacci(n);
      
    }
}
  
// This code is contributed by vt_m.

Python3

# Python 3 Program to print Fibonacci


# series in reverse order
  
def reverseFibonacci(n):
   
    a = [0] * n 
  
    # assigning first and second elements
    a[0] = 0 
    a[1] = 1 
  
    for i in range(2, n):  
  
        # storing sum in the
        # preceding location
        a[i] = a[i - 2] + a[i - 1] 
       
  
    for i in range(n - 1, -1 , -1):  
  

2409
Chapter 334. Print Fibonacci Series in reverse order

        # printing array in


        # reverse order
        print(a[i],end=" ") 
       
   
  
# Driver function
n = 5 
reverseFibonacci(n) 

C#

// C# Program to print Fibonacci


// series in reverse order
using System;
  
class GFG {
      
    static void reverseFibonacci(int n)
    {
        int []a = new int[n];
      
        // assigning first and second elements
        a[0] = 0;
        a[1] = 1;
      
        for (int i = 2; i < n; i++)
        {
      
            // storing sum in the
            // preceding location
            a[i] = a[i - 2] + a[i - 1];
        }
      
        for (int i = n - 1; i >= 0; i--) 
        {
      
            // printing array in
            // reverse order
            Console.Write(a[i] +" ");
        }
    }
      
    // Driver function
    public static void Main()
    {
        int n = 5;
        reverseFibonacci(n);

2410
Chapter 334. Print Fibonacci Series in reverse order

      
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP Program to print Fibonacci
// series in reverse order
  
function reverseFibonacci($n)
{
  
    // assigning first and
    // second elements
    $a[0] = 0;
    $a[1] = 1;
  
    for ($i = 2; $i < $n; $i++)
    {
  
        // storing sum in the
        // preceding location
        $a[$i] = $a[$i - 2] + 
                 $a[$i - 1];
    }
  
    for ($i = $n - 1; $i >= 0; $i--)
    {
  
        // printing array in
        // reverse order
        echo($a[$i] . " ");
    }
}
  
// Driver COde
$n = 5;
reverseFibonacci($n);
  
// This code is contributed by Ajit.
?>

Output:

2411
Chapter 334. Print Fibonacci Series in reverse order

3 2 1 1 0

Improved By : jit_t

Source

https://www.geeksforgeeks.org/print-fibonacci-series-reverse-order/

2412
Chapter 335

Print Fibonacci sequence using


2 variables

Print Fibonacci sequence using 2 variables - GeeksforGeeks


Print the Fibonacci sequence. The first Fibonacci numbers are:

C++

// Simple CPP Program to print Fibonacci 


// sequence
#include <iostream>
using std::cout;
void fib(int n)
{
    int a = 0, b = 1, c;
    if (n >= 0)
        cout << a << " ";
    if (n >= 1)
        cout << b << " ";
    for (int i = 2; i <= n; i++) {
        c = a + b;
        cout << c << " ";
        a = b;
        b = c;
    }
}
  
// Driver code

2413
Chapter 335. Print Fibonacci sequence using 2 variables

int main()
{
    fib(9);
    return 0;
}

Java

// Simple Java Program to print


// Fibonacci  sequence
import java.io.*;
class GFG {
  
static void fib(int n)
{
    int a = 0, b = 1, c;
    if (n >= 0)
        System.out.print( a + " ");
    if (n >= 1)
        System.out.print( b + " ");
    for (int i = 2; i <= n; i++) 
    {
        c = a + b;
        System.out.print( c + " ");
        a = b;
        b = c;
    }
}
  
    // Driver code
    public static void main (String[] args) 
    {
            fib(9);
    }
}
  
// This code is contributed by anuj_67.

Python3

# Simple Python3 Program to 


# print Fibonacci sequence
  
def fib(n):
    a = 0
    b = 1
    if (n >= 0):

2414
Chapter 335. Print Fibonacci sequence using 2 variables

        print(a, end=' ')


    if (n >= 1):
        print(b, end=' ')
    for i in range(2, n+1):
        c = a + b
        print(c, end=' ')
        a = b
        b = c
  
# Driver code
fib(9)
  
# This code is contributed 
# by Prasad Kshirsagar

C#

// Simple C# Program to print


// Fibonacci sequence
using System;
class GFG 
{
static void fib(int n)
{
    int a = 0, b = 1, c;
    if (n >= 0)
        Console.Write( a + " ");
    if (n >= 1)
        Console.Write( b + " ");
    for (int i = 2; i <= n; i++) 
    {
        c = a + b;
        Console.Write( c + " ");
        a = b;
        b = c;
    }
}
  
// Driver code
public static void Main () 
{
        fib(9);
}
}
  
// This code is contributed by anuj_67.

PHP

2415
Chapter 335. Print Fibonacci sequence using 2 variables

<?php
// Simple php Program to print
// Fibonacci sequence
  
function fib( $n)
{
    $a = 0; $b = 1; $c;
    if ($n >= 0)
        echo $a , " ";
    if ($n >= 1)
        echo $b , " ";
    for ( $i = 2; $i <= $n; $i++) 
    {
        $c = $a + $b;
        echo $c , " ";
        $a = $b;
        $b = $c;
    }
}
  
// Driver code
fib(9);
  
// This code is contributed by anuj_67.
?>

Output:

0 1 1 2 3 5 8 13 21 34

How to print using 2 variables isntead of 3 variables?


The algorithm with 2 variables is:
1. print a+b.
2. add a to b.
3. assign b – a to a.
C++

// CPP Program to print Fibonacci sequence


// using 2 variables
#include <iostream>
using std::cout;
void fib(int n)
{
    int a = 0, b = 1;

2416
Chapter 335. Print Fibonacci sequence using 2 variables

    if (n >= 0)
        cout << a << " ";
    if (n >= 1)
        cout << b << " ";
    for (int i = 2; i <= n; i++) {
        cout << a + b << " ";
        b = a + b;
        a = b - a;
    }
}
  
// Driver code
int main()
{
    fib(9);
    return 0;
}

Java

// Java Program to print 


// Fibonacci sequence
// using 2 variables
import java.io.*;
class GFG {
      
static void fib(int n)
{
    int a = 0, b = 1;
    if (n >= 0)
        System.out.print(a + " ");
    if (n >= 1)
        System.out.print(b + " ");
    for (int i = 2; i <= n; i++) 
    {
        System.out.print(a + b + " ");
        b = a + b;
        a = b - a;
    }
}
  
    // Driver code
    public static void main (String[] args) 
    {
        fib(9);
    }
}
  

2417
Chapter 335. Print Fibonacci sequence using 2 variables

// This code is contributed by anuj_67.

Python3

# Simple Python3 Program to


# print Fibonacci sequence
# using 2 variables
  
def fib(n):
    a = 0
    b = 1
    if (n >= 0):
        print(a, end=' ')
    if (n >= 1):
        print(b, end=' ')
    for i in range(2, n+1):
        print(a + b, end=' ')
        b = a + b
        a = b - a
  
# Driver code
fib(9)
  
# This code is contributed by
# Prasad Kshirsagar

C#

// C# Program to print Fibonacci


// sequence using 2 variables
using System;
  
class GFG {
          
    static void fib(int n)
    {
        int a = 0, b = 1;
          
        if (n >= 0)
            Console.Write(a + " ");
        if (n >= 1)
            Console.Write(b + " ");
        for (int i = 2; i <= n; i++) 
        {
            Console.Write(a + b + " ");
            b = a + b;
            a = b - a;

2418
Chapter 335. Print Fibonacci sequence using 2 variables

        }
    }
  
    // Driver code
    public static void Main () 
    {
        fib(9);
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP Program to print Fibonacci sequence
// using 2 variables
  
function fib( $n)
{
    $a = 0; $b = 1;
    if ($n >= 0)
        echo $a , " ";
    if ($n >= 1)
        echo $b , " ";
    for ($i = 2; $i <= $n; $i++)
    {
        echo $a + $b , " ";
        $b = $a + $b;
        $a = $b - $a;
    }
}
  
    // Driver code
    fib(9);
      
// This code is contributed by anuj_67
?>

Output :

0 1 1 2 3 5 8 13 21 34

Improved By : vt_m, Prasad_Kshirsagar

2419
Chapter 335. Print Fibonacci sequence using 2 variables

Source

https://www.geeksforgeeks.org/print-fibonacci-sequence-using-2-variables/

2420
Chapter 336

Print Longest Palindromic


Subsequence

Print Longest Palindromic Subsequence - GeeksforGeeks


Given a sequence, print a longest palindromic subsequence of it.
Examples :

Input : BBABCBCAB
Output : BABCBAB
The above output is the longest
palindromic subsequence of given
sequence. "BBBBB" and "BBCBB" are
also palindromic subsequences of
the given sequence, but not the
longest ones.

Input : GEEKSFORGEEKS
Output : Output can be either EEKEE
or EESEE or EEGEE, ..

We have discussed a solution in below post to find length of longest palindromic subsequence.
Dynamic Programming | Set 12 (Longest Palindromic Subsequence)
In this post a solution to print the longest palindromic subsequence is discussed.
This problem is close to the Longest Common Subsequence (LCS) problem. In fact, we can
use LCS as a subroutine to solve this problem. Following is the two step solution that uses
LCS.
1) Reverse the given sequence and store the reverse in another array say rev[0..n-1]
2) LCS of the given sequence and rev[] will be the longest palindromic sequence.
3) Once we have found LCS, we can print the LCS.

2421
Chapter 336. Print Longest Palindromic Subsequence

/* CPP program to print longest palindromic


   subsequence */
#include<bits/stdc++.h>
using namespace std;
  
/* Returns LCS X and Y */
string lcs(string &X, string &Y)
{
    int m = X.length();
    int n = Y.length();
  
    int L[m+1][n+1];
  
    /* Following steps build L[m+1][n+1] in bottom
       up fashion. Note that L[i][j] contains
       length of LCS of X[0..i-1] and Y[0..j-1] */
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
            else if (X[i-1] == Y[j-1])
                L[i][j] = L[i-1][j-1] + 1;
            else
                L[i][j] = max(L[i-1][j], L[i][j-1]);
        }
    }
  
    // Following code is used to print LCS
    int index = L[m][n];
  
    // Create a string length index+1 and
    // fill it with \0
    string lcs(index+1, '\0');
  
    // Start from the right-most-bottom-most
    // corner and one by one store characters
    // in lcs[]
    int i = m, j = n;
    while (i > 0 && j > 0)
    {
        // If current character in X[] and Y
        // are same, then current character
        // is part of LCS
        if (X[i-1] == Y[j-1])
        {
            // Put current character in result

2422
Chapter 336. Print Longest Palindromic Subsequence

            lcs[index-1] = X[i-1];
            i--;
            j--;
  
            // reduce values of i, j and index
            index--;
        }
  
        // If not same, then find the larger of
        // two and go in the direction of larger
        // value
        else if (L[i-1][j] > L[i][j-1])
            i--;
        else
            j--;
    }
  
    return lcs;
}
  
// Returns longest palindromic subsequence
// of str
string longestPalSubseq(string &str)
{
    // Find reverse of str
    string rev = str;
    reverse(rev.begin(), rev.end());
  
    // Return LCS of str and its reverse
    return lcs(str, rev);
}
  
/* Driver program to test above function */
int main()
{
    string str = "GEEKSFORGEEKS";
    cout << longestPalSubseq(str);
    return 0;
}

Output:

EEGEE

Source

https://www.geeksforgeeks.org/print-longest-palindromic-subsequence/

2423
Chapter 337

Print Maximum Length Chain


of Pairs

Print Maximum Length Chain of Pairs - GeeksforGeeks


You are given n pairs of numbers. In every pair, the first number is always smaller than the
second number. A pair (c, d) can follow another pair (a, b) if b < c. Chain of pairs can
be formed in this fashion. Find the longest chain which can be formed from a given set of
pairs.
Examples:

Input: (5, 24), (39, 60), (15, 28), (27, 40), (50, 90)
Output: (5, 24), (27, 40), (50, 90)

Input: (11, 20), {10, 40), (45, 60), (39, 40)


Output: (11, 20), (39, 40), (45, 60)

In previous post, we have discussed about Maximum Length Chain of Pairs problem. How-
ever, the post only covered code related to finding the length of maximum size chain, but
not to the construction of maximum size chain. In this post, we will discuss how to construct
Maximum Length Chain of Pairs itself.
The idea is to first sort given pairs in increasing order of their first element. Let arr[0..n-1]
be the input array of pairs after sorting. We define vector L such that L[i] is itself is a vector
that stores Maximum Length Chain of Pairs of arr[0..i] that ends with arr[i]. Therefore for
an index i, L[i] can be recursively written as –

L[0] = {arr[0]}
L[i] = {Max(L[j])} + arr[i] where j < i and arr[j].b < arr[i].a
= arr[i], if there is no such j

2424
Chapter 337. Print Maximum Length Chain of Pairs

For example, for (5, 24), (39, 60), (15, 28), (27, 40), (50, 90)

L[0]: (5, 24)


L[1]: (5, 24) (39, 60)
L[2]: (15, 28)
L[3]: (5, 24) (27, 40)
L[4]: (5, 24) (27, 40) (50, 90)

Please note sorting of pairs is done as we need to find the maximum pair length and ordering
doesn’t matter here. If we don’t sort, we will get pairs in increasing order but they won’t
be maximum possible pairs.
Below is C++ implementation of above idea –

/* Dynamic Programming solution to construct


   Maximum Length Chain of Pairs */
#include <bits/stdc++.h>
using namespace std;
  
struct Pair
{
    int a;
    int b;
};
  
// comparator function for sort function
int compare(Pair x, Pair y)
{
    return x.a < y.a;
}
  
// Function to construct Maximum Length Chain
// of Pairs
void maxChainLength(vector<Pair> arr)
{
    // Sort by start time
    sort(arr.begin(), arr.end(), compare);
  
    // L[i] stores maximum length of chain of
    // arr[0..i] that ends with arr[i].
    vector<vector<Pair> > L(arr.size());
  
    // L[0] is equal to arr[0]
    L[0].push_back(arr[0]);
  
    // start from index 1
    for (int i = 1; i < arr.size(); i++)

2425
Chapter 337. Print Maximum Length Chain of Pairs

    {
        // for every j less than i
        for (int j = 0; j < i; j++)
        {
            // L[i] = {Max(L[j])} + arr[i]
            // where j < i and arr[j].b < arr[i].a
            if ((arr[j].b < arr[i].a) &&
                (L[j].size() > L[i].size()))
                L[i] = L[j];
        }
        L[i].push_back(arr[i]);
    }
  
    // print max length vector
    vector<Pair> maxChain;
    for (vector<Pair> x : L)
        if (x.size() > maxChain.size())
            maxChain = x;
  
    for (Pair pair : maxChain)
        cout << "(" << pair.a << ", "
             << pair.b << ") ";
}
  
// Driver Function
int main()
{
    Pair a[] = {{5, 29}, {39, 40}, {15, 28},
                {27, 40}, {50, 90}};
    int n = sizeof(a)/sizeof(a[0]);
  
    vector<Pair> arr(a, a + n);
  
    maxChainLength(arr);
  
    return 0;
}

Output:

(5, 29) (39, 40) (50, 90)

Time complexity of above Dynamic Programming solution is O(n2 ) where n is the number
of pairs.
Auxiliary space used by the program is O(n2 ).

2426
Chapter 337. Print Maximum Length Chain of Pairs

Source

https://www.geeksforgeeks.org/print-maximum-length-chain-of-pairs/

2427
Chapter 338

Print all distinct characters of a


string in order (3 Methods)

Print all distinct characters of a string in order (3 Methods) - GeeksforGeeks


Given a string, find the all distinct (or non-repeating characters) in it. For example, if the
input string is “Geeks for Geeks”, then output should be ‘for’ and if input string is “Geeks
Quiz”, then output should be ‘GksQuiz’.
The distinct characters should be printed in same order as they appear in input string.
Examples:

Input : Geeks for Geeks


Output : for

Input : Hello Geeks


Output : HoGks

Method 1 (Simple : O(n2 ))


A Simple Solution is to run two loops. Start traversing from left side. For every character,
check if it repeats or not. If the character doesn’t repeat, increment count of non-repeating
characters. When the count becomes 1, return each character.
Method 2 (Efficient but requires two traversals: O(n))

1. Create an array count[] to store counts of characters.


2. Traverse the input string str and do following for every character x = str[i].
Increment count[x].
3. Traverse the input string again and do following for every character str[i]
(a) If count[x] is 1, then print the unique character
(b) If count[x] is greater than 1, then ignore the repeated character.

2428
Chapter 338. Print all distinct characters of a string in order (3 Methods)

Below is the implementation of above idea.

C++

// C++ program to print distinct characters of a


// string.
# include <iostream>
using namespace std;
# define NO_OF_CHARS 256
  
/* Print duplicates present in the passed string */
void printDistinct(char *str)
{
    // Create an array of size 256 and count of
    // every character in it
    int count[NO_OF_CHARS];
  
    /* Count array with frequency of characters */
    int i;
    for (i = 0; *(str+i); i++)
        if(*(str+i)!=' ')
            count[*(str+i)]++;
    int n = i;
  
    // Print characters having count more than 0
    for (i = 0; i < n; i++)
        if (count[*(str+i)] == 1)
            cout<< str[i];
}
  
/* Driver program*/
int main()
{
    char str[] = "GeeksforGeeks";
    printDistinct((str);
    return 0;
}

Java

// Java program to print distinct characters of a


// string.
public class GFG {
    static final int NO_OF_CHARS = 256;
       
    /* Print duplicates present in the passed string */
    static void printDistinct(String str)

2429
Chapter 338. Print all distinct characters of a string in order (3 Methods)

    {
        // Create an array of size 256 and count of
        // every character in it
        int[] count = new int[NO_OF_CHARS];
       
        /* Count array with frequency of characters */
        int i;
        for (i = 0; i < str.length(); i++)
            if(str.charAt(i)!=' ')
                count[(int)str.charAt(i)]++;
        int n = i;
       
        // Print characters having count more than 0
        for (i = 0; i < n; i++)
            if (count[(int)str.charAt(i)] == 1)
                System.out.print(str.charAt(i));
    }
       
    /* Driver program*/
    public static void main(String args[])
    {
        String str = "GeeksforGeeks";
        printDistinct(str);
    }
}
// This code is contributed by Sumit Ghosh

C#

// C# program to print distinct characters


// of a string.
using System;
  
public class GFG {
      
    static int NO_OF_CHARS = 256;
      
    /* Print duplicates present in the
    passed string */
    static void printDistinct(String str)
    {
          
        // Create an array of size 256 and
        // count of every character in it
        int[] count = new int[NO_OF_CHARS];
      
        /* Count array with frequency of
        characters */

2430
Chapter 338. Print all distinct characters of a string in order (3 Methods)

        int i;
          
        for (i = 0; i < str.Length; i++)
            if(str[i]!=' ')
                count[(int)str[i]]++;
                  
        int n = i;
      
        // Print characters having count
        // more than 0
        for (i = 0; i < n; i++)
            if (count[(int)str[i]] == 1)
                Console.Write(str[i]);
    }
      
    /* Driver program*/
    public static void Main()
    {
        String str = "GeeksforGeeks";
          
        printDistinct(str);
    }
}
  
// This code is contributed by parashar.

Output:

for

Method 3 (O(n) and requires one traversal)


The idea is to use two auxiliary arrays of size 256 (Assuming that characters are stored
using 8 bits).

1. Initialize all values in count[] as 0 and all values in index[] as n where n is length of
string.
2. Traverse the input string str and do following for every character c = str[i].
• Increment count[x].
• If count[x] is 1, then store index of x in index[x], i.e., index[x] = i
• If count[x] is 2, then remove x from index[], i.e., index[x] = n
3. Now index[] has indexes of all distinct characters. Sort indexes and print characters
using it. Note that this step takes O(1) time assuming number of characters are fixed
(typically 256)

2431
Chapter 338. Print all distinct characters of a string in order (3 Methods)

Below is the implementation of above idea.

C++

// C++ program to find all distinct characters


// in a string
#include <bits/stdc++.h>
using namespace std;
const int MAX_CHAR = 256;
  
// Function to print distinct characters in
// given string str[]
void printDistinct(string str)
{
    int n = str.length();
  
    // count[x] is going to store count of
    // character 'x' in str. If x is not present,
    // then it is going to store 0.
    int count[MAX_CHAR];
  
    // index[x] is going to store index of character
    // 'x' in str. If x is not present or x is
    // more than once, then it is going to store a value
    // (for example, length of string) that cannot be
    // a valid index in str[]
    int index[MAX_CHAR];
  
    // Initialize counts of all characters and indexes
    // of distinct characters.
    for (int i = 0; i < MAX_CHAR; i++)
    {
        count[i] = 0;
        index[i] = n; // A value more than any index
                      // in str[]
    }
  
    // Traverse the input string
    for (int i = 0; i < n; i++)
    {
        // Find current character and increment its
        // count
        char x = str[i];
        ++count[x];
  
        // If this is first occurrence, then set value
        // in index as index of it.
        if (count[x] == 1 && x !=' ')

2432
Chapter 338. Print all distinct characters of a string in order (3 Methods)

            index[x] = i;
  
        // If character repeats, then remove it from
        // index[]
        if (count[x] == 2)
            index[x] = n;
    }
  
    // Since size of index is constant, below operations
    // take constant time.
    sort(index, index+MAX_CHAR);
    for (int i=0; i<MAX_CHAR && index[i] != n; i++)
       cout << str[index[i]];
}
  
// Driver code
int main()
{
    string str = "GeeksforGeeks";
    printDistinct(str);
    return 0;
}

Java

// Java program to print distinct characters of 


// a string.
import java.util.Arrays;
  
public class GFG {
      
    static final int MAX_CHAR = 256;
       
    // Function to print distinct characters in
    // given string str[]
    static void printDistinct(String str)
    {
        int n = str.length();
       
        // count[x] is going to store count of
        // character 'x' in str. If x is not present,
        // then it is going to store 0.
        int[] count = new int[MAX_CHAR];
       
        // index[x] is going to store index of character
        // 'x' in str. If x is not present or x is
        // more than once, then it is going to store a 
        // value (for example, length of string) that 

2433
Chapter 338. Print all distinct characters of a string in order (3 Methods)

        // cannot be a valid index in str[]


        int[] index = new int[MAX_CHAR];
       
        // Initialize counts of all characters and 
        // indexes of distinct characters.
        for (int i = 0; i < MAX_CHAR; i++)
        {
            count[i] = 0;
            index[i] = n; // A value more than any 
                          // index in str[]
        }
       
        // Traverse the input string
        for (int i = 0; i < n; i++)
        {
            // Find current character and increment 
            // its count
            char x = str.charAt(i);
            ++count[x];
       
            // If this is first occurrence, then set 
            // value in index as index of it.
            if (count[x] == 1 && x !=' ')
                index[x] = i;
       
            // If character repeats, then remove it 
            // from index[]
            if (count[x] == 2)
                index[x] = n;
        }
       
        // Since size of index is constant, below 
        // operations take constant time.
        Arrays.sort(index);
          
        for (int i = 0; i < MAX_CHAR && index[i] != n;
                                                  i++)
           System.out.print(str.charAt(index[i]));
    }
       
    // Driver code
    public static void main(String args[])
    {
        String str = "GeeksforGeeks";
        printDistinct(str);
    }
}
// This code is contributed by Sumit Ghosh

2434
Chapter 338. Print all distinct characters of a string in order (3 Methods)

C#

// C# program to print distinct characters of 


// a string.
using System;
  
public class GFG {
      
    static int MAX_CHAR = 256;
      
    // Function to print distinct characters in
    // given string str[]
    static void printDistinct(string str)
    {
        int n = str.Length;
      
        // count[x] is going to store count of
        // character 'x' in str. If x is not 
        // present, then it is going to store 0.
        int []count = new int[MAX_CHAR];
      
        // index[x] is going to store index of 
        // character 'x' in str. If x is not 
        // present or x is more than once, then
        // it is going to store a value (for 
        // example, length of string) that 
        // cannot be a valid index in str[]
        int []index = new int[MAX_CHAR];
      
        // Initialize counts of all characters 
        // and indexes of distinct characters.
        for (int i = 0; i < MAX_CHAR; i++)
        {
            count[i] = 0;
              
            // A value more than any index
            // in str[]
            index[i] = n;
                          
        }
      
        // Traverse the input string
        for (int i = 0; i < n; i++)
        {
            // Find current character and 
            // increment its count
            char x = str[i];
            ++count[x];

2435
Chapter 338. Print all distinct characters of a string in order (3 Methods)

      
            // If this is first occurrence, then
            // set value in index as index of it.
            if (count[x] == 1 && x !=' ')
                index[x] = i;
      
            // If character repeats, then remove
            // it from index[]
            if (count[x] == 2)
                index[x] = n;
        }
      
        // Since size of index is constant, below 
        // operations take constant time.
        Array.Sort(index);
          
        for (int i = 0; i < MAX_CHAR && 
                              index[i] != n; i++)
        Console.Write(str[index[i]]);
    }
      
    // Driver code
    public static void Main()
    {
        string str = "GeeksforGeeks";
        printDistinct(str);
    }
}
  
// This code is contributed by nitin mittal.

Output:

for

Improved By : parashar, nitin mittal

Source

https://www.geeksforgeeks.org/print-all-distinct-characters-of-a-string-in-order-3-methods/

2436
Chapter 339

Print all longest common


sub-sequences in lexicographical
order

Print all longest common sub-sequences in lexicographical order - GeeksforGeeks


You are given two strings.Now you have to print all longest common sub-sequences in lexi-
cographical order?
Examples:

Input : str1 = "abcabcaa", str2 = "acbacba"


Output: ababa
abaca
abcba
acaba
acaca
acbaa
acbca

This problem is an extension of longest common subsequence. We first find length of LCS
and store all LCS in 2D table using Memoization (or Dynamic Programming). Then we
search all characters from ‘a’ to ‘z’ (to output sorted order) in both strings. If a character is
found in both strings and current positions of character lead to LCS, we recursively search
all occurrences with current LCS length plus 1.
Below is the implementation of algorithm.

// C++ program to find all LCS of two strings in


// sorted order.
#include<bits/stdc++.h>

2437
Chapter 339. Print all longest common sub-sequences in lexicographical order

#define MAX 100


using namespace std;
  
// length of lcs
int lcslen = 0;
  
// dp matrix to store result of sub calls for lcs
int dp[MAX][MAX];
  
// A memoization based function that returns LCS of
// str1[i..len1-1] and str2[j..len2-1]
int lcs(string str1, string str2, int len1, int len2,
                                      int i, int j)
{
    int &ret = dp[i][j];
  
    // base condition
    if (i==len1 || j==len2)
        return ret = 0;
  
    // if lcs has been computed
    if (ret != -1)
        return ret;
  
    ret = 0;
  
    // if characters are same return previous + 1 else
    // max of two sequences after removing i'th and j'th
    // char one by one
    if (str1[i] == str2[j])
        ret = 1 + lcs(str1, str2, len1, len2, i+1, j+1);
    else
        ret = max(lcs(str1, str2, len1, len2, i+1, j),
                  lcs(str1, str2, len1, len2, i, j+1));
    return ret;
}
  
// Function to print all routes common sub-sequences of
// length lcslen
void printAll(string str1, string str2, int len1, int len2,
              char data[], int indx1, int indx2, int currlcs)
{
    // if currlcs is equal to lcslen then print it
    if (currlcs == lcslen)
    {
        data[currlcs] = '\0';
        puts(data);
        return;

2438
Chapter 339. Print all longest common sub-sequences in lexicographical order

    }
  
    // if we are done with all the characters of both string
    if (indx1==len1 || indx2==len2)
        return;
  
    // here we have to print all sub-sequences lexicographically,
    // that's why we start from 'a'to'z' if this character is
    // present in both of them then append it in data[] and same
    // remaining part
    for (char ch='a'; ch<='z'; ch++)
    {
        // done is a flag to tell that we have printed all the
        // subsequences corresponding to current character
        bool done = false;
  
        for (int i=indx1; i<len1; i++)
        {
            // if character ch is present in str1 then check if
            // it is present in str2
            if (ch==str1[i])
            {
              for (int j=indx2; j<len2; j++)
              {
                // if ch is present in both of them and
                // remaining length is equal to remaining
                // lcs length then add ch in sub-sequenece
                if (ch==str2[j] &&
                  lcs(str1, str2, len1, len2, i, j) == lcslen-currlcs)
                {
                  data[currlcs] = ch;
                  printAll(str1, str2, len1, len2, data, i+1, j+1, currlcs+1);
                  done = true;
                  break;
                }
              }
            }
  
            // If we found LCS beginning with current character. 
            if (done)
                break;
        }
    }
}
  
// This function prints all LCS of str1 and str2
// in lexicographic order.
void prinlAllLCSSorted(string str1, string str2)

2439
Chapter 339. Print all longest common sub-sequences in lexicographical order

{
    // Find lengths of both strings
    int len1 = str1.length(), len2 = str2.length();
  
    // Find length of LCS
    memset(dp, -1, sizeof(dp));
    lcslen = lcs(str1, str2, len1, len2, 0, 0);
  
    // Print all LCS using recursive backtracking
    // data[] is used to store individual LCS.
    char data[MAX];
    printAll(str1, str2, len1, len2, data, 0, 0, 0);
}
  
// Driver program to run the case
int main()
{
    string str1 = "abcabcaa", str2 = "acbacba";
    prinlAllLCSSorted(str1, str2);
    return 0;
}

Output:

ababa
abaca
abcba
acaba
acaca
acbaa
acbca

Source

https://www.geeksforgeeks.org/print-longest-common-sub-sequences-lexicographical-order/

2440
Chapter 340

Print all possible ways to


convert one string into another
string | Edit-Distance

Print all possible ways to convert one string into another string | Edit-Distance - Geeks-
forGeeks
Prerequisite: Dynamic Programming | Set 5 (Edit Distance)
Given two strings str1 and str2, the task is to print the all possible ways to convert ‘str1’
into ‘str2’.
Below are the operations that can be performed on “str1”:

1. Insert
2. Remove
3. Replace

All of the above operations are of equal cost. The task is to print all the various ways to
convert ‘str1’ into ‘str2’ using the minimum number of edits (operations) required, where a
“way” comprises of the series of all such operations required.
Examples:

Input: str1 = “abcdef”, str2 = “axcdfdh”


Output:
Method 1:
Add h
Change f to d
Change e to f
Change b to x
Method 2:
Change f to h

2441
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

Add d
Change e to f
Change b to x
Method 3:
Change f to h
Change e to d
Add f
Change b to x

Approach for printing one possible way:


The approach for finding the minimum number of edits has been discussed in this post. To
print one possible way, iterate from the bottom right corner of the DP matrix formed using
Min-Edit Distance method. Check if the character pertaining to that element in both strings
is equal or not. If it is, it means it needs no edit, and DP[i][j] was copied from DP[i-1][j-1].

If str1[i-1] == str2[j-1], proceed diagonally.

Note that since the DP matrix contains one extra row and coloumn at 0 indices, String
indexes will be decreased by one. i.e. DP[i][j] corresponds to i-1 index of str1 and j-1 index
of str2.
Now, if the characters were not equal, that means this matrix element DP[i][j] was obtained
from the minimum of DP[i-1][j-1], DP[i][j-1] and DP[i-1][j], plus 1. Hence, check from where
this element was from.

1. If DP[i][j] == DP[i-1][j-1] + 1
It means the character was replaced from str1[i] to str2[j]. Proceed diagonally.
2. If DP[i][j] == DP[i][j-1] + 1
It means the character was Added from str2[j]. Proceed left.
3. If DP[i][j] == DP[i-1][j] + 1
It means the character str1[i] was deleted. Proceed up.

Once the end i.e., (i==0 or j==0 ) of either string is reached, converting of one string to
other is done. We will have printed all the set of operations required.
Below is the implementation of the above approach:

// Java program to print one possible


// way of converting a string to another
import java.util.*;
  
public class Edit_Distance {
    static int dp[][];
  
    // Function to print the steps
    static void printChanges(String s1, String s2)

2442
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

    {
        int i = s1.length();
        int j = s2.length();
  
        // check till the end
        while (i != 0 && j != 0) {
  
            // if characters are same
            if (s1.charAt(i - 1) == s2.charAt(j - 1)) {
                i--;
                j--;
            }
  
            // Replace
            else if (dp[i][j] == dp[i - 1][j - 1] + 1) {
                System.out.println("change " + s1.charAt(i - 1) + " to " + s2.charAt(j - 1));
                i--;
                j--;
            }
  
            // Delete the character
            else if (dp[i][j] == dp[i - 1][j] + 1) {
                System.out.println("Delete " + s1.charAt(i - 1));
                i--;
            }
  
            // Add the character
            else if (dp[i][j] == dp[i][j - 1] + 1) {
                System.out.println("Add " + s2.charAt(j - 1));
                j--;
            }
        }
    }
  
    // Function to compute the DP matrix
    static void editDP(String s1, String s2)
    {
        int l1 = s1.length();
        int l2 = s2.length();
        int[][] DP = new int[l1 + 1][l2 + 1];
  
        // initilize by the maximum edits possible
        for (int i = 0; i <= l1; i++)
            DP[i][0] = i;
        for (int j = 0; j <= l2; j++)
            DP[0][j] = j;
  
        // Compute the DP matrix

2443
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

        for (int i = 1; i <= l1; i++) {


            for (int j = 1; j <= l2; j++) {
  
                // if the characters are same
                // no changes required
                if (s1.charAt(i - 1) == s2.charAt(j - 1))
                    DP[i][j] = DP[i - 1][j - 1];
                else {
  
                    // minimu of three operations possible
                    DP[i][j] = min(DP[i - 1][j - 1],
                                   DP[i - 1][j], DP[i][j - 1])
                               + 1;
                }
            }
        }
  
        // initialize to global array
        dp = DP;
    }
  
    // Function to find the minimum of three
    static int min(int a, int b, int c)
    {
        int z = Math.min(a, b);
        return Math.min(z, c);
    }
  
    // Driver Code
    public static void main(String[] args) throws Exception
    {
        String s1 = "abcdef";
        String s2 = "axcdfdh";
  
        // calculate the DP matrix
        editDP(s1, s2);
  
        // print the steps
        printChanges(s1, s2);
    }
}

Output:

change f to h
change e to d
Add f

2444
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

change b to x

Approach to print all possible ways:


Create a collection of strings that will store the operations required. This collection can be
a vector of strings in C++ or a List of strings in Java. Add operations just like printing
them before to this collection. Then create a collection of these collections which will store
the multiple methods (sets of string operations).
Else-if was used earlier to check from where we derived the DP[i][j] from. Now, check all
If’s to see if there were more than 1 ways you could obtain the element. If there was, we
create a new collection from before, remove the last operation, add this new operation and
initiate another instance of this function with this new list. In this manner, add new lists
whenever there was a new method to change str1 to str2, getting a new method every time.
On reaching the end of either string, add this list to the collection of lists, thus completing
the set of all possible operations, and add them.
Below is the implementation of the above approach:

// Java program to print all the possible


// steps to change a string to another
import java.util.ArrayList;
  
public class Edit_Distance {
    static int dp[][];
  
    // create List of lists that will store all sets of operations
    static ArrayList<ArrayList<String> > arrs =
                              new ArrayList<ArrayList<String> >();
  
    // Function to print all ways
    static void printAllChanges(String s1,
                                String s2, ArrayList<String> changes)
    {
  
        int i = s1.length();
        int j = s2.length();
  
        // Iterate till end
        while (true) {
  
            if (i == 0 || j == 0) {
  
                // Add this list to our List of lists.
                arrs.add(changes);
                break;
            }
  
            // If same

2445
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

            if (s1.charAt(i - 1) == s2.charAt(j - 1)) {


                i--;
                j--;
            }
  
            else {
                boolean if1 = false, if2 = false;
  
                // Replace
                if (dp[i][j] == dp[i - 1][j - 1] + 1) {
  
                    // Add this step
                    changes.add("Change " + s1.charAt(i - 1)
                                + " to " + s2.charAt(j - 1));
                    i--;
                    j--;
  
                    // note whether this 'if' was true.
                    if1 = true;
                }
  
                // Delete
                if (dp[i][j] == dp[i - 1][j] + 1) {
                    if (if1 == false) {
                        changes.add("Delete " + s1.charAt(i - 1));
                        i--;
                    }
                    else {
                        // If the previous method was true,
                        // create a new list as a copy of previous.
                        ArrayList<String> changes2 = new ArrayList<String>();
                        changes2.addAll(changes);
  
                        // Remove last operation
                        changes2.remove(changes.size() - 1);
  
                        // Add this new operation
                        changes2.add("Delete " + s1.charAt(i));
  
                        // initiate new new instance of this
                        // function with remaining substrings
                        printAllChanges(s1.substring(0, i),
                                        s2.substring(0, j + 1), changes2);
                    }
  
                    if2 = true;
                }
  

2446
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

                // Add charater step


                if (dp[i][j] == dp[i][j - 1] + 1) {
                    if (if1 == false && if2 == false) {
                        changes.add("Add " + s2.charAt(j - 1));
                        j--;
                    }
                    else {
  
                        // Add steps
                        ArrayList<String> changes2 = new ArrayList<String>();
                        changes2.addAll(changes);
                        changes2.remove(changes.size() - 1);
                        changes2.add("Add " + s2.charAt(j));
  
                        // Recursively call for the next steps
                        printAllChanges(s1.substring(0, i + 1),
                                        s2.substring(0, j), changes2);
                    }
                }
            }
        }
    }
  
    // Function to compute the DP matrix
    static void editDP(String s1, String s2)
    {
        int l1 = s1.length();
        int l2 = s2.length();
        int[][] DP = new int[l1 + 1][l2 + 1];
  
        // initilize by the maximum edits possible
        for (int i = 0; i <= l1; i++)
            DP[i][0] = i;
        for (int j = 0; j <= l2; j++)
            DP[0][j] = j;
  
        // Compute the DP matrix
        for (int i = 1; i <= l1; i++) {
            for (int j = 1; j <= l2; j++) {
  
                // if the characters are same
                // no changes required
                if (s1.charAt(i - 1) == s2.charAt(j - 1))
                    DP[i][j] = DP[i - 1][j - 1];
                else {
  
                    // minimu of three operations possible
                    DP[i][j] = min(DP[i - 1][j - 1],

2447
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

                                   DP[i - 1][j], DP[i][j - 1])


                               + 1;
                }
            }
        }
  
        // initialize to global array
        dp = DP;
    }
  
    // Function to find the minimum of three
    static int min(int a, int b, int c)
    {
        int z = Math.min(a, b);
        return Math.min(z, c);
    }
    static void printWays(String s1, String s2,
                          ArrayList<String> changes)
    {
  
        // Function to print all the ways
        printAllChanges(s1, s2, new ArrayList<String>());
  
        int i = 1;
  
        // print all the possible ways
        for (ArrayList<String> ar : arrs) {
            System.out.println("\nMethod " + i++ + " : \n");
            for (String s : ar) {
                System.out.println(s);
            }
        }
    }
  
    // Driver Code
    public static void main(String[] args) throws Exception
    {
        String s1 = "abcdef";
        String s2 = "axcdfdh";
  
        // calculate the DP matrix
        editDP(s1, s2);
  
        // Function to print all ways
        printWays(s1, s2, new ArrayList<String>());
    }
}

2448
Chapter 340. Print all possible ways to convert one string into another string |
Edit-Distance

Output:

Method 1 :

Add h
Change f to d
Change e to f
Change b to x

Method 2 :

Change f to h
Add d
Change e to f
Change b to x

Method 3 :

Change f to h
Change e to d
Add f
Change b to x

Source

https://www.geeksforgeeks.org/print-all-possible-ways-to-convert-one-string-into-another-string-edit-distance/

2449
Chapter 341

Print equal sum sets of array


(Partition Problem) | Set 2

Print equal sum sets of array (Partition Problem) | Set 2 - GeeksforGeeks


Given an array arr[]. Determine whether it is possible to split the array into two sets such
that the sum of elements in both the sets is equal. If it is possible, then print both the sets.
If it is not possible then output -1.
Examples :

Input : arr = {5, 5, 1, 11}


Output : Set 1 = {5, 5, 1}, Set 2 = {11}
Sum of both the sets is 11 and equal.

Input : arr = {1, 5, 3}


Output : -1
No partitioning results in equal sum sets.

Prerequisite: Partition Problem


Approach: In the previous post, a solution using recursion is discussed. In this post, a
solution using Dynamic Programming is explained.
The idea is to declare two sets set 1 and set 2. To recover the solution, traverse the boolean
dp table backwards starting from the final result dp[n][k], where n = number of elements
and k = sum/2. Set 1 will consists of elements that contribute to sum k and other elements
that do not contribute are added to set 2. Follow these steps at each position to recover the
solution.

1. Check if dp[i-1][sum] is true or not. If it is true, then current element does not
contribute to sum k. Add this element to set 2. Update index i by i-1 and sum
remains unchanged.

2450
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

2. If dp[i-1][sum] is false, then current element contribute to sum k. Add current element
to set 1. Update index i by i-1 and sum by sum-arr[i-1].

Repeat above steps until each index position is traversed.


Implementation:

C++

// CPP program to print equal sum sets of array.


#include <bits/stdc++.h>
using namespace std;
  
// Function to print equal sum
// sets of array.
void printEqualSumSets(int arr[], int n)
{
    int i, currSum;
     
    // Finding sum of array elements
    int sum = accumulate(arr, arr+n, 0);
  
    // Check sum is even or odd. If odd
    // then array cannot be partitioned.
    // Print -1 and return.
    if (sum & 1) {
        cout << "-1";
        return;
    }
  
    // Divide sum by 2 to find
    // sum of two possible subsets.
    int k = sum >> 1;
  
    // Boolean DP table to store result
    // of states.
    // dp[i][j] = true if there is a
    // subset of elements in first i elements
    // of array that has sum equal to j.
    bool dp[n + 1][k + 1];
  
    // If number of elements are zero, then
    // no sum can be obtained.
    for (i = 1; i <= k; i++)
        dp[0][i] = false;
  
    // Sum 0 can be obtained by not selecting
    // any element.

2451
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

    for (i = 0; i <= n; i++)


        dp[i][0] = true;
  
    // Fill the DP table in bottom up manner.
    for (i = 1; i <= n; i++) {
        for (currSum = 1; currSum <= k; currSum++) {
  
            // Excluding current element.
            dp[i][currSum] = dp[i - 1][currSum];
  
            // Including current element
            if (arr[i - 1] <= currSum)
                dp[i][currSum] = dp[i][currSum] | 
                  dp[i - 1][currSum - arr[i - 1]];
        }
    }
  
    // Required sets set1 and set2.
    vector<int> set1, set2;
  
    // If partition is not possible print
    // -1 and return.
    if (!dp[n][k]) {
        cout << "-1\n";
        return;
    }
  
    // Start from last element in dp table.
    i = n;
    currSum = k;
  
    while (i > 0 && currSum >= 0) {
  
        // If current element does not
        // contribute to k, then it belongs
        // to set 2.
        if (dp[i - 1][currSum]) {
            i--;
            set2.push_back(arr[i]);
        }
  
        // If current element contribute
        // to k then it belongs to set 1.
        else if (dp[i - 1][currSum - arr[i - 1]]) {
            i--;
            currSum -= arr[i];
            set1.push_back(arr[i]);
        }

2452
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

    }
  
    // Print elements of both the sets.
    cout << "Set 1 elements: ";
    for (i = 0; i < set1.size(); i++) 
        cout << set1[i] << " ";
    cout << "\nSet 2 elements: ";
    for (i = 0; i < set2.size(); i++) 
        cout << set2[i] << " ";    
}
  
// Driver program.
int main()
{
    int arr[] = { 5, 5, 1, 11 };
    int n = sizeof(arr) / sizeof(arr[0]);
    printEqualSumSets(arr, n);
    return 0;
}

Java

// Java program to print 


// equal sum sets of array.
import java.io.*;
import java.util.*;
  
class GFG
{
    // Function to print equal 
    // sum sets of array.
    static void printEqualSumSets(int []arr, 
                                  int n)
    {
        int i, currSum, sum = 0;
          
        // Finding sum of array elements
        for (i = 0; i < arr.length; i++)
            sum += arr[i];
      
        // Check sum is even or odd. 
        // If odd then array cannot 
        // be partitioned. Print -1 
        // and return.
        if ((sum & 1) == 1) 
        {
            System.out.print("-1");
            return;

2453
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

        }
      
        // Divide sum by 2 to find
        // sum of two possible subsets.
        int k = sum >> 1;
      
        // Boolean DP table to store 
        // result of states.
        // dp[i,j] = true if there is a
        // subset of elements in first i 
        // elements of array that has sum
        // equal to j.
        boolean [][]dp = new boolean[n + 1][k + 1];
      
        // If number of elements are zero, 
        // then no sum can be obtained.
        for (i = 1; i <= k; i++)
            dp[0][i] = false;
      
        // Sum 0 can be obtained by 
        // not selecting any element.
        for (i = 0; i <= n; i++)
            dp[i][0] = true;
      
        // Fill the DP table 
        // in bottom up manner.
        for (i = 1; i <= n; i++) 
        {
            for (currSum = 1; 
                 currSum <= k; 
                 currSum++) 
            {
      
                // Excluding current element.
                dp[i][currSum] = dp[i - 1][currSum];
      
                // Including current element
                if (arr[i - 1] <= currSum)
                    dp[i][currSum] = dp[i][currSum] | 
                    dp[i - 1][currSum - arr[i - 1]];
            }
        }
      
        // Required sets set1 and set2.
        List<Integer> set1 = new ArrayList<Integer>();
        List<Integer> set2 = new ArrayList<Integer>();
      
        // If partition is not possible

2454
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

        // print -1 and return.


        if (!dp[n][k]) 
        {
            System.out.print("-1\n");
            return;
        }
      
        // Start from last 
        // element in dp table.
        i = n;
        currSum = k;
      
        while (i > 0 && currSum >= 0) 
        {
      
            // If current element does 
            // not contribute to k, then 
            // it belongs to set 2.
            if (dp[i - 1][currSum]) 
            {
                i--;
                set2.add(arr[i]);
            }
      
            // If current element contribute
            // to k then it belongs to set 1.
            else if (dp[i - 1][currSum - arr[i - 1]]) 
            {
                i--;
                currSum -= arr[i];
                set1.add(arr[i]);
            }
        }
      
        // Print elements of both the sets.
        System.out.print("Set 1 elements: ");
        for (i = 0; i < set1.size(); i++) 
            System.out.print(set1.get(i) + " ");
              
        System.out.print("\nSet 2 elements: ");
          
        for (i = 0; i < set2.size(); i++) 
            System.out.print(set2.get(i) + " "); 
    }
      
    // Driver Code
    public static void main(String args[])
    {

2455
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

        int []arr = new int[]{ 5, 5, 1, 11 };


        int n = arr.length;
        printEqualSumSets(arr, n);
    }
}
  
// This code is contributed by
// Manish Shaw(manishshaw1)

C#

// C# program to print 
// equal sum sets of array.
using System;
using System.Linq;
using System.Collections.Generic;
  
class GFG
{
    // Function to print equal 
    // sum sets of array.
    static void printEqualSumSets(int []arr, 
                                  int n)
    {
        int i, currSum, sum = 0;
          
        // Finding sum of array elements
        for (i = 0; i < arr.Length; i++)
            sum += arr[i];
      
        // Check sum is even or odd. 
        // If odd then array cannot 
        // be partitioned. Print -1 
        // and return.
        if ((sum & 1) == 1) 
        {
            Console.Write("-1");
            return;
        }
      
        // Divide sum by 2 to find
        // sum of two possible subsets.
        int k = sum >> 1;
      
        // Boolean DP table to store 
        // result of states.
        // dp[i,j] = true if there is a
        // subset of elements in first i 

2456
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

        // elements of array that has sum


        // equal to j.
        bool [,]dp = new bool[n + 1, k + 1];
      
        // If number of elements are zero, 
        // then no sum can be obtained.
        for (i = 1; i <= k; i++)
            dp[0, i] = false;
      
        // Sum 0 can be obtained by 
        // not selecting any element.
        for (i = 0; i <= n; i++)
            dp[i, 0] = true;
      
        // Fill the DP table 
        // in bottom up manner.
        for (i = 1; i <= n; i++) 
        {
            for (currSum = 1; currSum <= k; currSum++) 
            {
      
                // Excluding current element.
                dp[i, currSum] = dp[i - 1, currSum];
      
                // Including current element
                if (arr[i - 1] <= currSum)
                    dp[i, currSum] = dp[i, currSum] | 
                    dp[i - 1, currSum - arr[i - 1]];
            }
        }
      
        // Required sets set1 and set2.
        List<int> set1 = new List<int>();
        List<int> set2 = new List<int>();
      
        // If partition is not possible
        // print -1 and return.
        if (!dp[n, k]) 
        {
            Console.Write("-1\n");
            return;
        }
      
        // Start from last 
        // element in dp table.
        i = n;
        currSum = k;
      

2457
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

        while (i > 0 && currSum >= 0) 


        {
      
            // If current element does 
            // not contribute to k, then 
            // it belongs to set 2.
            if (dp[i - 1, currSum]) 
            {
                i--;
                set2.Add(arr[i]);
            }
      
            // If current element contribute
            // to k then it belongs to set 1.
            else if (dp[i - 1, currSum - arr[i - 1]]) 
            {
                i--;
                currSum -= arr[i];
                set1.Add(arr[i]);
            }
        }
      
        // Print elements of both the sets.
        Console.Write("Set 1 elements: ");
        for (i = 0; i < set1.Count; i++) 
            Console.Write(set1[i] + " ");
              
        Console.Write("\nSet 2 elements: ");
          
        for (i = 0; i < set2.Count; i++) 
            Console.Write(set2[i] + " "); 
    }
      
    // Driver Code.
    static void Main()
    {
        int []arr = { 5, 5, 1, 11 };
        int n = arr.Length;
        printEqualSumSets(arr, n);
    }
}
// This cide is contributed by
// Manish Shaw(manishshaw1)

Output :

Set 1 elements: 1 5 5

2458
Chapter 341. Print equal sum sets of array (Partition Problem) | Set 2

Set 2 elements: 11

Time Complexity: O(n*k), where k = sum(arr) / 2


Auxiliary Space: O(n*k)
Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/print-equal-sum-sets-array-partition-problem-set-2/

2459
Chapter 342

Print equal sum sets of array


(Partition problem) | Set 1

Print equal sum sets of array (Partition problem) | Set 1 - GeeksforGeeks


Given an array arr[]. Determine whether it is possible to split the array into two sets such
that the sum of elements in both the sets is equal. If it is possible, then print both the sets.
If it is not possible then output -1.
Examples :

Input : arr = {5, 5, 1, 11}


Output : Set 1 = {5, 5, 1},
Set 2 = {11}
Sum of both the sets is 11 and equal.

Input : arr = {1, 5, 3}


Output : -1
No partitioning results in equal sum sets.

We have already discussed a solution in Partition Problem to find if array can be partitioned
or not. In this post, we print two sets are also printed. We post pass two vectors set1 and
set2 and two sum variables sum1 and sum2. Traverse the array recursively. At every array
position there are two choices: either add current element to set 1 or to set 2. Recursively
call for both the conditions and update the vectors set1 and set2 accordingly. If current
element is added to set 1 then add current element to sum1 and insert it in vector set 1.
Repeat same if current elememt is included in set 2. At the end of array traversal compare
both the sums. If both the sums are equal then print both the vectors otherwise backtrack
to check other possibilities.
Implementation:

2460
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

C++

// CPP program to print equal sum two subsets of


// an array if it can be partitioned into subsets.
#include <bits/stdc++.h>
using namespace std;
  
/// Function to print the equal sum sets of the array.
void printSets(vector<int> set1, vector<int> set2)
{
    int i;
  
    /// Print set 1.
    for (i = 0; i < set1.size(); i++) {
        cout << set1[i] << " ";
    }
  
    cout << "\n";
  
    /// Print set 2.
    for (i = 0; i < set2.size(); i++) {
        cout << set2[i] << " ";
    }
}
  
/// Utility function to find the sets of the array which
/// have equal sum.
bool findSets(int arr[], int n, vector<int>& set1,
              vector<int>& set2, int sum1, int sum2, int pos)
{
  
    /// If entire array is traversed, compare both the sums.
    if (pos == n) {
  
        /// If sums are equal print both sets and return 
        /// true to show sets are found.
        if (sum1 == sum2) {
            printSets(set1, set2);
            return true;
        }
  
        /// If sums are not equal then return sets are not
        /// found.
        else 
            return false;        
    }
  
    /// Add current element to set 1.

2461
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

    set1.push_back(arr[pos]);
  
    /// Recursive call after adding current element to set 1.
    bool res = findSets(arr, n, set1, set2, sum1 + arr[pos], 
                                             sum2, pos + 1);
  
    /// If this inclusion results in equal sum sets partition 
    /// then return true to show desired sets are found.
    if (res)
        return res;
  
    /// If not then backtrack by removing current element 
    /// from set1 and include it in set 2.
    set1.pop_back();
    set2.push_back(arr[pos]);
  
    /// Recursive call after including current element to set 2.
    return findSets(arr, n, set1, set2, sum1, sum2 + arr[pos],
                                                    pos + 1);
}
  
/// Return true if array arr can be partitioned
/// into two equal sum sets or not.
bool isPartitionPoss(int arr[], int n)
{
    /// Calculate sum of elements in array.
    int sum = 0;
  
    for (int i = 0; i < n; i++) 
        sum += arr[i];    
  
    /// If sum is odd then array cannot be
    /// partitioned.
    if (sum % 2 != 0) 
        return false;    
  
    /// Declare vectors to store both the sets.
    vector<int> set1, set2;
  
    /// Find both the sets.
    return findSets(arr, n, set1, set2, 0, 0, 0);
}
  
// Driver code
int main()
{
    int arr[] = { 5, 5, 1, 11 };
    int n = sizeof(arr) / sizeof(arr[0]);

2462
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

    if (!isPartitionPoss(arr, n)) {


        cout << "-1";
    }
    return 0;
}

Java

// Java program to print equal sum two subsets


// of an array if it can be partitioned into
// subsets.
import java.io.*;
import java.util.*;
   
public class GFG {
      
    // Declare Lists to store both
    // the sets.
    static List<Integer> set1 = new ArrayList<Integer>();
    static List<Integer> set2 = new ArrayList<Integer>();
    /// Function to print the equal sum sets
    // of the array.
    static void printSets()
    {
        int i;
       
        /// Print set 1.
        for (i = 0; i < set1.size(); i++) {
            System.out.print(set1.get(i) + " ");
        }
       
        System.out.println();
       
        /// Print set 2.
        for (i = 0; i < set2.size(); i++) {
            System.out.print(set2.get(i) + " ");
        }
    }
       
    // Utility function to find the sets
    // of the array which have equal sum.
    static boolean findSets(Integer []arr, int n,
                       int sum1, int sum2, 
                                  int pos)
    {
       
        // If entire array is traversed,
        // compare both the sums.

2463
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

        if (pos == n) {
       
            // If sums are equal print
            // both sets and return true 
            // to show sets are found.
            if (sum1 == sum2) {
                printSets();
                return true;
            }
       
            // If sums are not equal 
            // then return sets are not
            // found.
            else
                return false;     
        }
       
        // Add current element to set 1.
        set1.add(arr[pos]);
       
        // Recursive call after adding 
        // current element to set 1.
        boolean res = findSets(arr, n, sum1 + arr[pos], 
                              sum2, pos + 1);
       
        // If this inclusion results in
        // equal sum sets partition then
        // return true to show desired 
        // sets are found.
        if (res == true)
            return res;
       
        // If not then backtrack by removing
        // current element from set1 and 
        // include it in set 2.
        set1.remove(set1.size() - 1);
        set2.add(arr[pos]);
       
        // Recursive call after including
        // current element to set 2.
        return findSets(arr, n, sum1, sum2 
                    + arr[pos], pos + 1);
    }
       
    // Return true if array arr can be
    // partitioned into two equal sum 
    // sets or not.
    static boolean isPartitionPoss(Integer []arr,

2464
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

                                    int n)
    {
        // Calculate sum of elements in 
        // array.
        int sum = 0;
       
        for (int i = 0; i < n; i++) 
            sum += arr[i]; 
       
        // If sum is odd then array cannot
        // be partitioned.
        if (sum % 2 != 0) 
            return false; 
  
        /// Find both the sets.
        return findSets(arr, n, 0, 0, 0);
    }
       
    // Driver code
    public static void main(String args[])
    {
        Integer []arr = { 5, 5, 1, 11 };
        int n = arr.length;
        if (isPartitionPoss(arr, n) == false)
        {
            System.out.print("-1");
        }
    }
}
   
// This code is contributed by Manish Shaw
// (manishshaw1)

Python3

# Python3 program to print equal sum two subsets of


# an array if it can be partitioned into subsets.
  
# Function to print the equal sum sets of the array.
def printSets(set1, set2) :
  
    # Print set 1.
    for i in range(0, len(set1)) :
        print ("{} ".format(set1[i]), end=""); 
    print ("")
  
    # Print set 2.
    for i in range(0, len(set2)) :

2465
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

        print ("{} ".format(set2[i]), end=""); 


    print ("")
  
# Utility function to find the sets of the 
# array which have equal sum.
def findSets(arr, n, set1, set2, sum1, sum2, pos) :
  
  
    # If entire array is traversed, compare both 
    # the sums.
    if (pos == n) : 
          
        # If sums are equal print both sets and
        # return true to show sets are found.
        if (sum1 == sum2) :
            printSets(set1, set2)
            return True
  
        # If sums are not equal then return 
        # sets are not found.
        else :
            return False     
  
    # Add current element to set 1.
    set1.append(arr[pos])
  
    # Recursive call after adding current
    # element to set 1.
    res = findSets(arr, n, set1, set2, 
               sum1 + arr[pos], sum2, pos + 1)
  
    # If this inclusion results in equal sum
    # sets partition then return true to show 
    # desired sets are found.
    if (res) :
        return res
  
    # If not then backtrack by removing current
    # element from set1 and include it in set 2.
    set1.pop()
    set2.append(arr[pos])
  
    # Recursive call after including current 
    # element to set 2.
    return findSets(arr, n, set1, set2, sum1, 
                     sum2 + arr[pos], pos + 1)
  
# Return true if array arr can be partitioned

2466
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

# into two equal sum sets or not.


def isPartitionPoss(arr, n) :
  
    # Calculate sum of elements in array.
    sum = 0
  
    for i in range(0, n):
        sum += arr[i]
  
    # If sum is odd then array cannot be
    # partitioned.
    if (sum % 2 != 0) :
        return False
  
    # Declare vectors to store both the sets.
    set1 = []
    set2 = []
  
    # Find both the sets.
    return findSets(arr, n, set1, set2, 0, 0, 0)
  
# Driver code
arr = [5, 5, 1, 11]
n = len(arr)
if (isPartitionPoss(arr, n) == False) :
    print ("-1")
      
# This code is contributed by Manish Shaw
# (manishshaw1)

C#

// C# program to print equal sum two subsets


// of an array if it can be partitioned into
// subsets.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
  
class GFG {
      
    /// Function to print the equal sum sets
    // of the array.
    static void printSets(List<int> set1, 
                             List<int> set2)
    {
        int i;

2467
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

      
        /// Print set 1.
        for (i = 0; i < set1.Count; i++) {
            Console.Write(set1[i] + " ");
        }
      
        Console.WriteLine();
      
        /// Print set 2.
        for (i = 0; i < set2.Count; i++) {
            Console.Write(set2[i] + " ");
        }
    }
      
    // Utility function to find the sets
    // of the array which have equal sum.
    static bool findSets(int []arr, int n,
                       ref List<int> set1, 
                       ref List<int> set2,
                       int sum1, int sum2, 
                                  int pos)
    {
      
        // If entire array is traversed,
        // compare both the sums.
        if (pos == n) {
      
            // If sums are equal print
            // both sets and return true 
            // to show sets are found.
            if (sum1 == sum2) {
                printSets(set1, set2);
                return true;
            }
      
            // If sums are not equal 
            // then return sets are not
            // found.
            else
                return false;     
        }
      
        // Add current element to set 1.
        set1.Add(arr[pos]);
      
        // Recursive call after adding 
        // current element to set 1.
        bool res = findSets(arr, n, ref set1,

2468
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

                   ref set2, sum1 + arr[pos], 


                              sum2, pos + 1);
      
        // If this inclusion results in
        // equal sum sets partition then
        // return true to show desired 
        // sets are found.
        if (res == true)
            return res;
      
        // If not then backtrack by removing
        // current element from set1 and 
        // include it in set 2.
        set1.RemoveAt(set1.Count - 1);
        set2.Add(arr[pos]);
      
        // Recursive call after including
        // current element to set 2.
        return findSets(arr, n, ref set1, 
                     ref set2, sum1, sum2 
                    + arr[pos], pos + 1);
    }
      
    // Return true if array arr can be
    // partitioned into two equal sum 
    // sets or not.
    static bool isPartitionPoss(int []arr,
                                    int n)
    {
        // Calculate sum of elements in 
        // array.
        int sum = 0;
      
        for (int i = 0; i < n; i++) 
            sum += arr[i]; 
      
        // If sum is odd then array cannot
        // be partitioned.
        if (sum % 2 != 0) 
            return false; 
      
        // Declare Lists to store both
        // the sets.
        List<int> set1 = new List<int>();
        List<int> set2 = new List<int>();
      
        /// Find both the sets.
        return findSets(arr, n, ref set1,

2469
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

                      ref set2, 0, 0, 0);


    }
      
    // Driver code
    public static void Main()
    {
        int []arr = { 5, 5, 1, 11 };
        int n = arr.Length;
        if (isPartitionPoss(arr, n) == false)
        {
            Console.Write("-1");
        }
    }
}
  
// This code is contributed by Manish Shaw
// (manishshaw1)

PHP

<?php
// PHP program to print equal sum 
// two subsets of an array if it 
// can be partitioned into subsets.
  
// Function to print the equal 
// sum sets of the array.
function printSets($set1, $set2)
{
    $i = 0;
      
    // Print set 1.
    for ($i = 0; $i < count($set1); $i++) 
    {
        echo ($set1[$i]." ");
    }
  
    echo ("\n");
  
    // Print set 2.
    for ($i = 0; $i < count($set2); $i++) 
    {
        echo ($set2[$i]." ");
    }
}
  
// Utility function to find the 
// sets of the array which have

2470
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

// equal sum.
function findSets($arr, $n, &$set1, 
                     &$set2, $sum1, 
                     $sum2, $pos)
{
  
    // If entire array is traversed,
    // compare both the sums.
    if ($pos == $n) 
    {
  
        // If sums are equal print
        // both sets and return 
        // true to show sets are found.
        if ($sum1 == $sum2) 
        {
            printSets($set1, $set2);
            return true;
        }
  
        // If sums are not equal then 
        // return sets are not found.
        else
            return false;     
    }
  
    // Add current element to set 1.
    array_push($set1, $arr[$pos]);
  
    // Recursive call after adding 
    // current element to set 1.
    $res = findSets($arr, $n, $set1, $set2, 
                    $sum1 + $arr[$pos], 
                    $sum2, $pos + 1);
  
    // If this inclusion results in
    // equal sum sets partition then  
    // return true to show desired 
    // sets are found.
    if ($res)
        return $res;
  
    // If not then backtrack by 
    // removing current element 
    // from set1 and include it 
    // in set 2.
    array_pop($set1);
    array_push($set2, $arr[$pos]);

2471
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

  
    // Recursive call after including
    // current element to set 2.
    return findSets($arr, $n, $set1, $set2, 
                    $sum1, $sum2 + $arr[$pos],
                                    $pos + 1);
}
  
// Return true if array arr 
// can be partitioned into
// two equal sum sets or not.
function isPartitionPoss($arr, $n)
{
    // Calculate sum of 
    // elements in array.
    $sum = 0;
  
    for ($i = 0; $i < $n; $i++) 
        $sum += $arr[$i]; 
  
    // If sum is odd then array 
    // cannot be partitioned.
    if ($sum % 2 != 0) 
        return false; 
  
    // Declare vectors to
    // store both the sets.
    $set1 = array();
    $set2 = array();
  
    // Find both the sets.
    return findSets($arr, $n, $set1,
                    $set2, 0, 0, 0);
}
  
// Driver code
$arr= array( 5, 5, 1, 11 );
$n = count($arr);
if (isPartitionPoss($arr, $n) == false)
    echo ("-1");
  
// This code is contributed by 
// Manish Shaw (manishshaw1)
?>

Output:

2472
Chapter 342. Print equal sum sets of array (Partition problem) | Set 1

5 5 1
11

Time Complexity: Exponential O(2^n)


Auxiliary Space: O(n) (Without considering size of function call stack)
Print equal sum sets of array (Partition Problem) | Set 2
Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/print-equal-sum-sets-array-partition-problem/

2473
Chapter 343

Print n terms of
Newman-Conway Sequence

Print n terms of Newman-Conway Sequence - GeeksforGeeks


Newman-Conway numbers is the one which generates the following integer sequence.
1 1 2 2 3 4 4 4 5 6 7 7….. and follows below recursive formula.

P(n) = P(P(n - 1)) + P(n - P(n - 1))

Given a number n then print n terms of Newman-Conway Sequence


Examples:

Input : 13
Output : 1 1 2 2 3 4 4 4 5 6 7 7 8

Input : 20
Output : 1 1 2 2 3 4 4 4 5 6 7 7 8 8 8 8 9 10 11 12

C++

// C++ Program to print n terms 


// of Newman-Conway Sequence
#include <bits/stdc++.h>
using namespace std;
  
// Function to find 
// the n-th element
void sequence(int n) 

2474
Chapter 343. Print n terms of Newman-Conway Sequence

{
    // Declare array to store sequence
    int f[n + 1];
    f[0] = 0;
    f[1] = 1;
    f[2] = 1;
      
    cout << f[1] << " " << f[2] << " ";
      
    for (int i = 3; i <= n; i++) {
        f[i] = f[f[i - 1]] + f[i - f[i - 1]];        
        cout << f[i] << " ";
    }
}
  
// Driver Program
int main()
{    
    int n = 13;    
    sequence(n);    
    return 0;
}

Java

// Java Program to print n terms


// of Newman-Conway Sequence
  
class GFG 
{
    // Function to find 
    // the n-th element
    public static void sequence(int n) 
    {
        // Declare array to store sequence
        int f[] = new int[n + 1];
          
        f[0] = 0;
        f[1] = 1;
        f[2] = 1;
          
        System.out.print( f[1] + " " + f[2] + " ");
        for (int i = 3; i <= n; i++) 
        {
            f[i] = f[f[i - 1]] + f[i - f[i - 1]];     
            System.out.print(f[i] + " ");
        }
    }

2475
Chapter 343. Print n terms of Newman-Conway Sequence

      
    //Driver code
    public static void main(String []args)
    {
        int n = 13 ;
        sequence(n);
    }
  
}
  
  
// This program is contributed 
// by upendra singh bartwal

Python3

# Python Program to print n terms


# of Newman-Conway Sequence
  
def sequence(n):
  
    # Function to find
    # the n-th element
    # Declare array to store sequence
    f = [0, 1, 1]
  
    print(f[1], end=" "),
    print(f[2], end=" "),
    for i in range(3,n+1):
        f.append( f[f[i - 1]] + f[i - f[i - 1]])
        print(f[i], end=" "),
          
# driver code
n = 13
sequence(n)
  
# This code is contributed
# by upendra singh bartwal

C#

// C# Program to print n terms


// of Newman-Conway Sequence
using System;
class GFG 
{
    // Function to find 

2476
Chapter 343. Print n terms of Newman-Conway Sequence

    // the n-th element


    public static void sequence(int n) 
    {
        // Declare array to store sequence
        int []f = new int[n + 1];
          
        f[0] = 0;
        f[1] = 1;
        f[2] = 1;
          
        Console.Write( f[1] + " " + f[2] + " ");
        for (int i = 3; i <= n; i++) 
        {
            f[i] = f[f[i - 1]] + f[i - f[i - 1]]; 
            Console.Write(f[i] + " ");
        }
    }
      
    // Driver code
    public static void Main()
    {
        int n = 13 ;
        sequence(n);
    }
  
}
  
  
// This program is contributed 
// by vt_m.

PHP

<?php
// PHP Program to print n terms 
// of Newman-Conway Sequence
  
// Function to find 
// the n-th element
function sequence($n) 
{
      
    // Declare array to 
    // store sequence
    $f=array(0);
  
    $f[0] = 0;
    $f[1] = 1;

2477
Chapter 343. Print n terms of Newman-Conway Sequence

    $f[2] = 1;
      
    echo $f[1] , " " , $f[2] , " ";
      
    for ($i = 3; $i <= $n; $i++) 
    {
        $f[$i] = $f[$f[$i - 1]] + 
                 $f[$i - $f[$i - 1]];     
        echo $f[$i], " ";
    }
}
  
// Driver Code

    $n = 13; 
    sequence($n); 
    return 0;
}
  
// This code is contributed by nitin mittal.
?>

Output :

1 1 2 2 3 4 4 4 5 6 7 7 8

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/print-n-terms-newman-conway-sequence/

2478
Chapter 344

Printing Items in 0/1 Knapsack

Printing Items in 0/1 Knapsack - GeeksforGeeks


Given weights and values of n items, put these items in a knapsack of capacity W to get the
maximum total value in the knapsack. In other words, given two integer arrays val[0..n-1]
and wt[0..n-1] which represent values and weights associated with n items respectively. Also
given an integer W which represents knapsack capacity, find out the items such that sum of
the weights of those items of given subset is smaller than or equal to W. You cannot break
an item, either pick the complete item, or don’t pick it (0-1 property).
Prerequisite : 0/1 Knapsack
Examples :

Input : val[] = {60, 100, 120};


wt[] = {10, 20, 30};
W = 50;
Output : 220 //maximum value that can be obtained
30 20 //weights 20 and 30 are included.

Input : val[] = {40, 100, 50, 60};


wt[] = {20, 10, 40, 30};
W = 60;
Output : 200
30 20 10

Approach :
Let val[] = {1, 4, 5, 7}, wt[] = {1, 3, 4, 5}
W = 7.
The 2d knapsack table will look like :

2479
Chapter 344. Printing Items in 0/1 Knapsack

Start backtracking from K[n][W].Here K[n][W] is 9.


Since, this value comes from the top (shown by grey arrow), the item in this row is not
included. Go vertically upward in the table without including this in the knapsack. Now,
this value K[n-1][W] which is 9 doesn’t come from the top which means the item in this row
is included and go vertically up and then left by the weight of the included item ( shown
by black arrow). Continuing this process include weights 3 and 4 with total value 9 in the
knapsack.
C++

// CPP code for Dynamic Programming based 


// solution for 0-1 Knapsack problem
#include <bits/stdc++.h>
  
// A utility function that returns maximum of two integers
int max(int a, int b) { return (a > b) ? a : b; }
  
// Prints the items which are put in a knapsack of capacity W
void printknapSack(int W, int wt[], int val[], int n)
{
    int i, w;
    int K[n + 1][W + 1];
  
    // Build table K[][] in bottom up manner
    for (i = 0; i <= n; i++) {
        for (w = 0; w <= W; w++) {
            if (i == 0 || w == 0)
                K[i][w] = 0;
            else if (wt[i - 1] <= w)
                K[i][w] = max(val[i - 1] + 

2480
Chapter 344. Printing Items in 0/1 Knapsack

                    K[i - 1][w - wt[i - 1]], K[i - 1][w]);


            else
                K[i][w] = K[i - 1][w];
        }
    }
  
    // stores the result of Knapsack
    int res = K[n][W];    
    printf("%d\n", res);
      
    w = W;
    for (i = n; i > 0 && res > 0; i--) {
          
        // either the result comes from the top
        // (K[i-1][w]) or from (val[i-1] + K[i-1]
        // [w-wt[i-1]]) as in Knapsack table. If
        // it comes from the latter one/ it means 
        // the item is included.
        if (res == K[i - 1][w]) 
            continue;        
        else {
  
            // This item is included.
            printf("%d ", wt[i - 1]);
              
            // Since this weight is included its 
            // value is deducted
            res = res - val[i - 1];
            w = w - wt[i - 1];
        }
    }
}
  
// Driver code
int main()
{
    int val[] = { 60, 100, 120 };
    int wt[] = { 10, 20, 30 };
    int W = 50;
    int n = sizeof(val) / sizeof(val[0]);
      
    printknapSack(W, wt, val, n);
      
    return 0;
}

Java

2481
Chapter 344. Printing Items in 0/1 Knapsack

// Java code for Dynamic Programming based


// solution for 0-1 Knapsack problem
  
class GFG {
      
    // A utility function that returns 
    // maximum of two integers
    static int max(int a, int b) 
    {
        return (a > b) ? a : b;
    }
  
    // Prints the items which are put 
    // in a knapsack of capacity W
    static void printknapSack(int W, int wt[], 
                             int val[], int n)
    {
        int i, w;
        int K[][] = new int[n + 1][W + 1];
  
        // Build table K[][] in bottom up manner
        for (i = 0; i <= n; i++) {
            for (w = 0; w <= W; w++) {
                if (i == 0 || w == 0)
                    K[i][w] = 0;
                else if (wt[i - 1] <= w)
                    K[i][w] = Math.max(val[i - 1] + 
                              K[i - 1][w - wt[i - 1]], K[i - 1][w]);
                else
                    K[i][w] = K[i - 1][w];
            }
        }
  
        // stores the result of Knapsack
        int res = K[n][W];
        System.out.println(res);
  
        w = W;
        for (i = n; i > 0 && res > 0; i--) {
  
            // either the result comes from the top
            // (K[i-1][w]) or from (val[i-1] + K[i-1]
            // [w-wt[i-1]]) as in Knapsack table. If
            // it comes from the latter one/ it means
            // the item is included.
            if (res == K[i - 1][w])
                continue;
            else {

2482
Chapter 344. Printing Items in 0/1 Knapsack

  
                // This item is included.
                System.out.print(wt[i - 1] + " ");
  
                // Since this weight is included its
                // value is deducted
                res = res - val[i - 1];
                w = w - wt[i - 1];
            }
        }
    }
  
    // Driver code
    public static void main(String arg[])
    {
        int val[] = { 60, 100, 120 };
        int wt[] = { 10, 20, 30 };
        int W = 50;
        int n = val.length;
  
        printknapSack(W, wt, val, n);
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python3 code for Dynamic Programming


# based solution for 0-1 Knapsack problem
  
# Prints the items which are put in a 
# knapsack of capacity W
def printknapSack(W, wt, val, n):
    K = [[0 for w in range(W + 1)]
            for i in range(n + 1)]
              
    # Build table K[][] in bottom
    # up manner
    for i in range(n + 1):
        for w in range(W + 1):
            if i == 0 or w == 0:
                K[i][w] = 0
            elif wt[i - 1] <= w:
                K[i][w] = max(val[i - 1] 
                  + K[i - 1][w - wt[i - 1]],
                               K[i - 1][w])
            else:

2483
Chapter 344. Printing Items in 0/1 Knapsack

                K[i][w] = K[i - 1][w]


  
    # stores the result of Knapsack
    res = K[n][W]
    print(res)
      
    w = W
    for i in range(n, 0, -1):
        if res <= 0:
            break
        # either the result comes from the
        # top (K[i-1][w]) or from (val[i-1]
        # + K[i-1] [w-wt[i-1]]) as in Knapsack
        # table. If it comes from the latter
        # one/ it means the item is included.
        if res == K[i - 1][w]:
            continue
        else:
  
            # This item is included.
            print(wt[i - 1])
              
            # Since this weight is included
            # its value is deducted
            res = res - val[i - 1]
            w = w - wt[i - 1]
  
# Driver code
val = [ 60, 100, 120 ]
wt = [ 10, 20, 30 ]
W = 50
n = len(val)
      
printknapSack(W, wt, val, n)
  
# This code is contributed by Aryan Garg.

Output:

220
30 20

Improved By : aryan21

Source
https://www.geeksforgeeks.org/printing-items-01-knapsack/

2484
Chapter 345

Printing Longest Bitonic


Subsequence

Printing Longest Bitonic Subsequence - GeeksforGeeks


The Longest Bitonic Subsequence problem is to find the longest subsequence of a given
sequence such that it is first increasing and then decreasing. A sequence, sorted in increasing
order is considered Bitonic with the decreasing part as empty. Similarly, decreasing order
sequence is considered Bitonic with the increasing part as empty.
Examples:

Input: [1, 11, 2, 10, 4, 5, 2, 1]


Output: [1, 2, 10, 4, 2, 1] OR [1, 11, 10, 5, 2, 1]
OR [1, 2, 4, 5, 2, 1]

Input: [12, 11, 40, 5, 3, 1]


Output: [12, 11, 5, 3, 1] OR [12, 40, 5, 3, 1]

Input: [80, 60, 30, 40, 20, 10]


Output: [80, 60, 30, 20, 10] OR [80, 60, 40, 20, 10]

In previous post, we have discussed about Longest Bitonic Subsequence problem. However,
the post only covered code related to finding maximum sum of increasing subsequence, but
not to the construction of subsequence. In this post, we will discuss how to construct Longest
Bitonic Subsequence itself.
Let arr[0..n-1] be the input array. We define vector LIS such that LIS[i] is itself is a vector
that stores Longest Increasing Subsequence of arr[0..i] that ends with arr[i]. Therefore for
an index i, LIS[i] can be recursively written as –

2485
Chapter 345. Printing Longest Bitonic Subsequence

LIS[0] = {arr[O]}
LIS[i] = {Max(LIS[j])} + arr[i] where j < i and arr[j] < arr[i]
= arr[i], if there is no such j

We also define a vector LDS such that LDS[i] is itself is a vector that stores Longest De-
creasing Subsequence of arr[i..n] that starts with arr[i]. Therefore for an index i, LDS[i] can
be recursively written as –

LDS[n] = {arr[n]}
LDS[i] = arr[i] + {Max(LDS[j])} where j > i and arr[j] < arr[i]
= arr[i], if there is no such j

For example, for array [1 11 2 10 4 5 2 1],

LIS[0]: 1
LIS[1]: 1 11
LIS[2]: 1 2
LIS[3]: 1 2 10
LIS[4]: 1 2 4
LIS[5]: 1 2 4 5
LIS[6]: 1 2
LIS[7]: 1

LDS[0]: 1
LDS[1]: 11 10 5 2 1
LDS[2]: 2 1
LDS[3]: 10 5 2 1
LDS[4]: 4 2 1
LDS[5]: 5 2 1
LDS[6]: 2 1
LDS[7]: 1

Therefore, Longest Bitonic Subsequence can be

LIS[1] + LDS[1] = [1 11 10 5 2 1] OR
LIS[3] + LDS[3] = [1 2 10 5 2 1] OR
LIS[5] + LDS[5] = [1 2 4 5 2 1]

Below is C++ implementation of above idea –

/* Dynamic Programming solution to print Longest


   Bitonic Subsequence */

2486
Chapter 345. Printing Longest Bitonic Subsequence

#include <bits/stdc++.h>
using namespace std;
  
// Utility function to print Longest Bitonic
// Subsequence
void print(vector<int>& arr, int size)
{
    for(int i = 0; i < size; i++)
        cout << arr[i] << " ";
}
  
// Function to construct and print Longest
// Bitonic Subsequence
void printLBS(int arr[], int n)
{
    // LIS[i] stores the length of the longest
    // increasing subsequence ending with arr[i]
    vector<vector<int>> LIS(n);
  
    // initialize LIS[0] to arr[0]
    LIS[0].push_back(arr[0]);
  
    // Compute LIS values from left to right
    for (int i = 1; i < n; i++)
    {
        // for every j less than i
        for (int j = 0; j < i; j++)
        {
            if ((arr[j] < arr[i]) &&
                (LIS[j].size() > LIS[i].size()))
                LIS[i] = LIS[j];
        }
        LIS[i].push_back(arr[i]);
    }
  
    /* LIS[i] now stores Maximum Increasing
       Subsequence of arr[0..i] that ends with
       arr[i] */
  
    // LDS[i] stores the length of the longest
    // decreasing subsequence starting with arr[i]
    vector<vector<int>> LDS(n);
  
    // initialize LDS[n-1] to arr[n-1]
    LDS[n - 1].push_back(arr[n - 1]);
  
    // Compute LDS values from right to left
    for (int i = n - 2; i >= 0; i--)

2487
Chapter 345. Printing Longest Bitonic Subsequence

    {
        // for every j greater than i
        for (int j = n - 1; j > i; j--)
        {
            if ((arr[j] < arr[i]) &&
                (LDS[j].size() > LDS[i].size()))
                LDS[i] = LDS[j];
        }
        LDS[i].push_back(arr[i]);
    }
  
    // reverse as vector as we're inserting at end
    for (int i = 0; i < n; i++)
        reverse(LDS[i].begin(), LDS[i].end());
  
    /* LDS[i] now stores Maximum Decreasing Subsequence
       of arr[i..n] that starts with arr[i] */
  
    int max = 0;
    int maxIndex = -1;
  
    for (int i = 0; i < n; i++)
    {
        // Find maximum value of size of LIS[i] + size
        // of LDS[i] - 1
        if (LIS[i].size() + LDS[i].size() - 1 > max)
        {
            max = LIS[i].size() + LDS[i].size() - 1;
            maxIndex = i;
        }
    }
  
    // print all but last element of LIS[maxIndex] vector
    print(LIS[maxIndex], LIS[maxIndex].size() - 1);
  
    // print all elements of LDS[maxIndex] vector
    print(LDS[maxIndex], LDS[maxIndex].size());
}
  
// Driver program
int main()
{
    int arr[] = { 1, 11, 2, 10, 4, 5, 2, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    printLBS(arr, n);
    return 0;
}

2488
Chapter 345. Printing Longest Bitonic Subsequence

Output:

1 11 10 5 2 1

Time complexity of above Dynamic Programming solution is O(n2 ).


Auxiliary space used by the program is O(n2 ).

Source

https://www.geeksforgeeks.org/printing-longest-bitonic-subsequence/

2489
Chapter 346

Printing Longest Common


Subsequence | Set 2 (Printing
All)

Printing Longest Common Subsequence | Set 2 (Printing All) - GeeksforGeeks


Given two sequences, print all longest subsequence present in both of them.
Examples:

Input:
string X = "AGTGATG"
string Y = "GTTAG"
Output:
GTAG
GTTG

Input:
string X = "AATCC"
string Y = "ACACG"
Output:
ACC
AAC

Input:
string X = "ABCBDAB"
string Y = "BDCABA"
Output:
BCAB
BCBA
BDAB

2490
Chapter 346. Printing Longest Common Subsequence | Set 2 (Printing All)

We have discussed Longest Common Subsequence (LCS) problem here. The function dis-
cussed there was mainly to find the length of LCS. We have also discussed how to print the
longest subsequence here. But as LCS for two strings is not unique, in this post we will
print out all the possible solutions to LCS problem.
Following is detailed algorithm to print the all LCS.
We construct L[m+1][n+1] table as discussed in the previous post and traverse the 2D array
starting from L[m][n]. For current cell L[i][j] in the matrix,
a) If the last characters of X and Y are same (i.e. X[i-1] == Y[j-1]), then the charcater must
be present in all LCS of substring X[0…i-1] and Y[0..j-1]. We simply recurse for L[i-1][j-1]
in the matrix and append current character to all LCS possible of substring X[0…i-2] and
Y[0..j-2].
b) If the last characters of X and Y are not same (i.e. X[i-1] != Y[j-1]), then LCS can be
constructed from either top side of the matrix (i.e. L[i-1][j]) or from left side of matrix (i.e.
L[i][j-1]) depending upon which value is greater. If both the values are equal(i.e. L[i-1][j]
== L[i][j-1]), then it will be constructed from both sides of matrix. So based on values at
L[i-1][j] and L[i][j-1], we go in direction of greater value or go in both directions if the values
are equal.
Below is recursive C++ implementation of above idea –

/* Dynamic Programming implementation of LCS problem */


#include <bits/stdc++.h>
using namespace std;
  
// Maximum string length
#define N 100
  
int L[N][N];
  
/* Returns set containing all LCS for X[0..m-1], Y[0..n-1] */
set<string> findLCS(string X, string Y, int m, int n)
{
    // construct a set to store possible LCS
    set<string> s;
  
    // If we reaches end of either string, return
    // a empty set
    if (m == 0 || n == 0)
    {
        s.insert("");
        return s;
    }
  
    // If the last characters of X and Y are same
    if (X[m - 1] == Y[n - 1])
    {

2491
Chapter 346. Printing Longest Common Subsequence | Set 2 (Printing All)

        // recurse for X[0..m-2] and Y[0..n-2] in


        // the matrix
        set<string> tmp = findLCS(X, Y, m - 1, n - 1);
  
        // append current character to all possible LCS
        // of substring X[0..m-2] and Y[0..n-2].
        for (string str : tmp)
            s.insert(str + X[m - 1]);
    }
  
    // If the last characters of X and Y are not same
    else
    {
        // If LCS can be constructed from top side of
        // the matrix, recurse for X[0..m-2] and Y[0..n-1]
        if (L[m - 1][n] >= L[m][n - 1])
            s = findLCS(X, Y, m - 1, n);
  
        // If LCS can be constructed from left side of
        // the matrix, recurse for X[0..m-1] and Y[0..n-2]
        if (L[m][n - 1] >= L[m - 1][n])
        {
            set<string> tmp = findLCS(X, Y, m, n - 1);
  
            // merge two sets if L[m-1][n] == L[m][n-1]
            // Note s will be empty if L[m-1][n] != L[m][n-1]
            s.insert(tmp.begin(), tmp.end());
        }
    }
    return s;
}
  
/* Returns length of LCS for X[0..m-1], Y[0..n-1] */
int LCS(string X, string Y, int m, int n)
{
    // Build L[m+1][n+1] in bottom up fashion
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
            else if (X[i - 1] == Y[j - 1])
                L[i][j] = L[i - 1][j - 1] + 1;
            else
                L[i][j] = max(L[i - 1][j], L[i][j - 1]);
        }
    }

2492
Chapter 346. Printing Longest Common Subsequence | Set 2 (Printing All)

    return L[m][n];
}
  
/* Driver program to test above function */
int main()
{
    string X = "AGTGATG";
    string Y = "GTTAG";
    int m = X.length();
    int n = Y.length();
  
    cout << "LCS length is " << LCS(X, Y, m, n) << endl;
  
    set<string> s = findLCS(X, Y, m, n);
  
    for (string str : s)
        cout << str << endl;
  
    return 0;
}

Output:

GTAG
GTTG

References: Wikibooks – Reading out all LCSs

Source

https://www.geeksforgeeks.org/printing-longest-common-subsequence-set-2-printing/

2493
Chapter 347

Printing Maximum Sum


Increasing Subsequence

Printing Maximum Sum Increasing Subsequence - GeeksforGeeks


The Maximum Sum Increasing Subsequence problem is to find the maximum sum subse-
quence of a given sequence such that all elements of the subsequence are sorted in increasing
order.
Examples:

Input: [1, 101, 2, 3, 100, 4, 5]


Output: [1, 2, 3, 100]

Input: [3, 4, 5, 10]


Output: [3, 4, 5, 10]

Input: [10, 5, 4, 3]
Output: [10]

Input: [3, 2, 6, 4, 5, 1]
Output: [3, 4, 5]

In previous post, we have discussed about Maximum Sum Increasing Subsequence problem.
However, the post only covered code related to finding maximum sum of increasing subse-
quence, but not to the construction of subsequence. In this post, we will discuss how to
construct Maximum Sum Increasing Subsequence itself.
Let arr[0..n-1] be the input array. We define vector L such that L[i] is itself is a vector that
stores Maximum Sum Increasing Subsequence of arr[0..i] that ends with arr[i]. Therefore
for an index i, L[i] can be recursively written as

2494
Chapter 347. Printing Maximum Sum Increasing Subsequence

L[0] = {arr[0]}
L[i] = {MaxSum(L[j])} + arr[i] where j < i and arr[j] < arr[i]
= arr[i], if there is no j such that arr[j] < arr[i]

For example, for array [3, 2, 6, 4, 5, 1],

L[0]: 3
L[1]: 2
L[2]: 3 6
L[3]: 3 4
L[4]: 3 4 5
L[5]: 1

Below is C++ implementation of above idea –

/* Dynamic Programming solution to construct


   Maximum Sum Increasing Subsequence */
#include <iostream>
#include <vector>
using namespace std;
  
// Utility function to calculate sum of all
// vector elements
int findSum(vector<int> arr)
{
    int sum = 0;
    for (int i: arr)
        sum += i;
    return sum;
}
  
// Function to construct Maximum Sum Increasing
// Subsequence
void printMaxSumIS(int arr[], int n)
{
    // L[i] - The Maximum Sum Increasing
    // Subsequence that ends with arr[i]
    vector <vector<int> > L(n);
  
    // L[0] is equal to arr[0]
    L[0].push_back(arr[0]);
  
    // start from index 1
    for (int i = 1; i < n; i++)
    {

2495
Chapter 347. Printing Maximum Sum Increasing Subsequence

        // for every j less than i


        for (int j = 0; j < i; j++)
        {
            /* L[i] = {MaxSum(L[j])} + arr[i]
            where j < i and arr[j] < arr[i] */
            if ((arr[i] > arr[j]) &&
                (findSum(L[i]) < findSum(L[j])))
                L[i] = L[j];
        }
  
        // L[i] ends with arr[i]
        L[i].push_back(arr[i]);
  
        // L[i] now stores Maximum Sum Increasing
        // Subsequence of arr[0..i] that ends with
        // arr[i]
    }
  
    vector<int> res = L[0];
  
    // find max
    for (vector<int> x : L)
        if (findSum(x) > findSum(res))
            res = x;
  
    // max will contain result
    for (int i : res)
        cout << i << " ";
    cout << endl;
}
  
// Driver function
int main()
{
    int arr[] = { 3, 2, 6, 4, 5, 1 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    // construct and print Max Sum IS of arr
    printMaxSumIS(arr, n);
  
    return 0;
}

Output:

3 4 5

2496
Chapter 347. Printing Maximum Sum Increasing Subsequence

We can optimize above DP solution by removing findSum() function. Instead, we can


maintain another vector/array to store sum of maximum sum increasing subsequence that
ends with arr[i]. The implementation can be seen here.
Time complexity of above Dynamic Programming solution is O(n2 ).
Auxiliary space used by the program is O(n2 ).

Source

https://www.geeksforgeeks.org/printing-maximum-sum-increasing-subsequence/

2497
Chapter 348

Printing Shortest Common


Supersequence

Printing Shortest Common Supersequence - GeeksforGeeks


Given two strings X and Y, print the shortest string that has both X and Y as subsequences.
If multiple shortest supersequence exists, print any one of them.
Examples:

Input: X = "AGGTAB", Y = "GXTXAYB"


Output: "AGXGTXAYB" OR "AGGXTXAYB"
OR Any string that represents shortest
supersequence of X and Y

Input: X = "HELLO", Y = "GEEK"


Output: "GEHEKLLO" OR "GHEEKLLO"
OR Any string that represents shortest
supersequence of X and Y

We have discussed how to print length of shortest possible supersequence for two given
strings here. In this post, we print the shortest supersequence.
We have already discussed below algorithm to find length of shortest supersequence in
previous post-

Let X[0..m-1] and Y[0..n-1] be two strings and m and be respective


lengths.

if (m == 0) return n;
if (n == 0) return m;

2498
Chapter 348. Printing Shortest Common Supersequence

// If last characters are same, then add 1 to result and


// recur for X[]
if (X[m-1] == Y[n-1])
return 1 + SCS(X, Y, m-1, n-1);

// Else find shortest of following two


// a) Remove last character from X and recur
// b) Remove last character from Y and recur
else return 1 + min( SCS(X, Y, m-1, n), SCS(X, Y, m, n-1) );

The following table shows steps followed by the above algorithm if we solve it in bottom-up
manner using Dynamic Programming for strings X = “AGGTAB” and Y = “GXTX-
AYB”,

Using the DP solution matrix, we can easily print shortest supersequence of two strings by
following below steps –

We start from the bottom-right most cell of the matrix and


push characters in output string based on below rules-

2499
Chapter 348. Printing Shortest Common Supersequence

1. If the characters corresponding to current cell (i, j)


in X and Y are same, then the character is part of shortest
supersequence. We append it in output string and move
diagonally to next cell (i.e. (i - 1, j - 1)).

2. If the characters corresponding to current cell (i, j)


in X and Y are different, we have two choices -

If matrix[i - 1][j] > matrix[i][j - 1],


we add character corresponding to current
cell (i, j) in string Y in output string
and move to the left cell i.e. (i, j - 1)
else
we add character corresponding to current
cell (i, j) in string X in output string
and move to the top cell i.e. (i - 1, j)

3. If string Y reaches its end i.e. j = 0, we add remaining


characters of string X in the output string
else if string X reaches its end i.e. i = 0, we add
remaining characters of string Y in the output string.

Below is C++ implementation of above idea –

/* A dynamic programming based C++ program print


   shortest supersequence of two strings */
#include <bits/stdc++.h>
using namespace std;
  
// returns shortest supersequence of X and Y
string printShortestSuperSeq(string X, string Y)
{
    int m = X.length();
    int n = Y.length();
  
    // dp[i][j] contains length of shortest supersequence
    // for X[0..i-1] and Y[0..j-1]
    int dp[m + 1][n + 1];
  
    // Fill table in bottom up manner
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
            // Below steps follow recurrence relation
            if(i == 0)
                dp[i][j] = j;
            else if(j == 0)

2500
Chapter 348. Printing Shortest Common Supersequence

                dp[i][j] = i;
            else if(X[i - 1] == Y[j - 1])
                dp[i][j] = 1 + dp[i - 1][j - 1];
            else
                dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]);
        }
    }
  
    // Following code is used to print shortest supersequence
  
    // dp[m][n] stores the length of the shortest supersequence
    // of X and Y
    int index = dp[m][n];
  
    // string to store the shortest supersequence
    string str;
  
    // Start from the bottom right corner and one by one
    // push characters in output string
    int i = m, j = n;
    while (i > 0 && j > 0)
    {
        // If current character in X and Y are same, then
        // current character is part of shortest supersequence
        if (X[i - 1] == Y[j - 1])
        {
            // Put current character in result
            str.push_back(X[i - 1]);
  
            // reduce values of i, j and index
            i--, j--, index--;
        }
  
        // If current character in X and Y are different
        else if (dp[i - 1][j] > dp[i][j - 1])
        {
            // Put current character of Y in result
            str.push_back(Y[j - 1]);
  
            // reduce values of j and index
            j--, index--;
        }
        else
        {
            // Put current character of X in result
            str.push_back(X[i - 1]);
  
            // reduce values of i and index

2501
Chapter 348. Printing Shortest Common Supersequence

            i--, index--;
        }
    }
  
    // If Y reaches its end, put remaining characters
    // of X in the result string
    while (i > 0)
    {
        str.push_back(X[i - 1]);
        i--, index--;
    }
  
    // If X reaches its end, put remaining characters
    // of Y in the result string
    while (j > 0)
    {
        str.push_back(Y[j - 1]);
        j--, index--;
    }
  
    // reverse the string and return it
    reverse(str.begin(), str.end());
    return str;
}
  
// Driver program to test above function
int main()
{
    string X = "AGGTAB";
    string Y = "GXTXAYB";
  
    cstr << printShortestSuperSeq(X, Y);
  
    return 0;
}

Output:

AGXGTXAYB

Time complexity of above solution is O(n2 ).


Auxiliary space used by the program is O(n2 ).

Source

https://www.geeksforgeeks.org/print-shortest-common-supersequence/

2502
Chapter 349

Printing brackets in Matrix


Chain Multiplication Problem

Printing brackets in Matrix Chain Multiplication Problem - GeeksforGeeks


Prerequisite : Dynamic Programming | Set 8 (Matrix Chain Multiplication)
Given a sequence of matrices, find the most efficient way to multiply these matrices together.
The problem is not actually to perform the multiplications, but merely to decide in which
order to perform the multiplications.
We have many options to multiply a chain of matrices because matrix multiplication is
associative. In other words, no matter how we parenthesize the product, the result will be
the same. For example, if we had four matrices A, B, C, and D, we would have:

(ABC)D = (AB)(CD) = A(BCD) = ....

However, the order in which we parenthesize the product affects the number of simple arith-
metic operations needed to compute the product, or the efficiency. For example, suppose A
is a 10 × 30 matrix, B is a 30 × 5 matrix, and C is a 5 × 60 matrix. Then,

(AB)C = (10×30×5) + (10×5×60) = 1500 + 3000 = 4500 operations


A(BC) = (30×5×60) + (10×30×60) = 9000 + 18000 = 27000 operations.

Clearly the first parenthesization requires less number of operations.


Given an array p[] which represents the chain of matrices such that the ith matrix Ai is of
dimension p[i-1] x p[i]. We need to write a function MatrixChainOrder() that should return
the minimum number of multiplications needed to multiply the chain.

Input: p[] = {40, 20, 30, 10, 30}


Output: Optimal parenthesization is ((A(BC))D)
Optimal cost of parenthesization is 26000

2503
Chapter 349. Printing brackets in Matrix Chain Multiplication Problem

There are 4 matrices of dimensions 40x20, 20x30, 30x10 and 10x30.


Let the input 4 matrices be A, B, C and D. The minimum number of
multiplications are obtained by putting parenthesis in following way
(A(BC))D --> 20*30*10 + 40*20*10 + 40*10*30

Input: p[] = {10, 20, 30, 40, 30}


Output: Optimal parenthesization is (((AB)C)D)
Optimal cost of parenthesization is 30000
There are 4 matrices of dimensions 10x20, 20x30, 30x40 and 40x30.
Let the input 4 matrices be A, B, C and D. The minimum number of
multiplications are obtained by putting parenthesis in following way
((AB)C)D --> 10*20*30 + 10*30*40 + 10*40*30

Input: p[] = {10, 20, 30}


Output: Optimal parenthesization is (AB)
Optimal cost of parenthesization is 6000
There are only two matrices of dimensions 10x20 and 20x30. So there
is only one way to multiply the matrices, cost of which is 10*20*30

This problem is mainly an extension of previous post. In the previous post, we have discussed
algorithm for finding optimal cost only. Here we need print parenthssization also.
The idea is to store optimal break point for every subexpression (i, j) in a 2D array
bracket[n][n]. Once we have bracket array us constructed, we can print parenthesization
using below code.

// Prints parenthesization in subexpression (i, j)


printParenthesis(i, j, bracket[n][n], name)
{
// If only one matrix left in current segment
if (i == j)
{
print name;
name++;
return;
}

print "(";

// Recursively put brackets around subexpression


// from i to bracket[i][j].
printParenthesis(i, bracket[i][j], bracket, name);

// Recursively put brackets around subexpression


// from bracket[i][j] + 1 to j.
printParenthesis(bracket[i][j]+1, j, bracket, name);

2504
Chapter 349. Printing brackets in Matrix Chain Multiplication Problem

print ")";
}

Below is C++ implementation of above steps.

   
// C++ program to print optimal parenthesization
// in matrix chain multiplication.
#include<bits/stdc++.h>
using namespace std;
  
// Function for printing the optimal
// parenthesization of a matrix chain product
void printParenthesis(int i, int j, int n,
                      int *bracket, char &name)
{
    // If only one matrix left in current segment
    if (i == j)
    {
        cout << name++;
        return;
    }
  
    cout << "(";
  
    // Recursively put brackets around subexpression
    // from i to bracket[i][j].
    // Note that "*((bracket+i*n)+j)" is similar to
    // bracket[i][j]
    printParenthesis(i, *((bracket+i*n)+j), n,
                     bracket, name);
  
    // Recursively put brackets around subexpression
    // from bracket[i][j] + 1 to j.
    printParenthesis(*((bracket+i*n)+j) + 1, j,
                     n, bracket, name);
    cout << ")";
}
  
// Matrix Ai has dimension p[i-1] x p[i] for i = 1..n
// Please refer below article for details of this
// function
// https://goo.gl/k6EYKj
void matrixChainOrder(int p[], int n)
{
    /* For simplicity of the program, one extra
       row and one extra column are allocated in
        m[][]. 0th row and 0th column of m[][]

2505
Chapter 349. Printing brackets in Matrix Chain Multiplication Problem

        are not used */


    int m[n][n];
  
    // bracket[i][j] stores optimal break point in
    // subexpression from i to j.
    int bracket[n][n];
  
    /* m[i,j] = Minimum number of scalar multiplications
    needed to compute the matrix A[i]A[i+1]...A[j] =
    A[i..j] where dimension of A[i] is p[i-1] x p[i] */
  
    // cost is zero when multiplying one matrix.
    for (int i=1; i<n; i++)
        m[i][i] = 0;
  
    // L is chain length.
    for (int L=2; L<n; L++)
    {
        for (int i=1; i<n-L+1; i++)
        {
            int j = i+L-1;
            m[i][j] = INT_MAX;
            for (int k=i; k<=j-1; k++)
            {
                // q = cost/scalar multiplications
                int q = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
                if (q < m[i][j])
                {
                    m[i][j] = q;
  
                    // Each entry bracket[i,j]=k shows
                    // where to split the product arr
                    // i,i+1....j for the minimum cost.
                    bracket[i][j] = k;
                }
            }
        }
    }
  
    // The first matrix is printed as 'A', next as 'B',
    // and so on
    char name = 'A';
  
    cout << "Optimal Parenthesization is : ";
    printParenthesis(1, n-1, n, (int *)bracket, name);
    cout << "nOptimal Cost is : " << m[1][n-1];
}
  

2506
Chapter 349. Printing brackets in Matrix Chain Multiplication Problem

// Driver code
int main()
{
    int arr[] = {40, 20, 30, 10, 30};
    int n = sizeof(arr)/sizeof(arr[0]);
    matrixChainOrder(arr, n);
    return 0;
}

Output:

Optimal Parenthesization: ((A(BC))D)


Minimum Cost of Multiplication: 26000

Time Complexity: O(n^3)


Auxiliary Space: O(n^2)

Source

https://www.geeksforgeeks.org/printing-brackets-matrix-chain-multiplication-problem/

2507
Chapter 350

Printing longest Increasing


consecutive subsequence

Printing longest Increasing consecutive subsequence - GeeksforGeeks


Given n elements, write a program that prints the longest increasing subsequence whose
adjacent element difference is one.
Examples:

Input : a[] = {3, 10, 3, 11, 4, 5, 6, 7, 8, 12}


Output : 3 4 5 6 7 8
Explanation: 3, 4, 5, 6, 7, 8 is the longest increasing subsequence whose adjacent
element differs by one.
Input : a[] = {6, 7, 8, 3, 4, 5, 9, 10}
Output : 6 7 8 9 10
Explanation: 6, 7, 8, 9, 10 is the longest increasing subsequence

We have discussed how to find length of Longest Increasing consecutive subsequence. To


print the subsequence, we store index of last element. Then we print consecutive elements
ending with last element.
Given below is the implementation of the above approach:

// CPP program to find length of the


// longest increasing subsequence
// whose adjacent element differ by 1
#include <bits/stdc++.h>
using namespace std;
  
// function that returns the length of the
// longest increasing subsequence
// whose adjacent element differ by 1

2508
Chapter 350. Printing longest Increasing consecutive subsequence

void longestSubsequence(int a[], int n)


{
    // stores the index of elements
    unordered_map<int, int> mp;
  
    // stores the length of the longest
    // subsequence that ends with a[i]
    int dp[n];
    memset(dp, 0, sizeof(dp));
  
    int maximum = INT_MIN;
  
    // iterate for all element
    int index = -1;
    for (int i = 0; i < n; i++) {
  
        // if a[i]-1 is present before i-th index
        if (mp.find(a[i] - 1) != mp.end()) {
  
            // last index of a[i]-1
            int lastIndex = mp[a[i] - 1] - 1;
  
            // relation
            dp[i] = 1 + dp[lastIndex];
        }
        else
            dp[i] = 1;
  
        // stores the index as 1-index as we need to
        // check for occurrence, hence 0-th index
        // will not be possible to check
        mp[a[i]] = i + 1;
  
        // stores the longest length
        if (maximum < dp[i]) {
            maximum = dp[i];
            index = i;
        }
    }
  
    // We know last element of sequence is
    // a[index]. We also know that length
    // of subsequence is "maximum". So We
    // print these many consecutive elements
    // starting from "a[index] - maximum + 1"
    // to a[index].
    for (int curr = a[index] - maximum + 1;
         curr <= a[index]; curr++)

2509
Chapter 350. Printing longest Increasing consecutive subsequence

        cout << curr << " ";


}
  
// Driver Code
int main()
{
    int a[] = { 3, 10, 3, 11, 4, 5, 6, 7, 8, 12 };
    int n = sizeof(a) / sizeof(a[0]);
    longestSubsequence(a, n);
    return 0;
}

Output:

3 4 5 6 7 8

Time Complexity : O(n)


Auxiliary Space : O(n)

Source

https://www.geeksforgeeks.org/printing-longest-increasing-consecutive-subsequence/

2510
Chapter 351

Probability of Knight to remain


in the chessboard

Probability of Knight to remain in the chessboard - GeeksforGeeks


Given an NxN chessboard and a Knight at position (x,y). The Knight has to take exactly
K steps, where at each step it chooses any of the 8 directions uniformly at random. What
is the probability that the Knight remains in the chessboard after taking K steps, with the
condition that it can’t enter the board again once it leaves it.
Examples:

Let's take:
8x8 chessboard,
initial position of the knight : (0, 0),
number of steps : 1
At each step, the Knight has 8 different positions to choose from.

If it starts from (0, 0), after taking one step it will lie inside the
board only at 2 out of 8 positions, and will lie outside at other positions.
So, the probability is 2/8 = 0.25

One thing that we can observe is that at every step the Knight has 8 choices to choose from.
Suppose, the Knight has to take k steps and after taking the Kth step the knight reaches
(x,y). There are 8 different positions from where the Knight can reach to (x,y) in one step,
and they are: (x+1,y+2), (x+2,y+1), (x+2,y-1), (x+1,y-2), (x-1,y-2), (x-2,y-1), (x-2,y+1),
(x-1,y+2).
What if we already knew the probabilities of reaching these 8 positions after K-1 steps? Then,
the final probability after K steps will simply be equal to the (Σ probability of reaching each
of these 8 positions after K-1 steps)/8;
Here we are dividing by 8 because each of these 8 positions have 8 choices and position (x,y)
is one of the choice.

2511
Chapter 351. Probability of Knight to remain in the chessboard

For the positions that lie outside the board, we will either take their probabilities as 0 or
simply neglect it.
Since, we need to keep track of the probabilities at each position for every number of steps,
we need Dynamic Programming to solve this problem.
We are going to take an array dp[x][y][steps] which will store the probability of reaching
(x,y) after (steps) number of moves.
Base case : if number of steps is 0, then the probability that the Knight will remain inside
the board is 1.
Here is the implementation :

C++

// C++ program to find the probability of the


// Knight to remain inside the chessboard after
// taking exactly K number of steps
#include <bits/stdc++.h>
using namespace std;
  
// size of the chessboard
#define N 8
  
// direction vector for the Knight
int dx[] = { 1, 2, 2, 1, -1, -2, -2, -1 };
int dy[] = { 2, 1, -1, -2, -2, -1, 1, 2 };
  
// returns true if the knight is inside the chessboard
bool inside(int x, int y)
{
    return (x >= 0 and x < N and y >= 0 and y < N);
}
  
// Bottom up approach for finding the probability to
// go out of chessboard.
double findProb(int start_x, int start_y, int steps)
{
    // dp array
    double dp1[N][N][N];
  
    // for 0 number of steps, each position
    // will have probability 1
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
            dp1[i][j][0] = 1;
  
    // for every number of steps s
    for (int s = 1; s <= steps; ++s)

2512
Chapter 351. Probability of Knight to remain in the chessboard

    {
        // for every position (x,y) after
        // s number of steps
        for (int x = 0; x < N; ++x)
        {
            for (int y = 0; y < N; ++y)
            {
                double prob = 0.0;
  
                // for every position reachable from (x,y)
                for (int i = 0; i < 8; ++i)
                {
                    int nx = x + dx[i];
                    int ny = y + dy[i];
  
                    // if this position lie inside the board
                    if (inside(nx, ny))
                        prob += dp1[nx][ny][s-1] / 8.0;
                }
  
                // store the result
                dp1[x][y][s] = prob;
            }
        }
    }
  
    // return the result
    return dp1[start_x][start_y][steps];
}
  
// Driver program
int main()
{
    // number of steps
    int K = 3;
  
    cout << findProb(0, 0, K) << endl;
  
    return 0;
}

Java

// Java program to find the probability 


// of the Knight to remain inside the 
// chessboard after taking exactly K 
// number of steps
class GFG {

2513
Chapter 351. Probability of Knight to remain in the chessboard

      
    // size of the chessboard
    static final int N = 8;
  
    // direction vector for the Knight
    static int dx[] = { 1, 2, 2, 1, 
                     -1, -2, -2, -1 };
                       
    static int dy[] = { 2, 1, -1, -2,
                       -2, -1, 1, 2 };
  
    // returns true if the knight is 
    // inside the chessboard
    static boolean inside(int x, int y)
    {
        return (x >= 0 && x < N && 
                       y >= 0 && y < N);
    }
  
    // Bottom up approach for finding 
    // the probability to go out of 
    // chessboard.
    static double findProb(int start_x, 
                  int start_y, int steps)
    {
          
        // dp array
        double dp1[][][] = new double[N][N][N];
  
        // for 0 number of steps, each position
        // will have probability 1
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
                dp1[i][j][0] = 1;
  
        // for every number of steps s
        for (int s = 1; s <= steps; ++s) {
              
            // for every position (x, y) after
            // s number of steps
            for (int x = 0; x < N; ++x) {
                  
                for (int y = 0; y < N; ++y) {
                      
                    double prob = 0.0;
  
                    // for every position reachable 
                    // from (x, y)

2514
Chapter 351. Probability of Knight to remain in the chessboard

                    for (int i = 0; i < 8; ++i) {


                        int nx = x + dx[i];
                        int ny = y + dy[i];
  
                        // if this position lie 
                        // inside the board
                        if (inside(nx, ny))
                            prob += dp1[nx][ny][s - 1] 
                                                / 8.0;
                    }
  
                    // store the result
                    dp1[x][y][s] = prob;
                }
            }
        }
  
        // return the result
        return dp1[start_x][start_y][steps];
    }
      
    // Driver code
    public static void main(String[] args)
    {
          
        // number of steps
        int K = 3;
  
        System.out.println(findProb(0, 0, K));
    }
}
  
// This code is contributed by Anant Agarwal.

Python3

# Python3 program to find the probability of


# the Knight to remain inside the chessboard 
# after taking exactly K number of steps
  
# size of the chessboard
N = 8
  
# Direction vector for the Knight
dx = [ 1, 2, 2, 1, -1, -2, -2, -1 ]
dy = [ 2, 1, -1, -2, -2, -1, 1, 2 ]
  
# returns true if the knight

2515
Chapter 351. Probability of Knight to remain in the chessboard

# is inside the chessboard


def inside(x, y):
  
    return (x >= 0 and x < N and y >= 0 and y < N)
  
# Bottom up approach for finding the 
# probability to go out of chessboard.
def findProb(start_x, start_y, steps):
  
    # dp array
    dp1 = [[[0 for i in range(N + 1)]
               for j in range(N + 1)]
               for k in range(N + 1)]
  
    # For 0 number of steps, each 
    # position will have probability 1
    for i in range(N):
          
        for j in range(N):
            dp1[i][j][0] = 1
  
    # for every number of steps s
    for s in range(1, steps + 1):
      
        # for every position (x,y) after
        # s number of steps
        for x in range(N):
              
            for y in range(N):
                prob = 0.0
  
                # For every position reachable from (x,y)
                for i in range(8):
                    nx = x + dx[i]
                    ny = y + dy[i]
  
                    # if this position lie inside the board
                    if (inside(nx, ny)):
                        prob += dp1[nx][ny][s-1] / 8.0
                  
                # store the result
                dp1[x][y][s] = prob
              
    # return the result
    return dp1[start_x][start_y][steps]
  
# Driver code
  

2516
Chapter 351. Probability of Knight to remain in the chessboard

# number of steps
K = 3
print(findProb(0, 0, K))
  
  
# This code is contributed by Anant Agarwal.

C#

// C# program to find the 


// probability of the Knight 
// to remain inside the 
// chessboard after taking  
// exactly K number of steps
using System;
  
class GFG
{
  
    // size of the chessboard
    static int N = 8;
  
    // direction vector 
    // for the Knight
    static int []dx = {1, 2, 2, 1, 
                      -1, -2, -2, -1};
                      
    static int []dy = {2, 1, -1, -2,
                      -2, -1, 1, 2};
  
    // returns true if the 
    // knight is inside the 
    // chessboard
    static bool inside(int x, int y)
    {
        return (x >= 0 && x < N && 
                y >= 0 && y < N);
    }
  
    // Bottom up approach for
    // finding the probability 
    // to go out of chessboard.
    static double findProb(int start_x, 
                           int start_y, 
                           int steps)
    {
          
        // dp array

2517
Chapter 351. Probability of Knight to remain in the chessboard

        double [,,]dp1 = new double[N, N, N];


  
        // for 0 number of steps, 
        // each position will have
        // probability 1
        for (int i = 0; i < N; ++i)
            for (int j = 0; j < N; ++j)
                dp1[i, j, 0] = 1;
  
        // for every number 
        // of steps s
        for (int s = 1; s <= steps; ++s) 
        {
              
            // for every position (x, y) 
            // after s number of steps
            for (int x = 0; x < N; ++x) 
            {
                for (int y = 0; y < N; ++y) 
                {
                    double prob = 0.0;
  
                    // for every position 
                    // reachable from (x, y)
                    for (int i = 0; i < 8; ++i)
                    {
                        int nx = x + dx[i];
                        int ny = y + dy[i];
  
                        // if this position lie 
                        // inside the board
                        if (inside(nx, ny))
                            prob += dp1[nx, ny, s - 1] 
                                                / 8.0;
                    }
  
                    // store the result
                    dp1[x, y, s] = prob;
                }
            }
        }
  
        // return the result
        return dp1[start_x, 
                   start_y, steps];
    }
      
    // Driver code

2518
Chapter 351. Probability of Knight to remain in the chessboard

    static void Main()


    {
        // number of steps
        int K = 3;
  
        Console.WriteLine(findProb(0, 0, K));
    }
}
  
// This code is contributed
// by Sam007

Output:

0.125

Time Complexity: O(NxNxKx8) which is O(NxNxK), where N is the size of the board
and K is the number of steps.
Space Complexity: O(NxNxK)
Improved By : Sam007

Source

https://www.geeksforgeeks.org/probability-knight-remain-chessboard/

2519
Chapter 352

Probability of getting at least K


heads in N tosses of Coins

Probability of getting at least K heads in N tosses of Coins - GeeksforGeeks


Given N number of coins, the task is to find probability of getting at least K number of
heads after tossing all the N coins simultaneously.
Example :

Suppose we have 3 unbiased coins and we have to


find the probability of getting at least 2 heads,
so there are 23 = 8 ways to toss these
coins, i.e.,
HHH, HHT, HTH, HTT, THH, THT, TTH, TTT

Out of which there are 4 set which contain at


least 2 Heads i.e.,
HHH, HHT, HH, THH

So the probability is 4/8 or 0.5

The probability of exactly k success in n trials with probability p of success in


any trial is given by:

So Probability ( getting at least 4 heads )=

2520
Chapter 352. Probability of getting at least K heads in N tosses of Coins

Method 1 (Naive)
A Naive approach is to store the value of factorial in dp[] array and call it directly whenever
it is required. But the problem of this approach is that we can only able to store it up to
certain value, after that it will lead to overflow.
Below is the implementation of above approach

C++

// Naive approach in C++ to find probability of


// at least k heads
#include<bits/stdc++.h>
using namespace std;
#define MAX 21
  
double fact[MAX];
  
// Returns probability of getting at least k
// heads in n tosses.
double probability(int k, int n)
{
    double ans = 0;
    for (int i = k; i <= n; ++i)
  
        // Probability of getting exactly i
        // heads out of n heads
        ans += fact[n] / (fact[i] * fact[n - i]);
  
    // Note: 1 << n = pow(2, n)
    ans = ans / (1LL << n);
    return ans;
}
  
void precompute()
{
    // Preprocess all factorial only upto 19,
    // as after that it will overflow
    fact[0] = fact[1] = 1;

2521
Chapter 352. Probability of getting at least K heads in N tosses of Coins

  
    for (int i = 2; i < 20; ++i)
        fact[i] = fact[i - 1] * i;
}
  
// Drive code
int main()
{
    precompute();
  
    // Probability of getting 2 head out of 3 coins
    cout << probability(2, 3) << "\n";
  
    // Probability of getting 3 head out of 6 coins
    cout << probability(3, 6) <<"\n";
  
    // Probability of getting 12 head out of 18 coins
    cout << probability(12, 18);
  
    return 0;
}

Java

// JAVA Code for Probability of getting 


// atleast K heads in N tosses of Coins
class GFG {
      
    public static double fact[];
       
    // Returns probability of getting at least k
    // heads in n tosses.
    public static double probability(int k, int n)
    {
        double ans = 0;
        for (int i = k; i <= n; ++ i)
       
            // Probability of getting exactly i
            // heads out of n heads
            ans += fact[n] / (fact[i] * fact[n-i]);
       
        // Note: 1 << n = pow(2, n)
        ans = ans / (1 << n);
        return ans;
    }
       
    public static void precompute()
    {

2522
Chapter 352. Probability of getting at least K heads in N tosses of Coins

        // Preprocess all factorial only upto 19,


        // as after that it will overflow
        fact[0] = fact[1] = 1;
       
        for (int i = 2; i < 20; ++i)
            fact[i] = fact[i - 1] * i;
    }
       
    // Drive code
    public static void main(String[] args) 
    {
        fact = new double[100];
        precompute();
       
        // Probability of getting 2 head out
        // of 3 coins
        System.out.println(probability(2, 3));
       
        // Probability of getting 3 head out
        // of 6 coins
        System.out.println(probability(3, 6));
       
        // Probability of getting 12 head out
        // of 18 coins
        System.out.println(probability(12, 18));
       
    }
 }
// This code is contributed by Arnav Kr. Mandal

C#

// C# Code for Probability of getting 


// atleast K heads in N tosses of Coins
using System;
  
class GFG 
{
      
    public static double []fact;
      
    // Returns probability of getting at least k
    // heads in n tosses.
    public static double probability(int k, int n)
    {
        double ans = 0;
        for (int i = k; i <= n; ++ i)
      

2523
Chapter 352. Probability of getting at least K heads in N tosses of Coins

            // Probability of getting exactly i


            // heads out of n heads
            ans += fact[n] / (fact[i] * fact[n - i]);
      
        // Note: 1 << n = pow(2, n)
        ans = ans / (1 << n);
        return ans;
    }
      
    public static void precompute()
    {
        // Preprocess all factorial only upto 19,
        // as after that it will overflow
        fact[0] = fact[1] = 1;
      
        for (int i = 2; i < 20; ++i)
            fact[i] = fact[i - 1] * i;
    }
      
    // Drive code
    public static void Main() 
    {
        fact = new double[100];
        precompute();
      
        // Probability of getting 2 head out
        // of 3 coins
        Console.WriteLine(probability(2, 3));
      
        // Probability of getting 3 head out
        // of 6 coins
        Console.WriteLine(probability(3, 6));
      
        // Probability of getting 12 head out
        // of 18 coins
        Console.Write(probability(12, 18));
      
    }
}
// This code is contributed by nitin mittal.

Output:

0.5
0.65625
0.118942

2524
Chapter 352. Probability of getting at least K heads in N tosses of Coins

Time Complexity: O(n) where n < 20


Auxiliary space: O(n)

Method 2 (Dynamic Programming and Log)


Another way is to use Dynamic programming and logarithm. log() is indeed useful to store
the factorial of any number without worrying about overflow. Let’s see how we use it:

At first let see how n! can be written.


n! = n * (n-1) * (n-2) * (n-3) * ... * 3 * 2 * 1

Now take log on base 2 both the sides as:


=> log(n!) = log(n) + log(n-1) + log(n-2) + ... + log(3)
+ log(2) + log(1)

Now whenever we need to find the factorial of any number, we can use
this precomputed value. For example:
Suppose if we want to find the value of nCi which can be written as:
=> nCi = n! / (i! * (n-i)! )

Taking log2() both sides as:


=> log2 (nCi) = log2 ( n! / (i! * (n-i)! ) )
=> log2 (nCi) = log2 ( n! ) - log2(i!) - log2( (n-i)! ) `

Putting dp[num] = log2 (num!), we get:


=> log2 (nCi) = dp[n] - dp[i] - dp[n-i]

But as we see in above relation there is an extra factor of 2n which


tells the probability of getting i heads, so
=> log2 (2n) = n.

We will subtract this n from above result to get the final answer:
=> Pi (log2 (nCi)) = dp[n] - dp[i] - dp[n-i] - n

Now: Pi (nCi) = 2 dp[n] - dp[i] - dp[n-i] - n

Tada! Now the questions boils down the summation of Pi for all i in
[k, n] will yield the answer which can be calculated easily without
overflow.

Below is C++ code to illustrate this:


C++

// Dynamic and Logarithm approach find probability of


// at least k heads
#include<bits/stdc++.h>

2525
Chapter 352. Probability of getting at least K heads in N tosses of Coins

using namespace std;


#define MAX 100001
  
// dp[i] is going to store Log ( i !) in base 2
double dp[MAX];
  
double probability(int k, int n)
{
    double ans = 0; // Initialize result
  
    // Iterate from k heads to n heads
    for (int i=k; i <= n; ++i)
    {
        double res = dp[n] - dp[i] - dp[n-i] - n;
        ans += pow(2.0, res);
    }
  
    return ans;
}
  
void precompute()
{
    // Preprocess all the logarithm value on base 2
    for (int i=2; i < MAX; ++i)
        dp[i] = log2(i) + dp[i-1];
}
  
// Drive code
int main()
{
    precompute();
  
    // Probability of getting 2 head out of 3 coins
    cout << probability(2, 3) << "\n";
  
    // Probability of getting 3 head out of 6 coins
    cout << probability(3, 6) << "\n";
  
    // Probability of getting 500 head out of 10000 coins
    cout << probability(500, 1000);
  
    return 0;
}

Output:

0.5

2526
Chapter 352. Probability of getting at least K heads in N tosses of Coins

0.65625
0.512613

Time Complexity: O(n)


Auxiliary space: O(n)
This approach is beneficial for large value of n ranging from 1 to 106
Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/probability-getting-least-k-heads-n-tosses-coins/

2527
Chapter 353

Probability of reaching a point


with 2 or 3 steps at a time

Probability of reaching a point with 2 or 3 steps at a time - GeeksforGeeks


A person starts walking from position X = 0, find the probability to reach exactly on X =
N if she can only take either 2 steps or 3 steps. Probability for step length 2 is given i.e. P,
probability for step length 3 is 1 – P.
Examples :

Input : N = 5, P = 0.20
Output : 0.32
Explanation :-
There are two ways to reach 5.
2+3 with probability = 0.2 * 0.8 = 0.16
3+2 with probability = 0.8 * 0.2 = 0.16
So, total probability = 0.32.

It is a simple dynamic programming problem. It is simple extension of this problem :-


count-ofdifferent-ways-express-n-sum-1-3-4
Below is the implementation of the above approach.

C++

// CPP Program to find probability to 


// reach N with P probability to take
// 2 steps (1-P) to take 3 steps
#include <bits/stdc++.h>
using namespace std;
  

2528
Chapter 353. Probability of reaching a point with 2 or 3 steps at a time

// Returns probability to reach N


float find_prob(int N, float P)
{
    double dp[N + 1];
    dp[0] = 1;
    dp[1] = 0;
    dp[2] = P;
    dp[3] = 1 - P;
    for (int i = 4; i <= N; ++i)
        dp[i] = (P)*dp[i - 2] + (1 - P) * dp[i - 3];
  
    return dp[N];
}
  
// Driver code
int main()
{
    int n = 5;
    float p = 0.2;
    cout << find_prob(n, p);
    return 0;
}

Java

// Java Program to find probability to 


// reach N with P probability to take
// 2 steps (1-P) to take 3 steps
import java.io.*;
  
class GFG {
      
    // Returns probability to reach N
    static float find_prob(int N, float P)
    {
        double dp[] = new double[N + 1];
        dp[0] = 1;
        dp[1] = 0;
        dp[2] = P;
        dp[3] = 1 - P;
      
        for (int i = 4; i <= N; ++i)
          dp[i] = (P) * dp[i - 2] +
                        (1 - P) * dp[i - 3];
      
        return ((float)(dp[N]));
    }
      

2529
Chapter 353. Probability of reaching a point with 2 or 3 steps at a time

    // Driver code


    public static void main(String args[])
    {
        int n = 5;
        float p = 0.2f;
        System.out.printf("%.2f",find_prob(n, p));
    }
}
  
  
/* This code is contributed by Nikita Tiwari.*/

Python3

# Python 3 Program to find 


# probability to reach N with
# P probability to take 2 
# steps (1-P) to take 3 steps
  
# Returns probability to reach N
def find_prob(N, P) :
      
    dp =[0] * (n + 1)
    dp[0] = 1
    dp[1] = 0
    dp[2] = P
    dp[3] = 1 - P
      
    for i in range(4, N + 1) :
        dp[i] = (P) * dp[i - 2] + (1 - P) * dp[i - 3]
  
    return dp[N]
  
# Driver code
n = 5
p = 0.2
print(round(find_prob(n, p), 2))
  
# This code is contributed by Nikita Tiwari.

C#

// C# Program to find probability to 


// reach N with P probability to take
// 2 steps (1-P) to take 3 steps
using System;
  

2530
Chapter 353. Probability of reaching a point with 2 or 3 steps at a time

class GFG {
      
    // Returns probability to reach N
    static float find_prob(int N, float P)
    {
        double []dp = new double[N + 1];
        dp[0] = 1;
        dp[1] = 0;
        dp[2] = P;
        dp[3] = 1 - P;
      
        for (int i = 4; i <= N; ++i)
        dp[i] = (P) * dp[i - 2] +
                (1 - P) * dp[i - 3];
      
        return ((float)(dp[N]));
    }
      
    // Driver code
    public static void Main()
    {
        int n = 5;
        float p = 0.2f;
        Console.WriteLine(find_prob(n, p));
    }
}
  
  
/* This code is contributed by vt_m.*/

PHP

<?php
// PHP Program to find probability to 
// reach N with P probability to take
// 2 steps (1-P) to take 3 steps
  
// Returns probability to reach N
function find_prob($N, $P)
{
    $dp;
    $dp[0] = 1;
    $dp[1] = 0;
    $dp[2] = $P;
    $dp[3] = 1 - $P;
    for ($i = 4; $i <= $N; ++$i)
        $dp[$i] = ($P) * $dp[$i - 2] + 
                  (1 - $P) * $dp[$i - 3];

2531
Chapter 353. Probability of reaching a point with 2 or 3 steps at a time

  
    return $dp[$N];
}
  
// Driver code
$n = 5;
$p = 0.2;
echo find_prob($n, $p);
  
// This code is contributed by mits.
?>

Output :

0.32

Improved By : Mithun Kumar

Source

https://www.geeksforgeeks.org/probability-reaching-point-2-3-steps-time/

2532
Chapter 354

Program for Bridge and Torch


problem

Program for Bridge and Torch problem - GeeksforGeeks


Given an array of positive distinct integer denoting the crossing time of ‘n’ people. These
‘n’ people are standing at one side of bridge. Bridge can hold at max two people at a time.
When two people cross the bridge, they must move at the slower person’s pace. Find the
minimum total time in which all persons can cross the bridge. See this puzzle to understand
more.
Note: Slower person’pace is given by larger time.

Input: Crossing Times = {10, 20, 30}


Output: 60
Explanation
1. Firstly person '1' and '2' cross the bridge
with total time about 20 min(maximum of 10, 20)
2. Now the person '1' will come back with total
time of '10' minutes.
3. Lastly the person '1' and '3' cross the bridge
with total time about 30 minutes
Hence total time incurred in whole journey will be
20 + 10 + 30 = 60

Input: Crossing Times = [1, 2, 5, 8}


Output: 15
Explanation
See this for full explanation.

The approach is to use Dynamic programming. Before getting dive into dynamic program-
minc let’s see the following observation that will be required in solving the problem.

2533
Chapter 354. Program for Bridge and Torch problem

1. When any two people cross the bridge, then the fastest person crossing time will not
be contributed in answer as both of them move with slowest person speed.
2. When some of the people will cross the river and reached the right side then only the
fastest people(smallest integer) will come back to the left side.
3. Person can only be present either left side or right side of the bridge. Thus, if we
maintain the left mask, then right mask can easily be calculated by setting the bits
‘1’ which is not present in the left mask. For instance, Right_mask = ((2n ) – 1) XOR
(left_mask).
4. Any person can easily be represented by bitmask(usually called as ‘mask’). When
ith bit of ‘mask’ is set, that means that person is present at left side of the bridge
otherwise it would be present at right side of bridge. For instance, let the mask of 6
people is 100101, which reprsents the person 1, 4, 6 are present at left side of bridge
and the person 2, 3 and 5 are present at the right side of the bridge.

// C++ program to find minimum time required to


// send people on other side of bridge
#include <bits/stdc++.h>
using namespace std;
  
/* Global dp[2^20][2] array, in dp[i][j]--
   'i' denotes mask in which 'set bits' denotes
   total people standing at left side of bridge
   and 'j' denotes the turn that represent on 
   which side we have to send people either
   from left to right(0) or from right to 
   left(1)  */
int dp[1 << 20][2];
  
/* Utility function to find total time required
   to send people to other side of bridge */
int findMinTime(int leftmask, bool turn, int arr[], int& n)
{
  
    // If all people has been transfered
    if (!leftmask)
        return 0;
  
    int& res = dp[leftmask][turn];
  
    // If we already have solved this subproblem, 
    // return the answer.
    if (~res)
        return res;
  
    // Calculate mask of right side of people
    int rightmask = ((1 << n) - 1) ^ leftmask;
  
    /* if turn == 1 means currently people are at

2534
Chapter 354. Program for Bridge and Torch problem

     right side, thus we need to transfer


     people to the left side */
    if (turn == 1) {
        int minRow = INT_MAX, person;
        for (int i = 0; i < n; ++i) {
  
            // Select one people whose time is less
            // among all others present at right
            // side
            if (rightmask & (1 << i)) {
                if (minRow > arr[i]) {
                    person = i;
                    minRow = arr[i];
                }
            }
        }
  
        // Add that person to answer and recurse for next turn
        // after initializing that person at left side
        res = arr[person] + findMinTime(leftmask | (1 << person),
                                        turn ^ 1, arr, n);
    }
    else {
  
        // __builtin_popcount() is inbuilt gcc function
        // which will count total set bits in 'leftmask'
        if (__builtin_popcount(leftmask) == 1) {
            for (int i = 0; i < n; ++i) {
  
                // Since one person is present at left
                // side, thus return that person only
                if (leftmask & (1 << i)) {
                    res = arr[i];
                    break;
                }
            }
        }
        else {
  
            // try for every pair of people by
            // sending them to right side
  
            // Initialize the result with maximum value
            res = INT_MAX;
            for (int i = 0; i < n; ++i) {
  
                // If ith person is not present then
                // skip the rest loop

2535
Chapter 354. Program for Bridge and Torch problem

                if (!(leftmask & (1 << i)))


                    continue;
  
                for (int j = i + 1; j < n; ++j) {
                    if (leftmask & (1 << j)) {
  
                        // Find maximum integer(slowest
                        // person's time)
                        int val = max(arr[i], arr[j]);
  
                        // Recurse for other people after un-setting
                        // the ith and jth bit of left-mask
                        val += findMinTime(leftmask ^ (1 << i) ^ (1 << j),
                                                       turn ^ 1, arr, n);
                        // Find minimum answer among
                        // all chosen values
                        res = min(res, val);
                    }
                }
            }
        }
    }
    return res;
}
  
// Utility function to find minimum time
int findTime(int arr[], int n)
{
    // Find the mask of 'n' peoples
    int mask = (1 << n) - 1;
  
    // Initialize all entries in dp as -1
    memset(dp, -1, sizeof(dp));
  
    return findMinTime(mask, 0, arr, n);
}
  
// Driver program
int main()
{
    int arr[] = { 10, 20, 30 };
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << findTime(arr, n);
    return 0;
}

Output

2536
Chapter 354. Program for Bridge and Torch problem

60

Time complexity:

Auxiliary space:

Source

https://www.geeksforgeeks.org/program-bridge-torch-problem/

2537
Chapter 355

Program for Fibonacci numbers

Program for Fibonacci numbers - GeeksforGeeks


The Fibonacci numbers are the numbers in the following integer sequence.
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ……..
In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence
relation

Fn = Fn-1 + Fn-2

with seed values

F0 = 0 and F1 = 1.

Given a number n, print n-th Fibonacci Number.


Examples:

2538
Chapter 355. Program for Fibonacci numbers

Input : n = 2
Output : 1

Input : n = 9
Output : 34

Write a function int fib(int n) that returns Fn . For example, if n = 0, then fib() should
return 0. If n = 1, then it should return 1. For n > 1, it should return Fn-1 + Fn-2

For n = 9
Output:34

Following are different methods to get the nth Fibonacci number.


Method 1 ( Use recursion )
A simple method that is a direct recursive implementation mathematical recurrence relation
given above.

//Fibonacci Series using Recursion


#include<stdio.h>
int fib(int n)
{
   if (n <= 1)
      return n;
   return fib(n-1) + fib(n-2);
}
  
int main ()
{
  int n = 9;
  printf("%d", fib(n));
  getchar();
  return 0;
}

Java

//Fibonacci Series using Recursion


class fibonacci
{
    static int fib(int n)
    {
    if (n <= 1)

2539
Chapter 355. Program for Fibonacci numbers

       return n;
    return fib(n-1) + fib(n-2);
    }
       
    public static void main (String args[])
    {
    int n = 9;
    System.out.println(fib(n));
    }
}
/* This code is contributed by Rajat Mishra */

Python

# Function for nth Fibonacci number


  
def Fibonacci(n):
    if n<0:
        print("Incorrect input")
    # First Fibonacci number is 0
    elif n==1:
        return 0
    # Second Fibonacci number is 1
    elif n==2:
        return 1
    else:
        return Fibonacci(n-1)+Fibonacci(n-2)
  
# Driver Program
  
print(Fibonacci(9))
  
#This code is contributed by Saket Modi

C#

// C# program for Fibonacci Series 


// using Recursion
using System; 
  
public class GFG 

    public static int Fib(int n) 
    { 
        if (n <= 1) 
        { 
            return n; 

2540
Chapter 355. Program for Fibonacci numbers

        } 
        else
        { 
            return Fib(n - 1) + Fib(n - 2); 
        } 
    } 
          
    // driver code
    public static void Main(string[] args) 
    { 
        int n = 9;
        Console.Write(Fib(n)); 
    } 

  
// This code is contributed by Sam007

PHP

<?php
// Fibonacci Series 
// using Recursion
  
// function returns 
// the Fibonacci number
function fib($n)
{
    if ($n <= 1)
        return $n;
    return fib($n - 1) + 
           fib($n - 2);
}
  
// Driver Code
$n = 9;
echo fib($n);
  
// This code is contributed by aj_36
?>

Output

34

Time Complexity: T(n) = T(n-1) + T(n-2) which is exponential.


We can observe that this implementation does a lot of repeated work (see the following
recursion tree). So this is a bad implementation for nth Fibonacci number.

2541
Chapter 355. Program for Fibonacci numbers

fib(5)
/
fib(4) fib(3)
/ /
fib(3) fib(2) fib(2) fib(1)
/ / /
fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
/
fib(1) fib(0)

Extra Space: O(n) if we consider the function call stack size, otherwise O(1).
Method 2 ( Use Dynamic Programming )
We can avoid the repeated work done is the method 1 by storing the Fibonacci numbers
calculated so far.

//Fibonacci Series using Dynamic Programming


#include<stdio.h>
  
int fib(int n)
{
  /* Declare an array to store Fibonacci numbers. */
  int f[n+2];   // 1 extra to handle case, n = 0
  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];
}
  
int main ()
{
  int n = 9;
  printf("%d", fib(n));
  getchar();
  return 0;
}

2542
Chapter 355. Program for Fibonacci numbers

Java

// Fibonacci Series using Dynamic Programming


class fibonacci
{
   static int fib(int n)
    {
    /* Declare an array to store Fibonacci numbers. */
    int f[] = new int[n+2]; // 1 extra to handle case, n = 0
    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));
    }
}
/* This code is contributed by Rajat Mishra */

Python

# Fibonacci Series using Dynamic Programming


def fibonacci(n):
      
    # Taking 1st two fibonacci nubers as 0 and 1
    FibArray = [0, 1]
      
    while len(FibArray) < n + 1: 
        FibArray.append(0) 
      
    if n <= 1:
       return n
    else:

2543
Chapter 355. Program for Fibonacci numbers

       if FibArray[n - 1] ==  0:


           FibArray[n - 1] = fibonacci(n - 1)
      
       if FibArray[n - 2] ==  0:
           FibArray[n - 2] = fibonacci(n - 2)
      
       FibArray[n] = FibArray[n - 2] + FibArray[n - 1]
    return FibArray[n]
      
print(fibonacci(9))

C#

// C# program for Fibonacci Series 


// using Dynamic Programming
using System;
class fibonacci {
      
static int fib(int n)
    {
          
        // Declare an array to 
        // store Fibonacci numbers.
        // 1 extra to handle 
        // case, n = 0
        int []f = new int[n + 2]; 
        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];
    }
      
    // Driver Code
    public static void Main ()
    {
        int n = 9;
        Console.WriteLine(fib(n));

2544
Chapter 355. Program for Fibonacci numbers

    }
}
  
// This code is contributed by anuj_67. 

PHP

<?php
//Fibonacci Series using Dynamic
// Programming
  
function fib( $n)
{
      
    /* Declare an array to store
    Fibonacci numbers. */
      
    // 1 extra to handle case,
    // n = 0
    $f = array();
    $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];
}
  
$n = 9;
echo fib($n);
  
// This code is contributed by
// anuj_67. 
?>

Output:

2545
Chapter 355. Program for Fibonacci numbers

34

Time Complexity: O(n)


Extra Space: O(n)
Method 3 ( Space Optimized Method 2 )
We can optimize the space used in method 2 by storing the previous two numbers only
because that is all we need to get the next Fibonacci number in series.

C/C++

// Fibonacci Series using Space Optimized Method


#include<stdio.h>
int fib(int n)
{
  int a = 0, b = 1, c, i;
  if( n == 0)
    return a;
  for (i = 2; i <= n; i++)
  {
     c = a + b;
     a = b;
     b = c;
  }
  return b;
}
  
int main ()
{
  int n = 9;
  printf("%d", fib(n));
  getchar();
  return 0;
}

Java

// Java program for Fibonacci Series using Space


// Optimized Method
class fibonacci
{
    static int fib(int n)
    {
        int a = 0, b = 1, c;
        if (n == 0)
            return a;
        for (int i = 2; i <= n; i++)

2546
Chapter 355. Program for Fibonacci numbers

        {
            c = a + b;
            a = b;
            b = c;
        }
        return b;
    }
  
    public static void main (String args[])
    {
        int n = 9;
        System.out.println(fib(n));
    }
}
  
// This code is contributed by Mihir Joshi

Python

# Function for nth fibonacci number - Space Optimisataion


# Taking 1st two fibonacci numbers as 0 and 1
  
def fibonacci(n):
    a = 0
    b = 1
    if n < 0:
        print("Incorrect input")
    elif n == 0:
        return a
    elif n == 1:
        return b
    else:
        for i in range(2,n+1):
            c = a + b
            a = b
            b = c
        return b
  
# Driver Program
  
print(fibonacci(9))
  
#This code is contributed by Saket Modi

C#

// C# program for Fibonacci Series 

2547
Chapter 355. Program for Fibonacci numbers

// using Space Optimized Method


using System;
  
namespace Fib 

    public class GFG 
    { 
        static int Fib(int n) 
        { 
            int a = 0, b = 1, c = 0; 
              
            // To return the first Fibonacci number 
            if (n == 0) return a; 
      
            for (int i = 2; i <= n; i++) 
            { 
                c = a + b; 
                a = b; 
                b = c; 
            } 
      
            return b; 
        } 
          
    // Driver function
    public static void Main(string[] args) 
        { 
              
            int n = 9;
            Console.Write("{0} ", Fib(n)); 
        } 
    } 

  
// This code is contributed by Sam007.

PHP

<?php
// PHP program for Fibonacci Series 
// using Space Optimized Method
  
function fib( $n)
{
    $a = 0; 
    $b = 1; 
    $c;
    $i;

2548
Chapter 355. Program for Fibonacci numbers

    if( $n == 0)
        return $a;
    for($i = 2; $i <= $n; $i++)
    {
        $c = $a + $b;
        $a = $b;
        $b = $c;
    }
    return $b;
}
  
// Driver Code
$n = 9;
echo fib($n);
  
// This code is contributed by anuj_67.
?>

Output :

34

Time Complexity: O(n)


Extra Space: O(1)
Method 4 ( Using power of the matrix {{1,1},{1,0}} )
This another O(n) which relies on the fact that if we n times multiply the matrix M =
{{1,1},{1,0}} to itself (in other words calculate power(M, n )), then we get the (n+1)th
Fibonacci number as the element at row and column (0, 0) in the resultant matrix.
The matrix representation gives the following closed expression for the Fibonacci numbers:

#include <stdio.h>
  
/* Helper function that multiplies 2 matrices F and M of size 2*2, and
  puts the multiplication result back to F[][] */
void multiply(int F[2][2], int M[2][2]);
  
/* Helper function that calculates F[][] raise to the power n and puts the
  result in F[][]
  Note that this function is designed only for fib() and won't work as general
  power function */

2549
Chapter 355. Program for Fibonacci numbers

void power(int F[2][2], int n);


  
int fib(int n)
{
  int F[2][2] = {{1,1},{1,0}};
  if (n == 0)
      return 0;
  power(F, n-1);
  
  return F[0][0];
}
  
void multiply(int F[2][2], int M[2][2])
{
  int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];
  int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
  int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
  int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];
  
  F[0][0] = x;
  F[0][1] = y;
  F[1][0] = z;
  F[1][1] = w;
}
  
void power(int F[2][2], int n)
{
  int i;
  int M[2][2] = {{1,1},{1,0}};
  
  // n - 1 times multiply the matrix to {{1,0},{0,1}}
  for (i = 2; i <= n; i++)
      multiply(F, M);
}
  
/* Driver program to test above function */
int main()
{
  int n = 9;
  printf("%d", fib(n));
  getchar();
  return 0;
}

Java

class fibonacci
{

2550
Chapter 355. Program for Fibonacci numbers

      
    static int fib(int n)
    {
    int F[][] = new int[][]{{1,1},{1,0}};
    if (n == 0)
        return 0;
    power(F, n-1);
      
       return F[0][0];
    }
       
     /* Helper function that multiplies 2 matrices F and M of size 2*2, and
     puts the multiplication result back to F[][] */
    static void multiply(int F[][], int M[][])
    {
    int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];
    int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
    int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
    int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];
       
    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
    }
  
    /* Helper function that calculates F[][] raise to the power n and puts the
    result in F[][]
    Note that this function is designed only for fib() and won't work as general
    power function */
    static void power(int F[][], int n)
    {
    int i;
    int M[][] = new int[][]{{1,1},{1,0}};
      
    // n - 1 times multiply the matrix to {{1,0},{0,1}}
    for (i = 2; i <= n; i++)
        multiply(F, M);
    }
       
    /* Driver program to test above function */
    public static void main (String args[])
    {
    int n = 9;
    System.out.println(fib(n));
    }
}
/* This code is contributed by Rajat Mishra */

2551
Chapter 355. Program for Fibonacci numbers

C#

// C# program to find fibonacci number.


using System;
  
class GFG {
      
    static int fib(int n)
    {
        int [,]F = new int[,] {{1, 1},
                               {1, 0} };
        if (n == 0)
            return 0;
        power(F, n-1);
          
        return F[0,0];
    }
      
    /* Helper function that multiplies 2 
    matrices F and M of size 2*2, and puts
    the multiplication result back to F[][] */
    static void multiply(int [,]F, int [,]M)
    {
        int x = F[0,0]*M[0,0] + F[0,1]*M[1,0];
        int y = F[0,0]*M[0,1] + F[0,1]*M[1,1];
        int z = F[1,0]*M[0,0] + F[1,1]*M[1,0];
        int w = F[1,0]*M[0,1] + F[1,1]*M[1,1];
          
        F[0,0] = x;
        F[0,1] = y;
        F[1,0] = z;
        F[1,1] = w;
    }
  
    /* Helper function that calculates F[][] 
    raise to the power n and puts the result
    in F[][] Note that this function is designed
    only for fib() and won't work as general
    power function */
    static void power(int [,]F, int n)
    {
        int i;
        int [,]M = new int[,]{{1, 1},
                              {1, 0} };
          
        // n - 1 times multiply the matrix to
        // {{1,0},{0,1}}
        for (i = 2; i <= n; i++)

2552
Chapter 355. Program for Fibonacci numbers

            multiply(F, M);
    }
      
    /* Driver program to test above function */
    public static void Main ()
    {
        int n = 9;
        Console.WriteLine(fib(n));
    }
}
  
// This code is contributed by anuj_67.

Time Complexity: O(n)


Extra Space: O(1)

Method 5 ( Optimized Method 4 )


The method 4 can be optimized to work in O(Logn) time complexity. We can do recursive
multiplication to get power(M, n) in the prevous method (Similar to the optimization done
in thispost)
C

#include <stdio.h>
  
void multiply(int F[2][2], int M[2][2]);
  
void power(int F[2][2], int n);
  
/* function that returns nth Fibonacci number */
int fib(int n)
{
  int F[2][2] = {{1,1},{1,0}};
  if (n == 0)
    return 0;
  power(F, n-1);
  return F[0][0];
}
  
/* Optimized version of power() in method 4 */
void power(int F[2][2], int n)
{
  if( n == 0 || n == 1)
      return;
  int M[2][2] = {{1,1},{1,0}};
  

2553
Chapter 355. Program for Fibonacci numbers

  power(F, n/2);
  multiply(F, F);
  
  if (n%2 != 0)
     multiply(F, M);
}
  
void multiply(int F[2][2], int M[2][2])
{
  int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];
  int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
  int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
  int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];
  
  F[0][0] = x;
  F[0][1] = y;
  F[1][0] = z;
  F[1][1] = w;
}
  
/* Driver program to test above function */
int main()
{
  int n = 9;
  printf("%d", fib(9));
  getchar();
  return 0;
}

Java

//Fibonacci Series using  Optimized Method


class fibonacci
{
    /* function that returns nth Fibonacci number */
    static int fib(int n)
    {
    int F[][] = new int[][]{{1,1},{1,0}};
    if (n == 0)
        return 0;
    power(F, n-1);
       
    return F[0][0];
    }
       
    static void multiply(int F[][], int M[][])
    {
    int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];

2554
Chapter 355. Program for Fibonacci numbers

    int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];


    int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
    int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];
      
    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
    }
       
    /* Optimized version of power() in method 4 */
    static void power(int F[][], int n)
    {
    if( n == 0 || n == 1)
      return;
    int M[][] = new int[][]{{1,1},{1,0}};
       
    power(F, n/2);
    multiply(F, F);
       
    if (n%2 != 0)
       multiply(F, M);
    }
      
    /* Driver program to test above function */ 
    public static void main (String args[])
    {
         int n = 9;
     System.out.println(fib(n));
    }
}
/* This code is contributed by Rajat Mishra */

Time Complexity: O(Logn)


Extra Space: O(Logn) if we consider the function call stack size, otherwise O(1).

Method 6 (O(Log n) Time)


Below is one more interesting recurrence formula that can be used to find n’th Fibonacci
Number in O(Log n) time.

If n is even then k = n/2:


F(n) = [2*F(k-1) + F(k)]*F(k)

If n is odd then k = (n + 1)/2


F(n) = F(k)*F(k) + F(k-1)*F(k-1)

How does this formula work?

2555
Chapter 355. Program for Fibonacci numbers

The formula can be derived from above matrix equation.

Taking determinant on both sides, we get


(-1)n = Fn+1 Fn-1 – Fn 2
Moreover, since An Am = An+m for any square matrix A, the following identities can be
derived (they are obtained form two different coefficients of the matrix product)
Fm Fn + Fm-1 Fn-1 = Fm+n-1
By putting n = n+1,
Fm Fn+1 + Fm-1 Fn = Fm+n
Putting m = n
F2n-1 = Fn 2 + Fn-1 2
F2n = (Fn-1 + Fn+1 )Fn = (2Fn-1 + Fn )Fn (Source: Wiki)
To get the formula to be proved, we simply need to do following
If n is even, we can put k = n/2
If n is odd, we can put k = (n+1)/2
Below is the implementation of above idea.

C++

// C++ Program to find n'th fibonacci Number in


// with O(Log n) arithmatic operations
#include <bits/stdc++.h>
using namespace std;
  
const int MAX = 1000;
  
// Create an array for memoization
int f[MAX] = {0};
  
// Returns n'th fuibonacci number using table f[]
int fib(int n)
{
    // Base cases
    if (n == 0)
        return 0;
    if (n == 1 || n == 2)
        return (f[n] = 1);
  
    // If fib(n) is already computed
    if (f[n])
        return f[n];

2556
Chapter 355. Program for Fibonacci numbers

  
    int k = (n & 1)? (n+1)/2 : n/2;
  
    // Applyting above formula [Note value n&1 is 1
    // if n is odd, else 0.
    f[n] = (n & 1)? (fib(k)*fib(k) + fib(k-1)*fib(k-1))
           : (2*fib(k-1) + fib(k))*fib(k);
  
    return f[n];
}
  
/* Driver program to test above function */
int main()
{
    int n = 9;
    printf("%d ", fib(n));
    return 0;
}

Java

// Java Program to find n'th fibonacci 


// Number with O(Log n) arithmetic operations
import java.util.*;
  
class GFG {
      
    static int MAX = 1000;
    static int f[];
      
    // Returns n'th fibonacci number using 
    // table f[]
    public static int fib(int n)
    {
        // Base cases
        if (n == 0)
            return 0;
              
        if (n == 1 || n == 2)
            return (f[n] = 1);
       
        // If fib(n) is already computed
        if (f[n] != 0)
            return f[n];
       
        int k = (n & 1) == 1? (n + 1) / 2 
                            : n / 2;
       

2557
Chapter 355. Program for Fibonacci numbers

        // Applyting above formula [Note value


        // n&1 is 1 if n is odd, else 0.
        f[n] = (n & 1) == 1? (fib(k) * fib(k) + 
                        fib(k - 1) * fib(k - 1))
                       : (2 * fib(k - 1) + fib(k)) 
                       * fib(k);
       
        return f[n];
    }
      
    /* Driver program to test above function */
    public static void main(String[] args) 
    {
        int n = 9;
        f= new int[MAX];
        System.out.println(fib(n));
    }
}
      
// This code is contributed by Arnav Kr. Mandal.

Python

# Python 3 Program to find n'th fibonacci Number in


# with O(Log n) arithmatic operations
MAX = 1000
  
# Create an array for memoization
f = [0] * MAX
  
# Returns n'th fuibonacci number using table f[]
def fib(n) :
    # Base cases
    if (n == 0) :
        return 0
    if (n == 1 or n == 2) :
        f[n] = 1
        return (f[n])
  
    # If fib(n) is already computed
    if (f[n]) :
        return f[n]
  
    if( n & 1) :
        k = (n + 1) // 2
    else : 
        k = n // 2
  

2558
Chapter 355. Program for Fibonacci numbers

    # Applyting above formula [Note value n&1 is 1


    # if n is odd, else 0.
    if((n & 1) ) :
        f[n] = (fib(k) * fib(k) + fib(k-1) * fib(k-1))
    else :
        f[n] = (2*fib(k-1) + fib(k))*fib(k)
  
    return f[n]
  
  
# Driver code
n = 9
print(fib(n))
  
  
# This code is contributed by Nikita Tiwari.

C#

// C# Program to find n'th 


// fibonacci Number with 
// O(Log n) arithmetic operations
using System;
  
class GFG
{
  
static int MAX = 1000;
static int[] f;
  
// Returns n'th fibonacci 
// number using table f[]
public static int fib(int n)
{
    // Base cases
    if (n == 0)
        return 0;
          
    if (n == 1 || n == 2)
        return (f[n] = 1);
  
    // If fib(n) is already 
    // computed
    if (f[n] != 0)
        return f[n];
  
    int k = (n & 1) == 1 ? (n + 1) / 2
                         : n / 2;

2559
Chapter 355. Program for Fibonacci numbers

  
    // Applyting above formula 
    // [Note value n&1 is 1 if 
    // n is odd, else 0.
    f[n] = (n & 1) == 1 ? (fib(k) * fib(k) + 
                           fib(k - 1) * fib(k - 1))
                        : (2 * fib(k - 1) + fib(k)) * 
                                            fib(k);
  
    return f[n];
}
  
// Driver Code
static void Main() 
{
    int n = 9;
    f = new int[MAX];
    Console.WriteLine(fib(n));
}
}
  
// This code is contributed by mits

Output :

34

Time complexity of this solution is O(Log n) as we divide the problem to half in every
recursive call.
This method is contributed by Chirag Agarwal.
Related Articles:
Large Fibonacci Numbers in Java
References:
http://en.wikipedia.org/wiki/Fibonacci_number
http://www.ics.uci.edu/~eppstein/161/960109.html
Improved By : jit_t, vt_m, humblezero, Mithun Kumar

Source

https://www.geeksforgeeks.org/program-for-nth-fibonacci-number/

2560
Chapter 356

Program for nth Catalan


Number

Program for nth Catalan Number - GeeksforGeeks


Catalan numbers are a sequence of natural numbers that occurs in many interesting counting
problems like following.
1) Count the number of expressions containing n pairs of parentheses which are correctly
matched. For n = 3, possible expressions are ((())), ()(()), ()()(), (())(), (()()).
2) Count the number of possible Binary Search Trees with n keys (See this)
3) Count the number of full binary trees (A rooted binary tree is full if every vertex has
either two children or no children) with n+1 leaves.
See thisfor more applications.
The first few Catalan numbers for n = 0, 1, 2, 3, … are 1, 1, 2, 5, 14, 42, 132, 429, 1430,
4862, …
Recursive Solution
Catalan numbers satisfy the following recursive formula.

Following is the implementation of above recursive formula.

C++

#include<iostream>
using namespace std;
  
// A recursive function to find nth catalan number
unsigned long int catalan(unsigned int n)
{

2561
Chapter 356. Program for nth Catalan Number

    // Base case


    if (n <= 1) return 1;
  
    // catalan(n) is sum of catalan(i)*catalan(n-i-1)
    unsigned long int res = 0;
    for (int i=0; i<n; i++)
        res += catalan(i)*catalan(n-i-1);
  
    return res;
}
  
// Driver program to test above function
int main()
{
    for (int i=0; i<10; i++)
        cout << catalan(i) << " ";
    return 0;
}

Java

class CatalnNumber {
  
    // A recursive function to find nth catalan number
  
    int catalan(int n) {
        int res = 0;
          
        // Base case
        if (n <= 1) {
            return 1;
        }
        for (int i = 0; i < n; i++) {
            res += catalan(i) * catalan(n - i - 1);
        }
        return res;
    }
  
    public static void main(String[] args) {
        CatalnNumber cn = new CatalnNumber();
        for (int i = 0; i < 10; i++) {
            System.out.print(cn.catalan(i) + " ");
        }
    }
}

Python

2562
Chapter 356. Program for nth Catalan Number

# A recursive function to find nth catalan number


def catalan(n):
    # Base Case
    if n <=1 :
        return 1 
  
    # Catalan(n) is the sum of catalan(i)*catalan(n-i-1)
    res = 0 
    for i in range(n):
        res += catalan(i) * catalan(n-i-1)
  
    return res
  
# Driver Program to test above function
for i in range(10):
    print catalan(i),
# This code is contributed by Nikhil Kumar Singh (nickzuck_007)

C#

// A recursive C# program to find


// nth catalan number
using System;
  
class GFG {
  
    // A recursive function to find 
    // nth catalan number
    static int catalan(int n) {
        int res = 0;
          
        // Base case
        if (n <= 1) {
            return 1;
        }
        for (int i = 0; i < n; i++) 
        {
            res += catalan(i)
               * catalan(n - i - 1);
        }
        return res;
    }
  
    public static void Main()
    {
        for (int i = 0; i < 10; i++) 
            Console.Write(catalan(i)
                             + " ");

2563
Chapter 356. Program for nth Catalan Number

    }
}
  
// This code is contributed by
// nitin mittal.

PHP

<?php
// PHP Program for nth 
// Catalan Number
  
// A recursive function to
// find nth catalan number
function catalan($n)
{
      
    // Base case
    if ($n <= 1)
        return 1;
  
    // catalan(n) is sum of 
    // catalan(i)*catalan(n-i-1)
    $res = 0;
    for($i = 0; $i < $n; $i++)
        $res += catalan($i) * 
                catalan($n - $i - 1);
  
    return $res;
}
  
    // Driver Code
    for ($i = 0; $i < 10; $i++)
        echo catalan($i), " ";
  
// This code is contributed aj_36
?>

Output :

1 1 2 5 14 42 132 429 1430 4862

Time complexity of above implementation is equivalent to nth catalan number.

The value of nth catalan number is exponential that makes the time complexity exponential.

2564
Chapter 356. Program for nth Catalan Number

Dynamic Programming Solution


We can observe that the above recursive implementation does a lot of repeated work (we can
the same by drawing recursion tree). Since there are overlapping subproblems, we can use
dynamic programming for this. Following is a Dynamic programming based implementation
in C++.
C++

#include<iostream>
using namespace std;
  
// A dynamic programming based function to find nth
// Catalan number
unsigned long int catalanDP(unsigned int n)
{
    // Table to store results of subproblems
    unsigned long int catalan[n+1];
  
    // Initialize first two values in table
    catalan[0] = catalan[1] = 1;
  
    // Fill entries in catalan[] using recursive formula
    for (int i=2; i<=n; i++)
    {
        catalan[i] = 0;
        for (int j=0; j<i; j++)
            catalan[i] += catalan[j] * catalan[i-j-1];
    }
  
    // Return last entry
    return catalan[n];
}
  
// Driver program to test above function
int main()
{
    for (int i = 0; i < 10; i++)
        cout << catalanDP(i) << " ";
    return 0;
}

Python

# A dynamic programming based function to find nth


# Catalan number
def catalan(n):
    if (n == 0 or n == 1):
        return 1

2565
Chapter 356. Program for nth Catalan Number

  
    # Table to store results of subproblems
    catalan = [0 for i in range(n + 1)]
  
    # Initialize first two values in table
    catalan[0] = 1
    catalan[1] = 1
  
    # Fill entries in catalan[] using recursive formula
    for i in range(2, n + 1):
        catalan[i] = 0
        for j in range(i):
            catalan[i] = catalan[i] + catalan[j] * catalan[i-j-1]
  
    # Return last entry
    return catalan[n]
  
# Driver code
for i in range (11):
    print (catalanDP(i))
# This code is contributed by Aditi Sharma

PHP

<?php
// PHP program for nth Catalan Number
  
// A dynamic programming based function 
// to find nth Catalan number
function catalanDP( $n)
{
      
    // Table to store results 
    // of subproblems
    $catalan= array();
  
    // Initialize first two 
    // values in table
    $catalan[0] = $catalan[1] = 1;
  
    // Fill entries in catalan[] 
    // using recursive formula
    for ($i = 2; $i <= $n; $i++)
    {
        $catalan[$i] = 0;
        for ( $j = 0; $j < $i; $j++)
            $catalan[$i] += $catalan[$j] * 
                   $catalan[$i - $j - 1];

2566
Chapter 356. Program for nth Catalan Number

    }
  
    // Return last entry
    return $catalan[$n];
}
  
    // Driver Code
    for ($i = 0; $i < 10; $i++)
        echo catalanDP($i) , " ";
  
// This code is contributed anuj_67.
?>

Output:

1 1 2 5 14 42 132 429 1430 4862

Time Complexity: Time complexity of above implementation is O(n2 )


Using Binomial Coefficient
We can also use the below formula to find nth catalan number in O(n) time.

We have discussed aO(n) approach to find binomial coefficient nCr.

C++

#include<iostream>
using namespace std;
  
// Returns value of Binomial Coefficient C(n, k)
unsigned long int binomialCoeff(unsigned int n, unsigned int k)
{
    unsigned long int res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if (k > n - k)
        k = n - k;
  
    // Calculate value of [n*(n-1)*---*(n-k+1)] / [k*(k-1)*---*1]
    for (int i = 0; i < k; ++i)
    {
        res *= (n - i);
        res /= (i + 1);
    }
  

2567
Chapter 356. Program for nth Catalan Number

    return res;
}
  
// A Binomial coefficient based function to find nth catalan
// number in O(n) time
unsigned long int catalan(unsigned int n)
{
    // Calculate value of 2nCn
    unsigned long int c = binomialCoeff(2*n, n);
  
    // return 2nCn/(n+1)
    return c/(n+1);
}
  
// Driver program to test above functions
int main()
{
    for (int i = 0; i < 10; i++)
        cout << catalan(i) << " ";
    return 0;
}

Python

# Returns value of Binomial Coefficient C(n, k)


def binomialCoefficient(n, k):
  
    # since C(n, k) = C(n, n - k)
    if (k > n - k):
        k = n - k
  
    # initialize result
    res = 1
  
    # Calculate value of [n * (n-1) *---* (n-k + 1)]
    # / [k * (k-1) *----* 1]
    for i in range(k):
        res = res * (n - i)
        res = res / (i + 1)
    return res
  
# A Binomial coefficient based function to
# find nth catalan number in O(n) time
def catalan(n):
    c = binomialCoefficient(2*n, n)
    return c/(n + 1)
  
for i in range (11):

2568
Chapter 356. Program for nth Catalan Number

    print (catalan(i))
  
# This code is contributed by Aditi Sharma

Output:

1 1 2 5 14 42 132 429 1430 4862

Time Complexity: Time complexity of above implementation is O(n).


We can also use below formula to find nth catalan number in O(n) time.

References:
http://en.wikipedia.org/wiki/Catalan_number

Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above
Improved By : icr0, jit_t, nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/program-nth-catalan-number/

2569
Chapter 357

Program to find amount of


water in a given glass

Program to find amount of water in a given glass - GeeksforGeeks


There are some glasses with equal capacity as 1 litre. The glasses are kept as follows:

1
2 3
4 5 6
7 8 9 10

You can put water to only top glass. If you put more than 1 litre water to 1st glass, water
overflows and fills equally in both 2nd and 3rd glasses. Glass 5 will get water from both
2nd glass and 3rd glass and so on.
If you have X litre of water and you put that water in top glass, how much water will be
contained by jth glass in ith row?
Example. If you will put 2 litre on top.
1st – 1 litre
2nd – 1/2 litre
3rd – 1/2 litre
The approach is similar to Method 2 of the Pascal’s Triangle. If we take a closer look at the
problem, the problem boils down to Pascal’s Triangle.

1 ---------------- 1
2 3 ---------------- 2
4 5 6 ------------ 3
7 8 9 10 --------- 4

2570
Chapter 357. Program to find amount of water in a given glass

Each glass contributes to the two glasses down the glass. Initially, we put all water in first
glass. Then we keep 1 litre (or less than 1 litre) in it, and move rest of the water to two
glasses down to it. We follow the same process for the two glasses and all other glasses till
ith row. There will be i*(i+1)/2 glasses till ith row.
C++

// Program to find the amount of water in j-th glass


// of i-th row
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
  
// Returns the amount of water in jth glass of ith row
float findWater(int i, int j, float X)
{
    // A row number i has maximum i columns. So input
    // column number must be less than i
    if (j > i)
    {
        printf("Incorrect Inputn");
        exit(0);
    }
  
    // There will be i*(i+1)/2 glasses till ith row 
    // (including ith row)
    float glass[i * (i + 1) / 2];
  
    // Initialize all glasses as empty
    memset(glass, 0, sizeof(glass));
  
    // Put all water in first glass
    int index = 0;
    glass[index] = X;
  
    // Now let the water flow to the downward glasses 
    // till the row number is less than or/ equal to i (given row) 
    // correction : X can be zero for side glasses as they have lower rate to fill
    for (int row = 1; row <= i ; ++row)
    {
        // Fill glasses in a given row. Number of 
        // columns in a row is equal to row number
        for (int col = 1; col <= row; ++col, ++index)
        {
            // Get the water from current glass
            X = glass[index];
  
            // Keep the amount less than or equal to
            // capacity in current glass

2571
Chapter 357. Program to find amount of water in a given glass

            glass[index] = (X >= 1.0f) ? 1.0f : X;


  
            // Get the remaining amount
            X = (X >= 1.0f) ? (X - 1) : 0.0f;
  
            // Distribute the remaining amount to 
            // the down two glasses
            glass[index + row] += X / 2;
            glass[index + row + 1] += X / 2;
        }
    }
  
    // The index of jth glass in ith row will 
    // be i*(i-1)/2 + j - 1
    return glass[i*(i-1)/2 + j - 1];
}
  
// Driver program to test above function
int main()
{
    int i = 2, j = 2;
    float X = 2.0; // Total amount of water
  
    printf("Amount of water in jth glass of ith row is: %f",
            findWater(i, j, X));
  
    return 0;
}

Java

// Program to find the amount 


/// of water in j-th glass
// of i-th row
import java.lang.*;
  
class GFG
{
// Returns the amount of water
// in jth glass of ith row
static float findWater(int i, int j, 
                       float X)
{
// A row number i has maximum i 
// columns. So input column 
// number must be less than i
if (j > i)
{

2572
Chapter 357. Program to find amount of water in a given glass

    System.out.println("Incorrect Input");
    System.exit(0);
}
  
// There will be i*(i+1)/2 glasses 
// till ith row (including ith row)
int ll = Math.round((i * (i + 1) ));
float[] glass = new float[ll + 2];
  
// Put all water in first glass
int index = 0;
glass[index] = X;
  
// Now let the water flow to the 
// downward glasses till the row 
// number is less than or/ equal 
// to i (given row) 
// correction : X can be zero for side 
// glasses as they have lower rate to fill
for (int row = 1; row <= i ; ++row)
{
    // Fill glasses in a given row. Number of 
    // columns in a row is equal to row number
    for (int col = 1; 
             col <= row; ++col, ++index)
    {
        // Get the water from current glass
        X = glass[index];
  
        // Keep the amount less than or 
        // equal to capacity in current glass
        glass[index] = (X >= 1.0f) ? 1.0f : X;
  
        // Get the remaining amount
        X = (X >= 1.0f) ? (X - 1) : 0.0f;
  
        // Distribute the remaining amount  
        // to the down two glasses
        glass[index + row] += X / 2;
        glass[index + row + 1] += X / 2;
    }
}
  
// The index of jth glass in ith 
// row will be i*(i-1)/2 + j - 1
return glass[(int)(i * (i - 1) / 
                   2 + j - 1)];
}

2573
Chapter 357. Program to find amount of water in a given glass

  
// Driver Code
public static void main(String[] args)
{
    int i = 2, j = 2;
    float X = 2.0f; // Total amount of water
    System.out.println("Amount of water in jth " +
                         "glass of ith row is: " + 
                              findWater(i, j, X));
}
}
  
// This code is contributed by mits

Python3

# Program to find the amount 


# of water in j-th glass of
# i-th row
  
# Returns the amount of water 
# in jth glass of ith row
def findWater(i, j, X):
    # A row number i has maximum
    # i columns. So input column 
    # number must be less than i
    if (j > i):
        print("Incorrect Input");
        return;
  
    # There will be i*(i+1)/2 
    # glasses till ith row 
    # (including ith row)
    # and Initialize all glasses 
    # as empty
    glass = [0]*int(i *(i + 1) / 2);
  
    # Put all water
    # in first glass
    index = 0;
    glass[index] = X;
  
    # Now let the water flow to 
    # the downward glasses till
    # the row number is less 
    # than or/ equal to i (given 
    # row) correction : X can be 
    # zero for side glasses as 

2574
Chapter 357. Program to find amount of water in a given glass

    # they have lower rate to fill


    for row in range(1,i):
        # Fill glasses in a given
        # row. Number of columns 
        # in a row is equal to row number
        for col in range(1,row+1):
            # Get the water 
            # from current glass
            X = glass[index];
  
            # Keep the amount less 
            # than or equal to
            # capacity in current glass
            glass[index] = 1.0 if (X >= 1.0) else X;
  
            # Get the remaining amount
            X = (X - 1) if (X >= 1.0) else 0.0;
  
            # Distribute the remaining 
            # amount to the down two glasses
            glass[index + row] += (X / 2);
            glass[index + row + 1] += (X / 2);
            index+=1;
  
    # The index of jth glass
    # in ith row will 
    # be i*(i-1)/2 + j - 1
    return glass[int(i * (i - 1) /2 + j - 1)];
  
# Driver Code
if __name__ == "__main__":
      
    i = 2;
    j = 2;
    X = 2.0; 
# Total amount of water
  
    res=repr(findWater(i, j, X));
    print("Amount of water in jth glass of ith row is:",res.ljust(8,'0'));
# This Code is contributed by mits

C#
// Program to find the amount
// of water in j-th glass
// of i-th row
using System;
class GFG

2575
Chapter 357. Program to find amount of water in a given glass

{
// Returns the amount of water
// in jth glass of ith row
static float findWater(int i, int j,
float X)
{
// A row number i has maximum i
// columns. So input column
// number must be less than i
if (j > i)
{
Console.WriteLine(“Incorrect Input”);
Environment.Exit(0);
}
// There will be i*(i+1)/2 glasses
// till ith row (including ith row)
int ll = (int)Math.Round((double)(i * (i + 1)));
float[] glass = new float[ll + 2];
// Put all water in first glass
int index = 0;
glass[index] = X;
// Now let the water flow to the
// downward glasses till the row
// number is less than or/ equal
// to i (given row)
// correction : X can be zero
// for side glasses as they have
// lower rate to fill
for (int row = 1; row <= i ; ++row) { // Fill glasses in a given row. // Number of columns
in a row // is equal to row number for (int col = 1; col <= row; ++col, ++index) { // Get
the water from current glass X = glass[index]; // Keep the amount less than // or equal to
capacity in // current glass glass[index] = (X >= 1.0f) ?
1.0f : X;
// Get the remaining amount
X = (X >= 1.0f) ? (X – 1) : 0.0f;
// Distribute the remaining amount
// to the down two glasses
glass[index + row] += X / 2;
glass[index + row + 1] += X / 2;
}
}
// The index of jth glass in ith
// row will be i*(i-1)/2 + j – 1
return glass[(int)(i * (i – 1) /
2 + j – 1)];

2576
Chapter 357. Program to find amount of water in a given glass

}
// Driver Code
static void Main()
{
int i = 2, j = 2;
float X = 2.0f; // Total amount of water
Console.WriteLine(“Amount of water in jth ” +
“glass of ith row is: ” +
findWater(i, j, X));
}
}
// This code is contributed by mits
PHP

<?php
// Program to find the amount 
// of water in j-th glass of
// i-th row
  
// Returns the amount of water 
// in jth glass of ith row
function findWater($i, $j, $X)
{
    // A row number i has maximum
    // i columns. So input column 
    // number must be less than i
    if ($j > $i)
    {
        echo "Incorrect Input\n";
        return;
    }
  
    // There will be i*(i+1)/2 
    // glasses till ith row 
    // (including ith row)
    // and Initialize all glasses 
    // as empty
    $glass = array_fill(0, (int)($i * 
                       ($i + 1) / 2), 0);
  
    // Put all water
    // in first glass
    $index = 0;
    $glass[$index] = $X;
  
    // Now let the water flow to 

2577
Chapter 357. Program to find amount of water in a given glass

    // the downward glasses till


    // the row number is less 
    // than or/ equal to i (given  
    // row) correction : X can be 
    // zero for side glasses as 
    // they have lower rate to fill
    for ($row = 1; $row < $i ; ++$row)
    {
        // Fill glasses in a given
        // row. Number of columns 
        // in a row is equal to row number
        for ($col = 1; 
             $col <= $row; ++$col, ++$index)
        {
            // Get the water 
            // from current glass
            $X = $glass[$index];
  
            // Keep the amount less 
            // than or equal to
            // capacity in current glass
            $glass[$index] = ($X >= 1.0) ? 
                                     1.0 : $X;
  
            // Get the remaining amount
            $X = ($X >= 1.0) ? 
                    ($X - 1) : 0.0;
  
            // Distribute the remaining 
            // amount to the down two glasses
            $glass[$index + $row] += (double)($X / 2);
            $glass[$index + $row + 1] += (double)($X / 2);
        }
    }
  
    // The index of jth glass
    // in ith row will 
    // be i*(i-1)/2 + j - 1
    return $glass[(int)($i * ($i - 1) /
                          2 + $j - 1)];
}
  
// Driver Code
$i = 2;
$j = 2;
$X = 2.0; // Total amount of water
echo "Amount of water in jth " , 
        "glass of ith row is: ".

2578
Chapter 357. Program to find amount of water in a given glass

       str_pad(findWater($i, $j, 
                   $X), 8, '0');
  
// This Code is contributed by mits
?>

Output:

Amount of water in jth glass of ith row is: 0.500000

Time Complexity: O(i*(i+1)/2) or O(i^2)


Auxiliary Space: O(i*(i+1)/2) or O(i^2)
This article is compiled by Rahul and reviewed by GeeksforGeeks team. Please write
comments if you find anything incorrect, or you want to share more information about the
topic discussed above
Improved By : Pradeep Joshi, Mithun Kumar

Source

https://www.geeksforgeeks.org/find-water-in-a-glass/

2579
Chapter 358

Pyramid form (increasing then


decreasing) consecutive array
using reduce operations

Pyramid form (increasing then decreasing) consecutive array using reduce operations -
GeeksforGeeks
We have N (where N > 2) stones of various heights laid out in a row. Task is to make a
pyramid from given array of stones. In a pyramid, height of the stones start from 1, increase
by 1, until it reaches some value x, then decreases by 1 until it reaches 1 again i.e. the stones
should be 1, 2, 3, 4…x – 1, x, x – 1, x – 2 … 1. All other stones not part of the pyramid should
have a height 0. We cannot move any of the stones from their current position, however, by
paying a fee of 1, we can reduce the heights of the stones. We wish to minimize the cost of
building a pyramid. Output the minimum cost to build this pyramid.
Examples:

Input : 1 2 3 4 2 1
Output : 4
The best pyramid that can be formed in this case is:
1 2 3 2 1 0
The cost is thus:
(4 - 2) + (2 - 1) + (1 - 0) = 4

Input : 1 5 2
Output : 4
We make a pyramid 1 2 1

Input : 1 2 1
Output : 0
We already have a pyramid, we do not need to do any

2580
Chapter 358. Pyramid form (increasing then decreasing) consecutive array using reduce
operations

further construction.

By using simple logic, we can prove that the pyramid with the least cost of construction
would be that of the maximum height. Also, two temples of same heights would cost the
same to construct.
This can be shown as follows:
Assume the cost of demolishing all the stones to height 0 is x.
Assume the cost of demolishing a temple of height h to height 0 is y.
Then, if it is possible to construct a temple of height h from given stones, its cost would be
x – y.
By using this, we can simplify our approach to two main steps:
1. Identify the pyramid of maximum height that can be formed.
2. Calculate the cost of constructing such a pyramid.
Step 2 can be completed in O(N) time complexity assuming we know where our pyramid is
placed.
Thus, our focus should be on decreasing the time complexity of step 1.
Naive Approach
For each position in the array, we can assume the pyramid starts at that point. We then
find the cost of constructing a temple of maximum height from 1 onwards, until a higher
height is not possible, that is, assume a pyramid of height 1 is the maximum, then assume
2 is maximum and so on. Out of each of these costs, we then choose the minimum.
This approach uses a time complexity of O(N^3).
Improved Approach
For each position, assume it is the center of a temple. Move to the left and right of this
point and attempt to find the maximum height of the temple.
This can be done by setting the maximum of height of a temple at position i to be H(i)
where H(i) is the height of the stone at that point. We then move to the left. If the height
of the stone at this point is less than H(i) – 1, we set the maximum height to now be H(i –
1) + 1. In this way we identify the maximum height for each position.
This approach uses a time complexity of O(N^2).
Dynamic Programming Approach
By modifying the above algorithm slightly, we can attempt to get an O(N) approach. Start at
the left, and moving right, find the maximum possible height pyramid that can be created
at that position. Assume that the part of the array to the right of that position is a
mirror image of the left. If H(i) is the height of stone at position i, then maxHeight(i) =
Minimum(H(i), i, maxHeight(i – 1))
This can be explained as follows:
The maximum possible height cannot exceed H(i) as we can only decrease the height of
stone, not increase.
The maximum possible height cannot exceed i, as the pyramid has to start from a height 1.
The maximum possible height cannot exceed the maximum possible height of the stone
before it – 1, as the stones have to increase by 1 for each step.
We calculate a similar value moving from right to left. We then take the minimum of these
values for each position. Then by identifying the maximum, we can calculate the minimum
cost of constructing a pyramid.

2581
Chapter 358. Pyramid form (increasing then decreasing) consecutive array using reduce
operations

// Program to find minimum cost for pyramid


// from given array
#include <iostream>
using namespace std;
  
#define ull unsigned long long
  
// Returns minimum cost to form a pyramid
ull minPyramidCost(ull arr[], ull N)
{
    // Store the maximum possible pyramid height
    ull *left = new ull[N];
    ull *right = new ull[N];
  
    // Maximum height at start is 1
    left[0] = min(arr[0], (ull)1);
  
    // For each position calculate maximum height
    for (int i = 1; i < N; ++i)
        left[i] = min(arr[i],
                      min(left[i - 1] + 1, (ull)i + 1));
  
    // Maximum height at end is 1
    right[N - 1] = min(arr[N - 1], (ull)1);
  
    // For each position calculate maximum height
    for (int i = N - 2; i >= 0; --i)
        right[i] = min(arr[i],
                       min(right[i + 1] + 1, N - i));
  
    // Find minimum possible among calculated values
    ull tot[N];
    for (int i = 0; i < N; ++i)
        tot[i] = min(right[i], left[i]);
  
    // Find maximum height of pyramid
    ull max_ind = 0;
    for (int i = 0; i < N; ++i)
        if (tot[i] > tot[max_ind])
            max_ind = i;
  
    // Calculate cost of this pyramid
    ull cost = 0;
    ull height = tot[max_ind];
  
    // Calculate cost of left half
    for (int x = max_ind; x >= 0; --x)
    {

2582
Chapter 358. Pyramid form (increasing then decreasing) consecutive array using reduce
operations

        cost += arr[x] - height;


        if (height > 0)
            --height;
    }
  
    // Calculate cost of right half
    height = tot[max_ind] - 1;
    for (int x = max_ind + 1; x < N; ++x)
    {
        cost += arr[x] - height;
        if (height > 0)
            --height;
    }
    return cost;
}
  
// Driver code
int main()
{
    ull arr[] = {1, 2, 3, 4, 2, 1};
    ull N = sizeof(arr)/sizeof(arr[0]);
    cout << minPyramidCost(arr, N);
    return 0;
}

Output:

This approach runs in O(N) time complexity.

Source

https://www.geeksforgeeks.org/pyramid-form-increasing-decreasing-consecutive-array-using-reduce-operations/

2583
Chapter 359

Queries on number of Binary


sub-matrices of Given size

Queries on number of Binary sub-matrices of Given size - GeeksforGeeks


Given a Binary Matrix of size N X M, the task is to answer Q queries of the following
type;

Query(a, b): Find the number of sub matrices of size a X a with each of its
element consisting of the Binary Number b.

We basically need to find submatrices of given sizes with all 1s or all 0s.
Examples:

Input : N = 5, M = 4
m[][] = { { 0, 0, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 1, 1 }
}
Q = 2
Query 1 : a = 2, b = 1
Query 2 : a = 2, b = 0
Output : 4 1

Explanation:
For Query 1,
0011 0011 0011 0011
0010 0010 0010 0010
0111 0111 0111 0111

2584
Chapter 359. Queries on number of Binary sub-matrices of Given size

1111 1111 1111 1111


0111 0111 0111 0111

For Query 2,
0011
0010
0111
1111
0111

Input : N = 5, M = 4
m[][] = { { 0, 0, 1, 1 },
{ 0, 0, 1, 0 },
{ 0, 1, 1, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 1, 1 }
}

Q = 1
Query 1 : a = 3, b = 1
Output : 1

The idea is to use Dynamic Programming to solve the problem. First declare a 2D array
dp[][], where value at dp[i][j] (say K) indicates the size of the largest square sub-matrix (K
X K) that can be formed whose all elements are equal to m[i][j] and (i, j) is the last element
(south-east) of the sub matrix. Now, dp[i][j] can be defined as:

1) If i = 0 OR j = 0 In this Case, dp[i][j] = 1, because only 1 X 1 is the only


square matrix that can be formed at 0th row or 0th column whose all elements
are equal
to m[i][j] and the last element is (i, 0) or (0, j).
2) If m[i][j] = m[i-1][j] = m[i][j-1] = m[i-1][j-1] dp[i][j] = min(dp[i][j-1],
dp[i-1][j], dp[i-1][j-1]) + 1, if the binary number at m[i][j] is equal to the binary
number at m[i-1][j], m[i-1][j-1] and m[i][j-1]. Because if the current binary number
is equal to all the three binary numbers it will form a 2 X 2 square sub-matrix
where all the elements are equal. Also, it will contribute 1 more row and column
to the square matrix with all equal element at position m[i-1][j], m[i-1][j-1] and
m[i][j-1].
dp[i][j] = 1, if above conditions do not meet because a single cell will always
contribute a 1 X 1 sub matrix.

Now, traverse the 2D dp[][] array and calculate the frequency (freq0[] for the element 0,
freq1[] for the element 1) of all the distinct values i.e distinct sizes of square sub-matrix for
both 0s and 1s.
Observe, that to count the square sub-matrix of size Y X Y, then Y+1 X Y+1 will also
contribute 1 count. Suppose we need to count 2 X 2 matrix and dp[][]=

2585
Chapter 359. Queries on number of Binary sub-matrices of Given size

...22
...23

Here, the frequency of two is 3 but observe element where dp[i][j] = 3 is also contributing a
2 X 2 square sub-matrix.
So, find the cumulative sum of the frequency for both freq0[] and freq1[].
Below is the implementation of this approach:

C++

// CPP Program to answer queries on number of


// submatrix of given size
#include <bits/stdc++.h>
using namespace std;
  
#define MAX 100
#define N 5
#define M 4
  
// Return the minimum of three numbers
int min(int a, int b, int c)
{
    return min(a, min(b, c));
}
  
// Solve each query on matrix
void solveQuery(int n, int m, int mat[N][M], int q, 
                             int a[], int binary[])
{
    int dp[n][m], max = 1;
  
    // For each of the cell.
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
  
            // finding submatrix size of oth row 
            // and column.
            if (i == 0 || j == 0)
                dp[i][j] = 1;
  
            // intermediate cells.
            else if ((mat[i][j] == mat[i - 1][j]) &&
                     (mat[i][j] == mat[i][j - 1]) && 
                     (mat[i][j] == mat[i - 1][j - 1])) {
  
                dp[i][j] = min(dp[i - 1][j], dp[i - 1][j - 1],
                               dp[i][j - 1])

2586
Chapter 359. Queries on number of Binary sub-matrices of Given size

                           + 1;
  
                if (max < dp[i][j])
                    max = dp[i][j];
            }
  
            else
                dp[i][j] = 1;
        }
    }
  
    int freq0[MAX] = { 0 }, freq1[MAX] = { 0 };
  
    // Find frequency of each distinct size 
    // for 0s and 1s.
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (mat[i][j] == 0)
                freq0[dp[i][j]]++;
            else
                freq1[dp[i][j]]++;
        }
    }
  
    // Find the Cumulative Sum.
    for (int i = max - 1; i >= 0; i--) {
        freq0[i] += freq0[i + 1];
        freq1[i] += freq1[i + 1];
    }
  
    // Output the answer for each query
    for (int i = 0; i < q; i++) {
        if (binary[i] == 0)
            cout << freq0[a[i]] << endl;
        else
            cout << freq1[a[i]] << endl;
    }
}
  
// Driver Program
int main()
{
    int n = 5, m = 4;
    int mat[N][M] = {
        { 0, 0, 1, 1 },
        { 0, 0, 1, 0 },
        { 0, 1, 1, 1 },
        { 1, 1, 1, 1 },

2587
Chapter 359. Queries on number of Binary sub-matrices of Given size

        { 0, 1, 1, 1 }
    };
    int q = 2;
    int a[] = { 2, 2 };
    int binary[] = { 1, 0 };
  
    solveQuery(n, m, mat, q, a, binary);
  
    return 0;
}

Java

// Java Program to answer queries on number of


// submatrix of given size
import java.io.*;
  
class GFG {
  
    static int MAX = 100;
    static int N = 5;
    static int M = 4;
      
    // Return the minimum of three numbers
    static int min(int a, int b, int c)
    {
        return Math.min(a, Math.min(b, c));
    }
      
    // Solve each query on matrix
    static void solveQuery(int n, int m, int mat[][],
                        int q, int a[], int binary[])
    {
        int dp[][] = new int[n][m]; 
        int max = 1;
      
        // For each of the cell.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
      
                // finding submatrix size of oth row 
                // and column.
                if (i == 0 || j == 0)
                    dp[i][j] = 1;
      
                // intermediate cells.
                else if ((mat[i][j] == mat[i - 1][j]) 
                      && (mat[i][j] == mat[i][j - 1])

2588
Chapter 359. Queries on number of Binary sub-matrices of Given size

                 && (mat[i][j] == mat[i - 1][j - 1]))


                 {
      
                    dp[i][j] = min(dp[i - 1][j],
                               dp[i - 1][j - 1],
                                dp[i][j - 1]) + 1;
      
                    if (max < dp[i][j])
                        max = dp[i][j];
                }
      
                else
                    dp[i][j] = 1;
            }
        }
      
        int freq0[] = new int[MAX];
        int freq1[] = new int[MAX];
      
        // Find frequency of each distinct size 
        // for 0s and 1s.
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (mat[i][j] == 0)
                    freq0[dp[i][j]]++;
                else
                    freq1[dp[i][j]]++;
            }
        }
      
        // Find the Cumulative Sum.
        for (int i = max - 1; i >= 0; i--) {
            freq0[i] += freq0[i + 1];
            freq1[i] += freq1[i + 1];
        }
      
        // Output the answer for each query
        for (int i = 0; i < q; i++) {
            if (binary[i] == 0)
                System.out.println( freq0[a[i]]);
            else
                System.out.println( freq1[a[i]]);
        }
    }
      
    // Driver Program
  
    public static void main (String[] args) 

2589
Chapter 359. Queries on number of Binary sub-matrices of Given size

    {
        int n = 5, m = 4;
        int mat[][] = { { 0, 0, 1, 1 },
                        { 0, 0, 1, 0 },
                        { 0, 1, 1, 1 },
                        { 1, 1, 1, 1 },
                        { 0, 1, 1, 1 } };
        int q = 2;
        int a[] = { 2, 2 };
        int binary[] = { 1, 0 };
      
        solveQuery(n, m, mat, q, a, binary);
    }
}
  
// This code is contributed by anuj_67.

C#

// C# Program to answer 
// queries on number of
// submatrix of given size
using System;
  
class GFG 
{
    static int MAX = 100;
    // static int N = 5;
    // static int M = 4;
      
    // Return the minimum
    // of three numbers
    static int min(int a, 
                   int b, 
                   int c)
    {
        return Math.Min(a, Math.Min(b, c));
    }
      
    // Solve each query on matrix
    static void solveQuery(int n, int m, 
                           int [,]mat, int q, 
                           int []a, int []binary)
    {
        int [,]dp = new int[n, m]; 
        int max = 1;
      
        // For each of the cell.

2590
Chapter 359. Queries on number of Binary sub-matrices of Given size

        for (int i = 0; i < n; i++) 


        {
            for (int j = 0; j < m; j++) 
            {
      
                // finding submatrix size 
                // of oth row and column.
                if (i == 0 || j == 0)
                    dp[i, j] = 1;
      
                // intermediate cells.
                else if ((mat[i, j] == mat[i - 1, j]) && 
                         (mat[i, j] == mat[i, j - 1]) && 
                         (mat[i, j] == mat[i - 1, j - 1]))
                { 
      
                    dp[i, j] = min(dp[i - 1, j],
                                   dp[i - 1, j - 1],
                                   dp[i, j - 1]) + 1;
      
                    if (max < dp[i, j])
                        max = dp[i, j];
                }
      
                else
                    dp[i, j] = 1;
            }
        }
      
        int []freq0 = new int[MAX];
        int []freq1 = new int[MAX];
      
        // Find frequency of each 
        // distinct size for 0s and 1s.
        for (int i = 0; i < n; i++) 
        {
            for (int j = 0; j < m; j++) 
            {
                if (mat[i, j] == 0)
                    freq0[dp[i, j]]++;
                else
                    freq1[dp[i, j]]++;
            }
        }
      
        // Find the Cumulative Sum.
        for (int i = max - 1; i >= 0; i--) 
        {

2591
Chapter 359. Queries on number of Binary sub-matrices of Given size

            freq0[i] += freq0[i + 1];


            freq1[i] += freq1[i + 1];
        }
      
        // Output the answer
        // for each query
        for (int i = 0; i < q; i++)
        {
            if (binary[i] == 0)
                Console.WriteLine(freq0[a[i]]);
            else
                Console.WriteLine(freq1[a[i]]);
        }
    }
      
    // Driver Code
    public static void Main () 
    {
        int n = 5, m = 4;
        int [,]mat = {{0, 0, 1, 1},
                      {0, 0, 1, 0},
                      {0, 1, 1, 1},
                      {1, 1, 1, 1},
                      {0, 1, 1, 1}};
        int q = 2;
        int []a = {2, 2};
        int []binary = {1, 0};
      
        solveQuery(n, m, mat, 
                   q, a, binary);
    }
}
  
// This code is contributed by anuj_67.

Output:

4
1

Time Complexity of the above algorithm is O(n * m)


Improved By : vt_m

Source
https://www.geeksforgeeks.org/queries-number-binary-sub-matrices-given-size/

2592
Chapter 360

Queries to find distance between


two nodes of a Binary tree

Queries to find distance between two nodes of a Binary tree - GeeksforGeeks


Given a binary tree, the task is to find the distance between two keys in a binary tree, no
parent pointers are given. The distance between two nodes is the minimum number of edges
to be traversed to reach one node from other.
It has been already discussed in this for a single query in O(logn) time, here the task is to
reduce multiple queries time to O(1) by compromising with space complexity to O(Nlogn).
In this post, we will use Sparse table instead of segment tree for finding the minimum in
given range, which uses dynamic programming and bit manipulation to achieve O(1) query
time.

2593
Chapter 360. Queries to find distance between two nodes of a Binary tree

A sparse table will preprocess the minimum values given for an array in Nlogn space i.e.
each node will contain chain of values of log(i) length where i is the index of the ith node in
L array. Each entry in the sparse table says M[i][j] will represent the index of the minimum
value in the subarray starting at i having length 2^j.
The distance between two nodes can be obtained in terms of lowest common ancestor.

Dist(n1, n2) = Level[n1] + Level[n2] - 2*Level[lca]

This problem can be breakdown into finding levels of each node, finding the Euler
tour of binary tree and building sparse table for LCA, these steps are explained below :

1. Find the levels of each node by applying level order traversal.

2. Find the LCA of two nodes in the binary tree in O(logn) by Storing Euler tour of
tree in array and computing two other arrays with the help of levels of each node and
Euler tour.
These steps are shown below:
(I) First, find Euler Tour of binary tree.

2594
Chapter 360. Queries to find distance between two nodes of a Binary tree

(II) Then, store levels of each node in Euler array.

(III) Then, store First occurrences of all nodes of binary tree in Euler array.

3. Then build sparse table on L array and find the minimum value say X in range (H[A]
to H[B]). Then use the index of value X as an index to Euler array to get LCA, i.e.
Euler[index(X)].
Let, A=8 and B=5.
(I) H[8]= 1 and H[5]=2
(II) we get min value in L array between 1 and 2 as X=0, index=7
(III) Then, LCA= Euler[7], i.e LCA=1.

4. Finally, apply distance formula discussed above to get the distance between two nodes.

Source

https://www.geeksforgeeks.org/queries-find-distance-two-nodes-binary-tree/

2595
Chapter 361

Recursively break a number in


3 parts to get maximum sum

Recursively break a number in 3 parts to get maximum sum - GeeksforGeeks


Given a number n, we can divide it in only three parts n/2, n/3 and n/4 (we will consider
only integer part). The task is to find the maximum sum we can make by dividing number
in three parts recursively and summing up them together.
Examples:

Input : n = 12
Output : 13
// We break n = 12 in three parts {12/2, 12/3, 12/4}
// = {6, 4, 3}, now current sum is = (6 + 4 + 3) = 13
// again we break 6 = {6/2, 6/3, 6/4} = {3, 2, 1} = 3 +
// 2 + 1 = 6 and further breaking 3, 2 and 1 we get maximum
// summation as 1, so breaking 6 in three parts produces
// maximum sum 6 only similarly breaking 4 in three
// parts we can get maximum sum 4 and same for 3 also.
// Thus maximum sum by breaking number in parts is=13

Input : n = 24
Output : 27
// We break n = 24 in three parts {24/2, 24/3, 24/4}
// = {12, 8, 6}, now current sum is = (12 + 8 + 6) = 26
// As seen in example, recursively breaking 12 would
// produce value 13. So our maximum sum is 13 + 8 + 6 = 27.
// Note that recursively breaking 8 and 6 doesn't produce
// more values, that is why they are not broken further.

Input : n = 23

2596
Chapter 361. Recursively break a number in 3 parts to get maximum sum

Output : 23
// we break n = 23 in three parts {23/2, 23/3, 23/4} =
// {10, 7, 5}, now current sum is = (10 + 7 + 5) = 22.
// Since after further breaking we can not get maximum
// sum hence number is itself maximum i.e; answer is 23

A simple solution for this problem is to do it recursively. In each call we have to check
only max((max(n/2) + max(n/3) + max(n/4)), n) and return it. Because either we
can get maximum sum by breaking number in parts or number is itself maximum. Below
is the implementation of recursive algorithm.

C++

// A simple recursive C++ program to find


// maximum sum by recursively breaking a
// number in 3 parts.
#include<bits/stdc++.h>
using namespace std;
  
// Function to find the maximum sum
int breakSum(int n)
{
    // base conditions
    if (n==0 || n == 1)
        return n;
  
    // recursively break the number and return
    // what maximum you can get
    return max((breakSum(n/2) + breakSum(n/3) +
                breakSum(n/4)),  n);
}
  
// Driver program to run the case
int main()
{
    int n = 12;
    cout << breakSum(n);
    return 0;
}

Java

// A simple recursive JAVA program to find


// maximum sum by recursively breaking a
// number in 3 parts.
import java.io.*;
  

2597
Chapter 361. Recursively break a number in 3 parts to get maximum sum

class GFG {
     
    // Function to find the maximum sum
    static int breakSum(int n)
    {
        // base conditions
        if (n==0 || n == 1)
            return n;
   
        // recursively break the number and return
        // what maximum you can get
        return Math.max((breakSum(n/2) + breakSum(n/3) +
                    breakSum(n/4)),  n);    
    }
          
    // Driver program to test the above function
    public static void main (String[] args) {
        int n = 12;
        System.out.println(breakSum(n));
    }
}
// This code is contributed by Amit Kumar

C#

// A simple recursive C# program to find


// maximum sum by recursively breaking a
// number in 3 parts.
using System;
  
class GFG {
      
    // Function to find the maximum sum
    static int breakSum(int n)
    {
        // base conditions
        if (n==0 || n == 1)
            return n;
  
        // recursively break the number 
        // and return what maximum you
        // can get
        return Math.Max((breakSum(n/2)
                       + breakSum(n/3) 
                 + breakSum(n/4)), n); 
    }
          
    // Driver program to test the 

2598
Chapter 361. Recursively break a number in 3 parts to get maximum sum

    // above function


    public static void Main () 
    {
        int n = 12;
          
        Console.WriteLine(breakSum(n));
    }
}
  
// This code is contributed by anuj_67.

Output :

13

An efficient solution for this problem is to use Dynamic programming because while
breaking the number in parts recursively we have to perform some overlapping problems.
For example part of n = 30 will be {15,10,7} and part of 15 will be {7,5,3} so we have to
repeat the process for 7 two times for further breaking. To avoid this overlapping problem
we are using Dynamic programming. We store values in an array and if for any number
in recursive calls we have already solution for that number currently so we diretly extract
it from array.

C++

// A Dynamic programming based C++ program


// to find maximum sum by recursively breaking
// a number in 3 parts.
#include<bits/stdc++.h>
#define MAX 1000000
using namespace std;
  
int breakSum(int n)
{
    int dp[n+1];
  
    // base conditions
    dp[0] = 0, dp[1] = 1;
  
    // Fill in bottom-up manner using recursive
    // formula.
    for (int i=2; i<=n; i++)
       dp[i] = max(dp[i/2] + dp[i/3] + dp[i/4], i);
  
    return dp[n];
}

2599
Chapter 361. Recursively break a number in 3 parts to get maximum sum

  
// Driver program to run the case
int main()
{
    int n = 24;
    cout << breakSum(n);
    return 0;
}

Java

// A simple recursive JAVA program to find


// maximum sum by recursively breaking a
// number in 3 parts.
import java.io.*;
  
class GFG {
  
    final int MAX = 1000000;
      
    // Function to find the maximum sum
    static int breakSum(int n)
    {
        int dp[] = new int[n+1];
   
        // base conditions
        dp[0] = 0;  dp[1] = 1;
       
        // Fill in bottom-up manner using recursive
        // formula.
        for (int i=2; i<=n; i++)
           dp[i] = Math.max(dp[i/2] + dp[i/3] + dp[i/4], i);
       
        return dp[n]; 
    }
          
    // Driver program to test the above function
    public static void main (String[] args) {
        int n = 24;
        System.out.println(breakSum(n));
    }
}
// This code is contributed by Amit Kumar

Python3

# A Dynamic programming based Python program

2600
Chapter 361. Recursively break a number in 3 parts to get maximum sum

# to find maximum sum by recursively breaking


# a number in 3 parts.
  
MAX = 1000000
  
def breakSum(n):
  
    dp = [0]*(n+1)
  
    # base conditions
    dp[0] = 0
    dp[1] = 1
  
    # Fill in bottom-up manner using recursive
    # formula.
    for i in range(2, n+1):
        dp[i] = max(dp[int(i/2)] + dp[int(i/3)] + dp[int(i/4)], i);
  
    return dp[n]
  
  
# Driver program to run the case
n = 24
print(breakSum(n))
  
# This code is contributed by
# Smitha Dinesh Semwal

C#

// A simple recursive C# program to find


// maximum sum by recursively breaking a
// number in 3 parts.
using System;
  
class GFG {
      
    // Function to find the maximum sum
    static int breakSum(int n)
    {
        int []dp = new int[n+1];
  
        // base conditions
        dp[0] = 0; dp[1] = 1;
      
        // Fill in bottom-up manner
        // using recursive formula.
        for (int i = 2; i <= n; i++)

2601
Chapter 361. Recursively break a number in 3 parts to get maximum sum

            dp[i] = Math.Max(dp[i/2] + 
                  dp[i/3] + dp[i/4], i);
      
        return dp[n]; 
    }
          
    // Driver program to test the
    // above function
    public static void Main () 
    {
        int n = 24;
        Console.WriteLine(breakSum(n));
    }
}
  
// This code is contributed by anuj_67.

Output:

27

Time Complexity : O(n)


Auxiliary Space : O(n)
Improved By : Sagar_Rakshit, vt_m

Source

https://www.geeksforgeeks.org/recursively-break-number-3-parts-get-maximum-sum/

2602
Chapter 362

Remove array end element to


maximize the sum of product

Remove array end element to maximize the sum of product - GeeksforGeeks


Given an array of N positive integers. We are allowed to remove element from either of the
two ends i.e from the left side or right side of the array. Each time we remove an element,
score is increased by value of element * (number of element already removed + 1). The task
is to find the maximum score that can be obtained by removing all the element.
Examples:

Input : arr[] = { 1, 3, 1, 5, 2 }.
Output : 43
Remove 1 from left side (score = 1*1 = 1)
then remove 2, score = 1 + 2*2 = 5
then remove 3, score = 5 + 3*3 = 14
then remove 1, score = 14 + 1*4 = 18
then remove 5, score = 18 + 5*5 = 43.

Input : arr[] = { 1, 2 }
Output : 5.

The idea is to use Dynamic Programming. Make a 2D matrix named dp[][] initialised with
0, where dp[i][j] denote the maximum value of score from index from index ito index j of
the array. So, our final result will be stored in dp[0][n-1].
Now, value for dp[i][j] will be maximum of arr[i] * (number of element already removed +
1) + dp[i+ 1][j] or arr[j] * (number of element already removed + 1) + dp[i][j – 1].
Below is the C++ implementation of this approach:

// CPP program to find maximum score we can get

2603
Chapter 362. Remove array end element to maximize the sum of product

// by removing elements from either end.


#include <bits/stdc++.h>
#define MAX 50
using namespace std;
  
int solve(int dp[][MAX], int a[], int low, int high,
                                          int turn)
{
    // If only one element left.
    if (low == high)
        return a[low] * turn;
  
    // If already calculated, return the value.
    if (dp[low][high] != 0)
        return dp[low][high];
  
    // Computing Maximum value when element at 
    // index i and index j is to be chosed.
    dp[low][high] = max(a[low] * turn + solve(dp, a, 
                            low + 1, high, turn + 1),
                        a[high] * turn + solve(dp, a, 
                           low, high - 1, turn + 1));
  
    return dp[low][high];
}
  
// Driven Program
int main()
{
    int arr[] = { 1, 3, 1, 5, 2 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    int dp[MAX][MAX];
    memset(dp, 0, sizeof(dp));
  
    cout << solve(dp, arr, 0, n - 1, 1) << endl;
    return 0;
}

Output:

43

Source

https://www.geeksforgeeks.org/remove-array-end-element-maximize-sum-product/

2604
Chapter 363

Remove minimum elements


from either side such that
2*min becomes more than max

Remove minimum elements from either side such that 2*min becomes more than max -
GeeksforGeeks
Given an unsorted array, trim the array such that twice of minimum is greater than maxi-
mum in the trimmed array. Elements should be removed either end of the array.
Number of removals should be minimum.
Examples:

arr[] = {4, 5, 100, 9, 10, 11, 12, 15, 200}


Output: 4
We need to remove 4 elements (4, 5, 100, 200)
so that 2*min becomes more than max.

arr[] = {4, 7, 5, 6}
Output: 0
We don't need to remove any element as
4*2 > 7 (Note that min = 4, max = 8)

arr[] = {20, 7, 5, 6}
Output: 1
We need to remove 20 so that 2*min becomes
more than max

arr[] = {20, 4, 1, 3}

2605
Chapter 363. Remove minimum elements from either side such that 2*min becomes more
than max

Output: 3
We need to remove any three elements from ends
like 20, 4, 1 or 4, 1, 3 or 20, 3, 1 or 20, 4, 1

Naive Solution:
A naive solution is to try every possible case using recurrence. Following is the naive
recursive algorithm. Note that the algorithm only returns minimum numbers of removals to
be made, it doesn’t print the trimmed array. It can be easily modified to print the trimmed
array as well.

// Returns minimum number of removals to be made in


// arr[l..h]
minRemovals(int arr[], int l, int h)
1) Find min and max in arr[l..h]
2) If 2*min > max, then return 0.
3) Else return minimum of "minRemovals(arr, l+1, h) + 1"
and "minRemovals(arr, l, h-1) + 1"

Following is C++ implementation of above algorithm.

#include <iostream>
using namespace std;
  
// A utility function to find minimum of two numbers
int min(int a, int b) {return (a < b)? a : b;}
  
// A utility function to find minimum in arr[l..h]
int min(int arr[], int l, int h)
{
    int mn = arr[l];
    for (int i=l+1; i<=h; i++)
       if (mn > arr[i])
         mn = arr[i];
    return mn;
}
  
// A utility function to find maximum in arr[l..h]
int max(int arr[], int l, int h)
{
    int mx = arr[l];
    for (int i=l+1; i<=h; i++)
       if (mx < arr[i])
         mx = arr[i];
    return mx;
}
  

2606
Chapter 363. Remove minimum elements from either side such that 2*min becomes more
than max

// Returns the minimum number of removals from either end


// in arr[l..h] so that 2*min becomes greater than max.
int minRemovals(int arr[], int l, int h)
{
    // If there is 1 or less elements, return 0
    // For a single element, 2*min > max 
    // (Assumption: All elements are positive in arr[])
    if (l >= h) return 0;
  
    // 1) Find minimum and maximum in arr[l..h]
    int mn = min(arr, l, h);
    int mx = max(arr, l, h);
  
    //If the property is followed, no removals needed
    if (2*mn > mx)
       return 0;
  
    // Otherwise remove a character from left end and recur,
    // then remove a character from right end and recur, take
    // the minimum of two is returned
    return min(minRemovals(arr, l+1, h),
               minRemovals(arr, l, h-1)) + 1;
}
  
// Driver program to test above functions
int main()
{
  int arr[] = {4, 5, 100, 9, 10, 11, 12, 15, 200};
  int n = sizeof(arr)/sizeof(arr[0]);
  cout << minRemovals(arr, 0, n-1);
  return 0;
}

Output:

Time complexity: Time complexity of the above function can be written as following

T(n) = 2T(n-1) + O(n)

An upper bound on solution of above recurrence would be O(n x 2n ).


Dynamic Programming:
The above recursive code exhibits many overlapping subproblems. For example minRe-
movals(arr, l+1, h-1) is evaluated twice. So Dynamic Programming is the choice to optimize
the solution. Following is Dynamic Programming based solution.

2607
Chapter 363. Remove minimum elements from either side such that 2*min becomes more
than max

#include <iostream>
using namespace std;
  
// A utility function to find minimum of two numbers
int min(int a, int b) {return (a < b)? a : b;}
  
// A utility function to find minimum in arr[l..h]
int min(int arr[], int l, int h)
{
    int mn = arr[l];
    for (int i=l+1; i<=h; i++)
       if (mn > arr[i])
         mn = arr[i];
    return mn;
}
  
// A utility function to find maximum in arr[l..h]
int max(int arr[], int l, int h)
{
    int mx = arr[l];
    for (int i=l+1; i<=h; i++)
       if (mx < arr[i])
         mx = arr[i];
    return mx;
}
  
// Returns the minimum number of removals from either end
// in arr[l..h] so that 2*min becomes greater than max.
int minRemovalsDP(int arr[], int n)
{
    // Create a table to store solutions of subproblems
    int table[n][n], gap, i, j, mn, mx;
  
    // Fill table using above recursive formula. Note that the table
    // is filled in diagonal fashion (similar to http://goo.gl/PQqoS),
    // from diagonal elements to table[0][n-1] which is the result.
    for (gap = 0; gap < n; ++gap)
    {
        for (i = 0, j = gap; j < n; ++i, ++j)
        {
            mn = min(arr, i, j);
            mx = max(arr, i, j);
            table[i][j] = (2*mn > mx)? 0: min(table[i][j-1]+1,
                                              table[i+1][j]+1);
        }
    }
    return table[0][n-1];
}

2608
Chapter 363. Remove minimum elements from either side such that 2*min becomes more
than max

  
// Driver program to test above functions
int main()
{
  int arr[] = {20, 4, 1, 3};
  int n = sizeof(arr)/sizeof(arr[0]);
  cout << minRemovalsDP(arr, n);
  return 0;
}

Time Complexity: O(n3 ) where n is the number of elements in arr[].


Further Optimizations:
The above code can be optimized in many ways.
1) We can avoid calculation of min() and/or max() when min and/or max is/are not changed
by removing corner elements.
2) We can pre-process the array and build segment treein O(n) time. After the segment
tree is built, we can query range minimum and maximum in O(Logn) time. The overall
time complexity is reduced to O(n2 Logn) time.
A O(n^2) Solution
The idea is to find the maximum sized subarray such that 2*min > max. We run two nested
loops, the outer loop chooses a starting point and the inner loop chooses ending point for
the current starting point. We keep track of longest subarray with the given property.
Following is C++ implementation of the above approach. Thanks to Richard Zhang for
suggesting this solution.

// A O(n*n) solution to find the minimum of elements to


// be removed
#include <iostream>
#include <climits>
using namespace std;
  
// Returns the minimum number of removals from either end
// in arr[l..h] so that 2*min becomes greater than max.
int minRemovalsDP(int arr[], int n)
{
    // Initialize starting and ending indexes of the maximum
    // sized subarray with property 2*min > max
    int longest_start = -1, longest_end = 0;
  
    // Choose different elements as starting point
    for (int start=0; start<n; start++)
    {
        // Initialize min and max for the current start
        int min = INT_MAX, max = INT_MIN;
  
        // Choose different ending points for current start

2609
Chapter 363. Remove minimum elements from either side such that 2*min becomes more
than max

        for (int end = start; end < n; end ++)


        {
            // Update min and max if necessary
            int val = arr[end];
            if (val < min) min = val;
            if (val > max) max = val;
  
            // If the property is violated, then no
            // point to continue for a bigger array
            if (2 * min <= max) break;
  
            // Update longest_start and longest_end if needed
            if (end - start > longest_end - longest_start ||
                longest_start == -1)
            {
                longest_start = start;
                longest_end = end;
            }
        }
    }
  
    // If not even a single element follow the property,
    // then return n
    if (longest_start == -1) return n;
  
    // Return the number of elements to be removed
    return (n - (longest_end - longest_start + 1));
}
  
// Driver program to test above functions
int main()
{
    int arr[] = {4, 5, 100, 9, 10, 11, 12, 15, 200};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << minRemovalsDP(arr, n);
    return 0;
}

This article is contributed by Rahul Jain. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/remove-minimum-elements-either-side-2min-max/

2610
Chapter 364

Rencontres Number (Counting


partial derangements)

Rencontres Number (Counting partial derangements) - GeeksforGeeks


Given two numbers, n >= 0 and 0 <= k <= n, count the number of derangements with k
fixed points.
Examples:

Input : n = 3, k = 0
Output : 2
Since k = 0, no point needs to be on its
original position. So derangements
are {3, 1, 2} and {2, 3, 1}

Input : n = 3, k = 1
Output : 3
Since k = 1, one point needs to be on its
original position. So partial derangements
are {1, 3, 2}, {3, 2, 1} and {2, 1, 3}

Input : n = 7, k = 2
Output : 924

In combinatorial mathematics, the rencontres number< or D(n, k) represents count of partial


derangements.
The recurrence relation to find Rencontres Number Dn, k :

D(0, 0) = 1
D(0, 1) = 0

2611
Chapter 364. Rencontres Number (Counting partial derangements)

D(n+2, 0) = (n+1) * (D(n+1, 0) + D(n, 0) )


D(n, k) = n Ck * D(n-k, 0) )

Given the two positive integer n and k. The task is find rencontres number D(n, k) for giver
n and k.
Below is Recursive solution of this approach:
C++

// Recursive CPP program to find n-th Rencontres 


// Number
#include <bits/stdc++.h>
using namespace std;
  
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    // Base Cases
    if (k == 0 || k == n)
        return 1;
  
    // Recurrence relation
    return binomialCoeff(n - 1, k - 1) +
           binomialCoeff(n - 1, k);
}
  
// Return Recontres number D(n, m)
int RencontresNumber(int n, int m)
{
    // base condition
    if (n == 0 && m == 0)
        return 1;
  
    // base condition
    if (n == 1 && m == 0)
        return 0;
  
    // base condition
    if (m == 0)
        return (n - 1) * (RencontresNumber(n - 1, 0) +
                          RencontresNumber(n - 2, 0));
  
    return binomialCoeff(n, m) * RencontresNumber(n - m, 0);
}
  
// Driver Program
int main()
{

2612
Chapter 364. Rencontres Number (Counting partial derangements)

    int n = 7, m = 2;
    cout << RencontresNumber(n, m) << endl;
    return 0;
}

Java

// Recursive Java program to find n-th Rencontres


// Number
import java.io.*;
  
class GFG {
      
    // Returns value of Binomial Coefficient
    // C(n, k)
    static int binomialCoeff(int n, int k)
    {
          
        // Base Cases
        if (k == 0 || k == n)
            return 1;
  
        // Recurrence relation
        return binomialCoeff(n - 1, k - 1) + 
                         binomialCoeff(n - 1, k);
    }
  
    // Return Recontres number D(n, m)
    static int RencontresNumber(int n, int m)
    {
          
        // base condition
        if (n == 0 && m == 0)
            return 1;
  
        // base condition
        if (n == 1 && m == 0)
            return 0;
  
        // base condition
        if (m == 0)
            return (n - 1) * (RencontresNumber(n - 1, 0) 
                          + RencontresNumber(n - 2, 0));
  
        return binomialCoeff(n, m) * 
                             RencontresNumber(n - m, 0);
    }
  

2613
Chapter 364. Rencontres Number (Counting partial derangements)

    // Driver Program


    public static void main(String[] args)
    {
        int n = 7, m = 2;
        System.out.println(RencontresNumber(n, m));
    }
}
  
// This code is contributed by vt_m.

Python3

# Recursive CPP program to find


# n-th Rencontres Number
  
# Returns value of Binomial Coefficient C(n, k)
def binomialCoeff(n, k):
  
    # Base Cases
    if (k == 0 or k == n):
        return 1
  
    # Recurrence relation
    return (binomialCoeff(n - 1, k - 1) 
          + binomialCoeff(n - 1, k))
  
# Return Recontres number D(n, m)
def RencontresNumber(n, m):
  
    # base condition
    if (n == 0 and m == 0):
        return 1
  
    # base condition
    if (n == 1 and m == 0):
        return 0
  
    # base condition
    if (m == 0):
        return ((n - 1) * (RencontresNumber(n - 1, 0) 
                         + RencontresNumber(n - 2, 0)))
  
    return (binomialCoeff(n, m) *
            RencontresNumber(n - m, 0))
  
# Driver Program
n = 7; m = 2
print(RencontresNumber(n, m))

2614
Chapter 364. Rencontres Number (Counting partial derangements)

  
# This code is contributed by Smitha Dinesh Semwal.

C#

// Recursive C# program to find n-th Rencontres


// Number
using System;
  
class GFG {
      
    // Returns value of Binomial Coefficient
    // C(n, k)
    static int binomialCoeff(int n, int k)
    {
          
        // Base Cases
        if (k == 0 || k == n)
            return 1;
  
        // Recurrence relation
        return binomialCoeff(n - 1, k - 1) + 
                     binomialCoeff(n - 1, k);
    }
  
    // Return Recontres number D(n, m)
    static int RencontresNumber(int n, int m)
    {
          
        // base condition
        if (n == 0 && m == 0)
            return 1;
  
        // base condition
        if (n == 1 && m == 0)
            return 0;
  
        // base condition
        if (m == 0)
            return (n - 1) * 
                (RencontresNumber(n - 1, 0) 
                + RencontresNumber(n - 2, 0));
  
        return binomialCoeff(n, m) * 
                 RencontresNumber(n - m, 0);
    }
  
    // Driver Program

2615
Chapter 364. Rencontres Number (Counting partial derangements)

    public static void Main()


    {
        int n = 7, m = 2;
          
        Console.Write(RencontresNumber(n, m));
    }
}
  
// This code is contributed by 
// Smitha Dinesh Semwal

PHP

<?php
// Recursive PHP program to
// find n-th Rencontres 
// Number
  
// Returns value of Binomial
// Coefficient C(n, k)
function binomialCoeff($n, $k)
{
      
    // Base Cases
    if ($k == 0 || $k == $n)
        return 1;
  
    // Recurrence relation
    return binomialCoeff($n - 1,$k - 1) +
              binomialCoeff($n - 1, $k);
}
  
// Return Recontres number D(n, m)
function RencontresNumber($n, $m)
{
      
    // base condition
    if ($n == 0 && $m == 0)
        return 1;
  
    // base condition
    if ($n == 1 && $m == 0)
        return 0;
  
    // base condition
    if ($m == 0)
        return ($n - 1) * (RencontresNumber($n - 1, 0) +
                           RencontresNumber($n - 2, 0));

2616
Chapter 364. Rencontres Number (Counting partial derangements)

  
    return binomialCoeff($n, $m) * 
           RencontresNumber($n - $m, 0);
}
  
    // Driver Code
    $n = 7; 
    $m = 2;
    echo RencontresNumber($n, $m),"\n";
      
// This code is contributed by ajit. 
?>

Output:

924

Below is the implementation using Dynamic Programming:

C++

// DP based CPP program to find n-th Rencontres 


// Number
#include <bits/stdc++.h>
using namespace std;
#define MAX 100
  
// Fills table C[n+1][k+1] such that C[i][j]
// represents table of binomial coefficient
// iCj
int binomialCoeff(int C[][MAX], int n, int k)
{
    // Calculate value of Binomial Coefficient
    // in bottom up manner
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= min(i, k); j++) {
  
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
  
            // Calculate value using previously
            // stored values
            else
                C[i][j] = C[i - 1][j - 1] + 
                          C[i - 1][j];

2617
Chapter 364. Rencontres Number (Counting partial derangements)

        }
    }
}
  
// Return Recontres number D(n, m)
int RencontresNumber(int C[][MAX], int n, int m)
{
    int dp[n+1][m+1] = { 0 };
  
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            if (j <= i) {
  
                // base case
                if (i == 0 && j == 0)
                    dp[i][j] = 1;
  
                // base case
                else if (i == 1 && j == 0)
                    dp[i][j] = 0;
  
                else if (j == 0)
                    dp[i][j] = (i - 1) * (dp[i - 1][0] + 
                                          dp[i - 2][0]);
                else
                    dp[i][j] = C[i][j] * dp[i - j][0];
            }
        }
    }
  
    return dp[n][m];
}
  
// Driver Program
int main()
{
    int n = 7, m = 2;
  
    int C[MAX][MAX];
    binomialCoeff(C, n, m);
  
    cout << RencontresNumber(C, n, m) << endl;
    return 0;
}

Java

// DP based Java program to find n-th Rencontres

2618
Chapter 364. Rencontres Number (Counting partial derangements)

// Number
  
import java.io.*;
  
class GFG {
  
    static int MAX = 100;
  
    // Fills table C[n+1][k+1] such that C[i][j]
    // represents table of binomial coefficient
    // iCj
    static void binomialCoeff(int C[][], int n, int k)
    {
  
        // Calculate value of Binomial Coefficient
        // in bottom up manner
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= Math.min(i, k); j++)
            {
  
                // Base Cases
                if (j == 0 || j == i)
                    C[i][j] = 1;
  
                // Calculate value using previously
                // stored values
                else
                    C[i][j] = C[i - 1][j - 1] + 
                                         C[i - 1][j];
            }
        }
    }
  
    // Return Recontres number D(n, m)
    static int RencontresNumber(int C[][], int n, int m)
    {
        int dp[][] = new int[n + 1][m + 1];
  
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                if (j <= i) {
  
                    // base case
                    if (i == 0 && j == 0)
                        dp[i][j] = 1;
  
                    // base case
                    else if (i == 1 && j == 0)

2619
Chapter 364. Rencontres Number (Counting partial derangements)

                        dp[i][j] = 0;
  
                    else if (j == 0)
                        dp[i][j] = (i - 1) * (dp[i - 1][0] 
                                           + dp[i - 2][0]);
                    else
                        dp[i][j] = C[i][j] * dp[i - j][0];
                }
            }
        }
  
        return dp[n][m];
    }
  
    // Driver Program
    public static void main(String[] args)
    {
        int n = 7, m = 2;
  
        int C[][] = new int[MAX][MAX];
        binomialCoeff(C, n, m);
  
        System.out.println(RencontresNumber(C, n, m));
    }
}
  
// This code is contributed by vt_m.

Python 3

# DP based Python 3 program to find n-th


# Rencontres Number
  
MAX = 100
  
# Fills table C[n+1][k+1] such that C[i][j]
# represents table of binomial coefficient
# iCj
def binomialCoeff(C, n, k) :
      
    # Calculate value of Binomial Coefficient
    # in bottom up manner
    for i in range(0, n + 1) :
        for j in range(0, min(i, k) + 1) :
              
            # Base Cases
            if (j == 0 or j == i) :
                C[i][j] = 1

2620
Chapter 364. Rencontres Number (Counting partial derangements)

  
            # Calculate value using previously
            # stored values
            else :
                C[i][j] = (C[i - 1][j - 1] 
                               + C[i - 1][j])
                  
  
# Return Recontres number D(n, m)
def RencontresNumber(C, n, m) :
    w, h = m+1, n+1
    dp= [[0 for x in range(w)] for y in range(h)] 
      
  
    for i in range(0, n+1) :
        for j in range(0, m+1) :
            if (j <= i) :
                  
                # base case
                if (i == 0 and j == 0) :
                    dp[i][j] = 1
  
                # base case
                elif (i == 1 and j == 0) :
                    dp[i][j] = 0
  
                elif (j == 0) :
                    dp[i][j] = ((i - 1) * 
                     (dp[i - 1][0] + dp[i - 2][0]))
                else :
                    dp[i][j] = C[i][j] * dp[i - j][0]
                      
    return dp[n][m]
  
  
# Driver Program
n = 7
m = 2
C = [[0 for x in range(MAX)] for y in range(MAX)] 
  
binomialCoeff(C, n, m)
  
print(RencontresNumber(C, n, m))
  
# This code is contributed by Nikita Tiwari.

C#

2621
Chapter 364. Rencontres Number (Counting partial derangements)

// DP based C# program 
// to find n-th Rencontres 
// Number
using System;
  
class GFG
{
    static int MAX = 100;
  
    // Fills table C[n+1][k+1]
    // such that C[i][j]
    // represents table of 
    // binomial coefficient iCj
    static void binomialCoeff(int [,]C, 
                              int n, int k)
    {
  
        // Calculate value of 
        // Binomial Coefficient
        // in bottom up manner
        for (int i = 0; i <= n; i++) 
        {
            for (int j = 0; 
                     j <= Math.Min(i, k); j++)
            {
  
                // Base Cases
                if (j == 0 || j == i)
                    C[i,j] = 1;
  
                // Calculate value using 
                // previously stored values
                else
                    C[i, j] = C[i - 1, j - 1] + 
                              C[i - 1, j];
            }
        }
    }
  
    // Return Recontres 
    // number D(n, m)
    static int RencontresNumber(int [,]C, 
                                int n, int m)
    {
        int [,]dp = new int[n + 1, 
                            m + 1];
  
        for (int i = 0; i <= n; i++) 

2622
Chapter 364. Rencontres Number (Counting partial derangements)

        {
            for (int j = 0; j <= m; j++) 
            {
                if (j <= i) 
                {
  
                    // base case
                    if (i == 0 && j == 0)
                        dp[i, j] = 1;
  
                    // base case
                    else if (i == 1 && j == 0)
                        dp[i, j] = 0;
  
                    else if (j == 0)
                        dp[i, j] = (i - 1) * 
                                   (dp[i - 1, 0] + 
                                    dp[i - 2, 0]);
                    else
                        dp[i, j] = C[i, j] *
                                  dp[i - j, 0];
                }
            }
        }
  
        return dp[n, m];
    }
  
    // Driver Code
    static public void Main ()
    {
        int n = 7, m = 2;
        int [,]C = new int[MAX, MAX];
        binomialCoeff(C, n, m);
      
        Console.WriteLine(RencontresNumber(C, n, m));
    }
}
  
// This code is contributed
// by akt_mit

Output:

924

Improved By : Nikita tiwari, Smitha Dinesh Semwal, jit_t

2623
Chapter 364. Rencontres Number (Counting partial derangements)

Source

https://www.geeksforgeeks.org/rencontres-number-counting-partial-derangements/

2624
Chapter 365

Semiperfect Number

Semiperfect Number - GeeksforGeeks


In number theory, a semiperfect number or pseudoperfect number is a natural number n
that is equal to the sum of all or some of its proper divisors. A semiperfect number that is
equal to the sum of all its proper divisors is a perfect number.
Given a number, the task is to check if the number is a semi-perfect number or not.
Examples:

Input: 40
Output: The number is Semiperfect
1+4+5+10+20=40
Input: 70
Output: The number is not Semiperfect
The first few semiperfect numbers are
6, 12, 18, 20, 24, 28, 30, 36, 40

Approach: Store all th factors of the number in a data-structure(Vector or Arrays). Sort


them in increasing order. Once the factors are stored, Dynamic programming can be used
to check if any combination forms N or not. The problem becomes similar to the Subset
Sum Problem. We can use the same approach and check if the number is a semi-perfect
number or not.
Below is the implementation of the above approach.

// C++ program to check if the number


// is semi-perfect or not
#include <bits/stdc++.h>
using namespace std;
  
// code to find all the factors of

2625
Chapter 365. Semiperfect Number

// the number excluding the number itself


vector<int> factors(int n)
{
    // vector to store the factors
    vector<int> v;
    v.push_back(1);
  
    // note that this loop runs till sqrt(n)
    for (int i = 2; i <= sqrt(n); i++) {
  
        // if the value of i is a factor
        if (n % i == 0) {
            v.push_back(i);
  
            // condition to check the
            // divisor is not the number itself
            if (n / i != i) {
                v.push_back(n / i);
            }
        }
    }
    // return the vector
    return v;
}
  
// Function to check if the
// number is semi-perfecr or not
bool check(int n)
{
    vector<int> v;
  
    // find the divisors
    v = factors(n);
  
    // sorting the vector
    sort(v.begin(), v.end());
  
    int r = v.size();
  
    // subset to check if no is semiperfect
    bool subset[r + 1][n + 1];
  
    // initialising 1st column to true
    for (int i = 0; i <= r; i++)
        subset[i][0] = true;
  
    // initialing 1st row except zero position to 0
    for (int i = 1; i <= n; i++)

2626
Chapter 365. Semiperfect Number

        subset[0][i] = false;
  
    // loop to find whther the number is semiperfect
    for (int i = 1; i <= r; i++) {
        for (int j = 1; j <= n; j++) {
  
            // calculation to check if the
            // number can be made by summation of diviors
            if (j < v[i - 1])
                subset[i][j] = subset[i - 1][j];
            else {
                subset[i][j] = subset[i - 1][j] || 
                               subset[i - 1][j - v[i - 1]];
            }
        }
    }
  
    // if not possible to make the
    // number by any combination of divisors
    if ((subset[r][n]) == 0)
        return false;
    else
        return true;
}
  
// driver code to check if possible
int main()
{
    int n = 40;
    if (check(n))
        cout << "Yes";
    else
        cout << "No";
    return 0;
}

Output:

Yes

Time Complexity: O(number of factors * N)


Auxiliary Space: O(number of factors * N)

Source

https://www.geeksforgeeks.org/semiperfect-number/

2627
Chapter 366

Sequence Alignment problem

Sequence Alignment problem - GeeksforGeeks

Given as an input two strings, = , and = ,


output the alignment of the strings, character by character, so that the net penalty is
minimised. The penalty is calculated as:
1. A penalty of occurs if a gap is inserted between the string.
2. A penalty of occurs for mis-matching the characters of and .
Examples:

Input : X = CG, Y = CA, p_gap = 3, p_xy = 7


Output : X = CG_, Y = C_A, Total penalty = 6

Input : X = AGGGCT, Y = AGGCA, p_gap = 3, p_xy = 2


Output : X = AGGGCT, Y = A_GGCA, Total penalty = 5

Input : X = CG, Y = CA, p_gap = 3, p_xy = 5


Output : X = CG, Y = CA, Total penalty = 5

A brief Note on the history of the problem


The Sequence Alignment problem is one of the fundamental problems of Biological Sciences,
aimed at finding the similarity of two amino-acid sequences. Comparing amino-acids is of
prime importance to humans, since it gives vital information on evolution and development.
Saul B. Needleman and Christian D. Wunsch devised a dynamic programming algorithm to
the problem and got it published in 1970. Since then, numerous improvements have been
made to improve the time complexity and space complexity, however these are beyond the
scope of discussion in this post.
Solution We can use dynamic programming to solve this problem. The feasible solution is
to introduce gaps into the strings, so as to equalise the lengths. Since it can be easily proved

2628
Chapter 366. Sequence Alignment problem

that the addition of extra gaps after equalising the lengths will only lead to increment of
penalty.
Optimal Substructure
It can be observed from an optimal solution, for example from the given sample input, that
the optimal solution narrows down to only three candidates.
1. and .
2. and gap.
3. gap and .
Proof of Optimal Substructure.

We can easily prove by contradiction. Let be and be

. Suppose that the induced alignment of , has some penalty , and a


competitor alignment has a penalty , with .

Now, appending and , we get an alignment with penalty .

This contradicts the optimality of the original alignment of .


Hence, proved.

Let be the penalty of the optimal alignment of and . Then, from the

optimal substructure,
.

The total minimum penalty is thus, .


Reconstructing the solution
To Reconstruct,

1. Trace back through the filled table, starting .

2. When

…..2a. if it was filled using case 1, go to .

…..2b. if it was filled using case 2, go to .

…..2c. if it was filled using case 3, go to .


3. if either i = 0 or j = 0, match the remaining substring with gaps.
Below is the implementation of the above solution.
C++

// CPP program to implement sequence alignment


// problem.
#include <bits/stdc++.h>

2629
Chapter 366. Sequence Alignment problem

  
using namespace std;
  
// function to find out the minimum penalty
void getMinimumPenalty(string x, string y, int pxy, int pgap)
{
    int i, j; // intialising variables
      
    int m = x.length(); // length of gene1
    int n = y.length(); // length of gene2
      
    // table for storing optimal substructure answers
    int dp[n+m+1][n+m+1] = {0};
  
    // intialising the table 
    for (i = 0; i <= (n+m); i++)
    {
        dp[i][0] = i * pgap;
        dp[0][i] = i * pgap;
    }    
  
    // calcuting the minimum penalty
    for (i = 1; i <= m; i++)
    {
        for (j = 1; j <= n; j++)
        {
            if (x[i - 1] == y[j - 1])
            {
                dp[i][j] = dp[i - 1][j - 1];
            }
            else
            {
                dp[i][j] = min({dp[i - 1][j - 1] + pxy , 
                                dp[i - 1][j] + pgap    , 
                                dp[i][j - 1] + pgap    });
            }
        }
    }
  
    // Reconstructing the solution
    int l = n + m; // maximum possible length
      
    i = m; j = n;
      
    int xpos = l;
    int ypos = l;
  
    // Final answers for the respective strings

2630
Chapter 366. Sequence Alignment problem

    int xans[l+1], yans[l+1];


      
    while ( !(i == 0 || j == 0))
    {
        if (x[i - 1] == y[j - 1])
        {
            xans[xpos--] = (int)x[i - 1];
            yans[ypos--] = (int)y[j - 1];
            i--; j--;
        }
        else if (dp[i - 1][j - 1] + pxy == dp[i][j])
        {
            xans[xpos--] = (int)x[i - 1];
            yans[ypos--] = (int)y[j - 1];
            i--; j--;
        }
        else if (dp[i - 1][j] + pgap == dp[i][j])
        {
            xans[xpos--] = (int)x[i - 1];
            yans[ypos--] = (int)'_';
            i--;
        }
        else if (dp[i][j - 1] + pgap == dp[i][j])
        {
            xans[xpos--] = (int)'_';
            yans[ypos--] = (int)y[j - 1];
            j--;
        }
    }
    while (xpos > 0)
    {
        if (i > 0) xans[xpos--] = (int)x[--i];
        else xans[xpos--] = (int)'_';
    }
    while (ypos > 0)
    {
        if (j > 0) yans[ypos--] = (int)y[--j];
        else yans[ypos--] = (int)'_';
    }
  
    // Since we have assumed the answer to be n+m long, 
    // we need to remove the extra gaps in the starting 
    // id represents the index from which the arrays
    // xans, yans are useful
    int id = 1;
    for (i = l; i >= 1; i--)
    {
        if ((char)yans[i] == '_' && (char)xans[i] == '_')

2631
Chapter 366. Sequence Alignment problem

        {
            id = i + 1;
            break;
        }
    }
  
    // Printing the final answer
    cout << "Minimum Penalty in aligning the genes = ";
    cout << dp[m][n] << "\n";
    cout << "The aligned genes are :\n";
    for (i = id; i <= l; i++)
    {
        cout<<(char)xans[i];
    }
    cout << "\n";
    for (i = id; i <= l; i++)
    {
        cout << (char)yans[i];
    }
    return;
}
  
// Driver code
int main(){
    // input strings
    string gene1 = "AGGGCT";
    string gene2 = "AGGCA";
      
    // intialsing penalties of different types
    int misMatchPenalty = 3;
    int gapPenalty = 2;
  
    // calling the function to calculate the result
    getMinimumPenalty(gene1, gene2, 
        misMatchPenalty, gapPenalty);
    return 0;
}

Java

// Java program to implement 


// sequence alignment problem.
import java.io.*;
import java.util.*;
import java.lang.*;
  
class GFG
{

2632
Chapter 366. Sequence Alignment problem

// function to find out 


// the minimum penalty
static void getMinimumPenalty(String x, String y, 
                              int pxy, int pgap)
{
    int i, j; // intialising variables
      
    int m = x.length(); // length of gene1
    int n = y.length(); // length of gene2
      
    // table for storing optimal
    // substructure answers
    int dp[][] = new int[n + m + 1][n + m + 1];
      
    for (int[] x1 : dp)
    Arrays.fill(x1, 0);
  
    // intialising the table 
    for (i = 0; i <= (n + m); i++)
    {
        dp[i][0] = i * pgap;
        dp[0][i] = i * pgap;
    } 
  
    // calcuting the 
    // minimum penalty
    for (i = 1; i <= m; i++)
    {
        for (j = 1; j <= n; j++)
        {
            if (x.charAt(i - 1) == y.charAt(j - 1))
            {
                dp[i][j] = dp[i - 1][j - 1];
            }
            else
            {
                dp[i][j] = Math.min(Math.min(dp[i - 1][j - 1] + pxy , 
                                             dp[i - 1][j] + pgap) , 
                                             dp[i][j - 1] + pgap );
            }
        }
    }
  
    // Reconstructing the solution
    int l = n + m; // maximum possible length
      
    i = m; j = n;
      

2633
Chapter 366. Sequence Alignment problem

    int xpos = l;
    int ypos = l;
  
    // Final answers for 
    // the respective strings
    int xans[] = new int[l + 1]; 
    int yans[] = new int[l + 1];
      
    while ( !(i == 0 || j == 0))
    {
        if (x.charAt(i - 1) == y.charAt(j - 1))
        {
            xans[xpos--] = (int)x.charAt(i - 1);
            yans[ypos--] = (int)y.charAt(j - 1);
            i--; j--;
        }
        else if (dp[i - 1][j - 1] + pxy == dp[i][j])
        {
            xans[xpos--] = (int)x.charAt(i - 1);
            yans[ypos--] = (int)y.charAt(j - 1);
            i--; j--;
        }
        else if (dp[i - 1][j] + pgap == dp[i][j])
        {
            xans[xpos--] = (int)x.charAt(i - 1);
            yans[ypos--] = (int)'_';
            i--;
        }
        else if (dp[i][j - 1] + pgap == dp[i][j])
        {
            xans[xpos--] = (int)'_';
            yans[ypos--] = (int)y.charAt(j - 1);
            j--;
        }
    }
    while (xpos > 0)
    {
        if (i > 0) xans[xpos--] = (int)x.charAt(--i);
        else xans[xpos--] = (int)'_';
    }
    while (ypos > 0)
    {
        if (j > 0) yans[ypos--] = (int)y.charAt(--j);
        else yans[ypos--] = (int)'_';
    }
  
    // Since we have assumed the 
    // answer to be n+m long, 

2634
Chapter 366. Sequence Alignment problem

    // we need to remove the extra 


    // gaps in the starting id 
    // represents the index from 
    // which the arrays xans,
    // yans are useful
    int id = 1;
    for (i = l; i >= 1; i--)
    {
        if ((char)yans[i] == '_' && 
            (char)xans[i] == '_')
        {
            id = i + 1;
            break;
        }
    }
  
    // Printing the final answer
    System.out.print("Minimum Penalty in " + 
                     "aligning the genes = ");
    System.out.print(dp[m][n] + "\n");
    System.out.println("The aligned genes are :");
    for (i = id; i <= l; i++)
    {
        System.out.print((char)xans[i]);
    }
    System.out.print("\n");
    for (i = id; i <= l; i++)
    {
        System.out.print((char)yans[i]);
    }
    return;
}
  
// Driver code
public static void main(String[] args)
{
    // input strings
    String gene1 = "AGGGCT";
    String gene2 = "AGGCA";
      
    // intialsing penalties
    // of different types
    int misMatchPenalty = 3;
    int gapPenalty = 2;
  
    // calling the function to
    // calculate the result
    getMinimumPenalty(gene1, gene2, 

2635
Chapter 366. Sequence Alignment problem

        misMatchPenalty, gapPenalty);
}
}

PHP

<?php
// PHP program to implement 
// sequence alignment problem.
  
// function to find out
// the minimum penalty
function getMinimumPenalty($x, $y, 
                           $pxy, $pgap)
{
    $i; $j; // intializing variables
      
    $m = strlen($x); // length of gene1
    $n = strlen($y); // length of gene2
      
    // table for storing optimal
    // substructure answers
    $dp[$n + $m + 1][$n + $m + 1] = array(0);
  
    // intialising the table 
    for ($i = 0; $i <= ($n+$m); $i++)
    {
        $dp[$i][0] = $i * $pgap;
        $dp[0][$i] = $i * $pgap;
    } 
  
    // calcuting the 
    // minimum penalty
    for ($i = 1; $i <= $m; $i++)
    {
        for ($j = 1; $j <= $n; $j++)
        {
            if ($x[$i - 1] == $y[$j - 1])
            {
                $dp[$i][$j] = $dp[$i - 1][$j - 1];
            }
            else
            {
                $dp[$i][$j] = min($dp[$i - 1][$j - 1] + $pxy , 
                                  $dp[$i - 1][$j] + $pgap , 
                                  $dp[$i][$j - 1] + $pgap );
            }
        }

2636
Chapter 366. Sequence Alignment problem

    }
  
    // Reconstructing the solution
    $l = $n + $m; // maximum possible length
      
    $i = $m; $j = $n;
      
    $xpos = $l;
    $ypos = $l;
  
    // Final answers for 
    // the respective strings
    // $xans[$l + 1]; $yans[$l + 1];
      
    while ( !($i == 0 || $j == 0))
    {
        if ($x[$i - 1] == $y[$j - 1])
        {
            $xans[$xpos--] = $x[$i - 1];
            $yans[$ypos--] = $y[$j - 1];
            $i--; $j--;
        }
        else if ($dp[$i - 1][$j - 1] + 
                 $pxy == $dp[$i][$j])
        {
            $xans[$xpos--] = $x[$i - 1];
            $yans[$ypos--] = $y[$j - 1];
            $i--; $j--;
        }
        else if ($dp[$i - 1][$j] + 
                 $pgap == $dp[$i][$j])
        {
            $xans[$xpos--] = $x[$i - 1];
            $yans[$ypos--] = '_';
            $i--;
        }
        else if ($dp[$i][$j - 1] + 
                 $pgap == $dp[$i][$j])
        {
            $xans[$xpos--] = '_';
            $yans[$ypos--] = $y[$j - 1];
            $j--;
        }
    }
    while ($xpos > 0)
    {
        if ($i > 0) $xans[$xpos--] = $x[--$i];
        else $xans[$xpos--] = '_';

2637
Chapter 366. Sequence Alignment problem

    }
    while ($ypos > 0)
    {
        if ($j > 0) 
            $yans[$ypos--] = $y[--$j];
        else 
            $yans[$ypos--] = '_';
    }
  
    // Since we have assumed the
    // answer to be n+m long, 
    // we need to remove the extra
    // gaps in the starting 
    // id represents the index 
    // from which the arrays
    // xans, yans are useful
    $id = 1;
    for ($i = $l; $i >= 1; $i--)
    {
        if ($yans[$i] == '_' && 
            $xans[$i] == '_')
        {
            $id = $i + 1;
            break;
        }
    }
  
    // Printing the final answer
    echo "Minimum Penalty in ". 
         "aligning the genes = ";
    echo $dp[$m][$n] . "\n";
    echo "The aligned genes are :\n";
    for ($i = $id; $i <= $l; $i++)
    {
        echo $xans[$i];
    }
    echo "\n";
    for ($i = $id; $i <= $l; $i++)
    {
        echo $yans[$i];
    }
    return;
}
  
// Driver code
  
// input strings
$gene1 = "AGGGCT";

2638
Chapter 366. Sequence Alignment problem

$gene2 = "AGGCA";
  
// intialsing penalties
// of different types
$misMatchPenalty = 3;
$gapPenalty = 2;
  
// calling the function 
// to calculate the result
getMinimumPenalty($gene1, $gene2, 
    $misMatchPenalty, $gapPenalty);
  
// This code is contributed by Abhinav96
?>

Output:

Minimum Penalty in aligning the genes = 5


The aligned genes are :
AGGGCT
A_GGCA

Time Complexity :

Space Complexity :
Improved By : AayushChaturvedi

Source

https://www.geeksforgeeks.org/sequence-alignment-problem/

2639
Chapter 367

Sequences of given length where


every element is more than or
equal to twice of previous

Sequences of given length where every element is more than or equal to twice of previous -
GeeksforGeeks
Given two integers m & n, find the number of possible sequences of length n such that each
of the next element is greater than or equal to twice of the previous element but less than
or equal to m.
Examples :

Input : m = 10, n = 4
Output : 4
There should be n elements and value of last
element should be at-most m.
The sequences are {1, 2, 4, 8}, {1, 2, 4, 9},
{1, 2, 4, 10}, {1, 2, 5, 10}

Input : m = 5, n = 2
Output : 6
The sequences are {1, 2}, {1, 3}, {1, 4},
{1, 5}, {2, 4}, {2, 5}

As per the given condition the n-th value of the sequence can be at most m. There can be
two cases for n-th element:

1. If it is m, then the (n-1)th element is at most m/2. We recur for m/2 and n-1.
2. If it is not m, then the n-1th element is at most is m-1. We recur for (m-1) and n.

2640
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

The total number of sequences is the sum of the number of sequences including m and the
number of sequences where m is not included. Thus the original problem of finding number
of sequences of length n with max value m can be subdivided into independent subproblems
of finding number of sequences of length n with max value m-1 and number of sequences of
length n-1 with max value m/2.
C++

// C program to count total number of special sequences


// of length n where
#include <stdio.h>
  
// Recursive function to find the number of special
// sequences
int  getTotalNumberOfSequences(int m, int n)
{
    // A special sequence cannot exist if length
    // n is more than the maximum value m.
    if (m < n)
        return 0;
  
    // If n is 0, found an empty special sequence
    if (n == 0)
        return 1;
  
    // There can be two possibilities : (1) Reduce
    // last element value (2) Consider last element
    // as m and reduce number of terms
    return getTotalNumberOfSequences (m-1, n) +
           getTotalNumberOfSequences (m/2, n-1);
}
  
// Driver Code
int main()
{
    int m = 10;
    int n = 4;
    printf("Total number of possible sequences %d",
                   getTotalNumberOfSequences(m, n));
    return 0;
}

Java

// Java program to count total number 


// of special sequences of length n where
class Sequences
{

2641
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

    // Recursive function to find the number of special


    // sequences
    static int  getTotalNumberOfSequences(int m, int n)
    {
        // A special sequence cannot exist if length
        // n is more than the maximum value m.
        if(m < n)
            return 0;
       
        // If n is 0, found an empty special sequence
        if(n == 0)
            return 1;
       
        // There can be two possibilities : (1) Reduce
        // last element value (2) Consider last element
        // as m and reduce number of terms
        return getTotalNumberOfSequences (m-1, n) +
               getTotalNumberOfSequences (m/2, n-1);
    }   
      
    // main function
    public static void main (String[] args) 
    {
        int m = 10;
        int n = 4;
        System.out.println("Total number of possible sequences "+
                       getTotalNumberOfSequences(m, n));
    }
}

C#

// C# program to count total number 


// of special sequences of length n 
// where every element is more than 
// or equal to twice of previous
using System;
  
class GFG
{
    // Recursive function to find 
    // the number of special sequences
    static int getTotalNumberOfSequences(int m, int n)
    {
        // A special sequence cannot exist if length
        // n is more than the maximum value m.
        if(m < n)
            return 0;

2642
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

      
        // If n is 0, found an empty special sequence
        if(n == 0)
            return 1;
      
        // There can be two possibilities : (1) Reduce
        // last element value (2) Consider last element
        // as m and reduce number of terms
        return getTotalNumberOfSequences (m-1, n) +
               getTotalNumberOfSequences (m/2, n-1);
    } 
      
    // Driver code
    public static void Main () 
    {
        int m = 10;
        int n = 4;
        Console.Write("Total number of possible sequences " +
                           getTotalNumberOfSequences(m, n));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to count total 
// number of special sequences
// of length n where
  
// Recursive function to find 
// the number of special sequences
function getTotalNumberOfSequences($m, $n)
{
      
    // A special sequence cannot 
    // exist if length n is more 
    // than the maximum value m.
    if ($m < $n)
        return 0;
  
    // If n is 0, found an empty 
    // special sequence
    if ($n == 0)
        return 1;
  
    // There can be two possibilities : 

2643
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

    // (1) Reduce last element value


    // (2) Consider last element
    // as m and reduce number of terms
    return getTotalNumberOfSequences($m - 1, $n) +
           getTotalNumberOfSequences($m / 2, $n - 1);
}
  
    // Driver Code
    $m = 10;
    $n = 4;
    echo("Total number of possible sequences ");
    echo (getTotalNumberOfSequences($m, $n));
  
// This code is contributed by nitin mittal.
?>

Output:

Total number of possible sequences 4

Note that the above function computes the same sub problems again and again. Consider
the following tree for f(10, 4).

Recursive Tree for m= 10 and N =4


We can solve this problem using dynamic programming.
C++

2644
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

// C program to count total number of special sequences


// of length N where
#include <stdio.h>
  
// DP based function to find the number of special
// sequences
int  getTotalNumberOfSequences(int m, int n)
{
        // define T and build in bottom manner to store
        // number of special sequences of length n and
        // maximum value m
        int T[m+1][n+1];
        for (int i=0; i<m+1; i++)
        {
            for (int j=0; j<n+1; j++)
            {
                // Base case : If length of sequence is 0
                // or maximum value is 0, there cannot
                // exist any special sequence
                if (i == 0 || j == 0)
                    T[i][j] = 0;
  
                // if length of sequence is more than
                // the maximum value, special sequence
                // cannot exist
                else if (i < j)
                    T[i][j] = 0;
  
                // If length of sequence is 1 then the
                // number of special sequences is equal
                // to the maximum value
                // For example with maximum value 2 and
                // length 1, there can be 2 special
                // sequences {1}, {2}
                else if (j == 1)
                    T[i][j] = i;
  
                // otherwise calculate
                else
                    T[i][j] = T[i-1][j] + T[i/2][j-1];
            }
        }
        return T[m][n];
}
  
// Driver Code
int main()
{

2645
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

    int m = 10;
    int n = 4;
    printf("Total number of possible sequences %d",
                   getTotalNumberOfSequences(m, n));
    return 0;
}

Java

// Efficient java program to count total number 


// of special sequences of length n where
class Sequences
{
    // DP based function to find the number of special
    // sequences
    static int  getTotalNumberOfSequences(int m, int n)
    {
            // define T and build in bottom manner to store
            // number of special sequences of length n and
            // maximum value m
            int T[][]=new int[m+1][n+1];
            for (int i=0; i<m+1; i++)
            {
                for (int j=0; j<n+1; j++)
                {
                    // Base case : If length of sequence is 0
                    // or maximum value is 0, there cannot
                    // exist any special sequence
                    if (i == 0 || j == 0)
                        T[i][j] = 0;
       
                    // if length of sequence is more than
                    // the maximum value, special sequence
                    // cannot exist
                    else if (i < j)
                        T[i][j] = 0;
       
                    // If length of sequence is 1 then the
                    // number of special sequences is equal
                    // to the maximum value
                    // For example with maximum value 2 and
                    // length 1, there can be 2 special
                    // sequences {1}, {2}
                    else if (j == 1)
                        T[i][j] = i;
       
                    // otherwise calculate
                    else

2646
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

                        T[i][j] = T[i-1][j] + T[i/2][j-1];


                }
            }
            return T[m][n];
    }
      
    // main function
    public static void main (String[] args) 
    {
        int m = 10;
        int n = 4;
        System.out.println("Total number of possible sequences "+
                       getTotalNumberOfSequences(m, n));
    }
}

C#

// Efficient C# program to count total number 


// of special sequences of length n where
using System;
class Sequences {
      
    // DP based function to find
    // the number of special
    // sequences
    static int getTotalNumberOfSequences(int m, int n)
    {
          
            // define T and build in
            // bottom manner to store
            // number of special sequences
            // of length n and maximum value m
            int [,]T=new int[m + 1, n + 1];
              
            for (int i = 0; i < m + 1; i++)
            {
                for (int j = 0; j < n + 1; j++)
                {
                      
                    // Base case : If length 
                    // of sequence is 0
                    // or maximum value is 
                    // 0, there cannot
                    // exist any special 
                    // sequence
                    if (i == 0 || j == 0)
                        T[i, j] = 0;

2647
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

      
                    // if length of sequence
                    // is more than the maximum
                    // value, special sequence
                    // cannot exist
                    else if (i < j)
                        T[i,j] = 0;
      
                    // If length of sequence is 1 then the
                    // number of special sequences is equal
                    // to the maximum value
                    // For example with maximum value 2 and
                    // length 1, there can be 2 special
                    // sequences {1}, {2}
                    else if (j == 1)
                        T[i,j] = i;
      
                    // otherwise calculate
                    else
                        T[i,j] = T[i - 1, j] + T[i / 2, j - 1];
                }
            }
            return T[m,n];
    }
      
    // Driver Code
    public static void Main () 
    {
        int m = 10;
        int n = 4;
        Console.WriteLine("Total number of possible sequences "+
                                getTotalNumberOfSequences(m, n));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to count total
// number of special sequences
// of length N where
  
// DP based function to find
// the number of special
// sequences
function getTotalNumberOfSequences($m, $n)

2648
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

{
      
        // define T and build in bottom
        // manner to store number of 
        // special sequences of length 
        // n and maximum value m
        $T = array(array());
          
        for ($i = 0; $i < $m + 1; $i++)
        {
            for ($j = 0; $j < $n + 1; $j++)
            {
                  
                // Base case : If length of 
                // sequence is 0 or maximum
                // value is 0, there cannot
                // exist any special sequence
                if ($i == 0 or $j == 0)
                    $T[$i][$j] = 0;
  
                // if length of sequence is 
                // more than the maximum value,
                // special sequence cannot exist
                else if ($i < $j)
                    $T[$i][$j] = 0;
  
                // If length of sequence is
                // 1 then the number of 
                // special sequences is equal
                // to the maximum value
                // For example with maximum 
                // value 2 and length 1, there
                // can be 2 special sequences 
                // {1}, {2}
                else if ($j == 1)
                    $T[$i][$j] = $i;
  
                // otherwise calculate
                else
                    $T[$i][$j] = $T[$i - 1][$j] + 
                                 $T[$i / 2][$j - 1];
            }
        }
        return $T[$m][$n];
}
  
    // Driver Code
    $m = 10;

2649
Chapter 367. Sequences of given length where every element is more than or equal to twice
of previous

    $n = 4;
    echo "Total number of possible sequences ",
            getTotalNumberOfSequences($m, $n);
  
// This code is contributed by anuj_67.
?>

Output:

Time Complexity : O(m x n)


Auxiliary Space : O(m x n)
Improved By : nitin mittal, vt_m

Source

https://www.geeksforgeeks.org/sequences-given-length-every-element-equal-twice-previous/

2650
Chapter 368

Shortest Common
Supersequence

Shortest Common Supersequence - GeeksforGeeks


Given two strings str1 and str2, find the shortest string that has both str1 and str2 as
subsequences.
Examples :

Input: str1 = "geek", str2 = "eke"


Output: "geeke"

Input: str1 = "AGGTAB", str2 = "GXTXAYB"


Output: "AGXGTXAYB"

This problem is closely related to longest common subsequence problem. Below are steps.
1) Find Longest Common Subsequence (lcs) of two given strings. For example, lcs of “geek”
and “eke” is “ek”.
2) Insert non-lcs characters (in their original order in strings) to the lcs found above, and
return the result. So “ek” becomes “geeke” which is shortest common supersequence.
Let us consider another example, str1 = “AGGTAB” and str2 = “GXTXAYB”. LCS of str1
and str2 is “GTAB”. Once we find LCS, we insert characters of both strings in order and
we get “AGXGTXAYB”
How does this work?
We need to find a string that has both strings as subsequences and is shortest such string. If
both strings have all characters different, then result is sum of lengths of two given strings.
If there are common characters, then we don’t want them multiple times as the task is
to minimize length. Therefore, we fist find the longest common subsequence, take one
occurrence of this subsequence and add extra characters.

2651
Chapter 368. Shortest Common Supersequence

Length of the shortest supersequence = (Sum of lengths of given two strings) -


(Length of LCS of two given strings)

Below is the implementation of above idea. The below implementation only finds length of
the shortest supersequence.

// C program to find length of


// the shortest supersequence
#include<stdio.h>
#include<string.h>
  
// Utility function to get 
// max of 2 integers
int max(int a, int b)
    {
        return (a > b)? a : b;
    }
  
// Returns length of LCS for
// X[0..m - 1], Y[0..n - 1]
int lcs( char *X, char *Y, 
            int m, int n);
  
// Function to find length of the
// shortest supersequence of X and Y.
int shortestSuperSequence(char *X, char *Y)
    {
        int m = strlen(X), n = strlen(Y);
  
        // find lcs
        int l = lcs(X, Y, m, n);
  
        // Result is sum of input string
        // lengths - length of lcs
        return (m + n - l);
    }
  
// Returns length of LCS
// for X[0..m - 1], Y[0..n - 1]
int lcs( char *X, char *Y,
              int m, int n)
    {
        int L[m + 1][n + 1];

2652
Chapter 368. Shortest Common Supersequence

        int i, j;
  
        // Following steps build L[m + 1][n + 1] 
        // in bottom up fashion. Note that 
        // L[i][j] contains length of LCS of 
        // X[0..i - 1] and Y[0..j - 1]
        for (i = 0; i <= m; i++)
        {
            for (j = 0; j <= n; j++)
            {
                if (i == 0 || j == 0)
                    L[i][j] = 0;
  
                else if (X[i - 1] == Y[j - 1])
                    L[i][j] = L[i - 1][j - 1] + 1;
  
                else
                    L[i][j] = max(L[i - 1][j],
                                  L[i][j - 1]);
            }
        }
  
    // L[m][n] contains length of LCS
    // for X[0..n - 1] and Y[0..m - 1]
    return L[m][n];
    }
  
// Driver code
int main()
{
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
  
    printf("Length of the shortest supersequence is %d\n",
                            shortestSuperSequence(X, Y));
          
    return 0;
}

Java

// Java program to find length of


// the shortest supersequence
class GFG
{
          
    // Function to find length of the 
    // shortest supersequence of X and Y.

2653
Chapter 368. Shortest Common Supersequence

    static int shortestSuperSequence(String X,


                                    String Y)
    {
    int m = X.length();
    int n = Y.length();
      
    // find lcs
    int l = lcs(X, Y, m, n);
      
    // Result is sum of input string
    // lengths - length of lcs
    return (m + n - l);
    }
      
    // Returns length of LCS
    // for X[0..m - 1], Y[0..n - 1]
    static int lcs(String X, String Y,
                         int m, int n)
    {
    int[][] L = new int[m + 1][n + 1];
    int i, j;
      
    // Following steps build L[m + 1][n + 1]
    // in bottom up fashion. Note that
    // L[i][j] contains length of LCS
    // of X[0..i - 1]and Y[0..j - 1]
    for (i = 0; i <= m; i++)
    {
        for (j = 0; j <= n; j++)
        {
        if (i == 0 || j == 0)
            L[i][j] = 0;
      
        else if (X.charAt(i - 1) == Y.charAt(j - 1))
            L[i][j] = L[i - 1][j - 1] + 1;
      
        else
            L[i][j] = Math.max(L[i - 1][j],
                               L[i][j - 1]);
        }
    }
      
    // L[m][n] contains length of LCS
    // for X[0..n - 1] and Y[0..m - 1]
    return L[m][n];
    }
      
    // Driver code

2654
Chapter 368. Shortest Common Supersequence

    public static void main(String args[])


    {
    String X = "AGGTAB";
    String Y = "GXTXAYB";
      
    System.out.println("Length of the shortest " +
                             "supersequence is " +
                      shortestSuperSequence(X, Y));
    }
}
  
// This article is contributed by Sumit Ghosh

Python3

# Python program to find length


# of the shortest supersequence
  
# Function to find length of the
# shortest supersequence of X and Y.
def shortestSuperSequence(X, Y):
    m = len(X)
    n = len(Y)
    l = lcs(X, Y, m, n)
      
    # Result is sum of input string
    # lengths - length of lcs
    return (m + n - l)
  
# Returns length of LCS for
# X[0..m - 1], Y[0..n - 1]
def lcs(X, Y, m, n):
    L = [[0] * (n + 2) for i in
                    range(m + 2)]
      
    # Following steps build L[m + 1][n + 1]
    # in bottom up fashion. Note that L[i][j]
    # contains length of LCS of X[0..i - 1]
    # and Y[0..j - 1]
    for i in range(m + 1):
          
        for j in range(n + 1):
              
            if (i == 0 or j == 0) : L[i][j] = 0
              
            elif (X[i - 1] == Y[j - 1]) :
                L[i][j] = L[i - 1][j - 1] + 1
                  

2655
Chapter 368. Shortest Common Supersequence

            else : L[i][j] = max(L[i - 1][j],


                                 L[i][j - 1])
              
    # L[m][n] contains length of
    # LCS for X[0..n - 1] and Y[0..m - 1]
    return L[m][n]
  
# Driver code
X = "AGGTAB"
Y = "GXTXAYB"
  
print("Length of the shortest supersequence is %d"
                      % shortestSuperSequence(X, Y))
  
# This code is contributed by Ansu Kumari

C#

// C# program to find length of


// the shortest supersequence
using System;
  
class GFG
{
    // Function to find length of the
    // shortest supersequence of X and Y.
    static int shortestSuperSequence(String X,
                                    String Y)
    {
    int m = X.Length;
    int n = Y.Length;
      
    // find lcs
    int l = lcs(X, Y, m, n);
      
    // Result is sum of input string
    // lengths - length of lcs
    return (m + n - l);
    }
      
    // Returns length of LCS for
    // X[0..m - 1], Y[0..n - 1]
    static int lcs(String X, String Y,
                        int m, int n)
    {
    int[,] L = new int[m + 1, n + 1];
    int i, j;
      

2656
Chapter 368. Shortest Common Supersequence

    // Following steps build L[m + 1][n + 1]


    // in bottom up fashion.Note that
    // L[i][j] contains length of LCS of
    // X[0..i - 1] and Y[0..j - 1]
    for (i = 0; i <= m; i++)
    {
        for (j = 0; j <= n; j++)
        {
        if (i == 0 || j == 0)
            L[i, j] = 0;
      
        else if (X[i - 1] == Y[j - 1])
            L[i, j] = L[i - 1, j - 1] + 1;
      
        else
            L[i, j] = Math.Max(L[i - 1, j],
                               L[i, j - 1]);
        }
    }
      
    // L[m][n] contains length of LCS
    // for X[0..n - 1] and Y[0..m - 1]
    return L[m, n];
    }
      
    // Driver code
    public static void Main()
    {
    String X = "AGGTAB";
    String Y = "GXTXAYB";
      
    Console.WriteLine("Length of the shortest" +
                           "supersequence is " +
                    shortestSuperSequence(X, Y));
    }
}
  
// This code is contributed by Sam007

Output:

Length of the shortest supersequence is 9

Below is Another Method to solve the above problem.


A simple analysis yields below simple recursive solution.

2657
Chapter 368. Shortest Common Supersequence

Let X[0..m - 1] and Y[0..n - 1] be two strings and m and n be respective


lengths.

if (m == 0) return n;
if (n == 0) return m;

// If last characters are same, then add 1 to result and


// recur for X[]
if (X[m - 1] == Y[n - 1])
return 1 + SCS(X, Y, m - 1, n - 1);

// Else find shortest of following two


// a) Remove last character from X and recur
// b) Remove last character from Y and recur
else return 1 + min( SCS(X, Y, m - 1, n), SCS(X, Y, m, n - 1) );

Below is simple naive recursive solution based on above recursive formula.

C++

// A Naive recursive C++ program to find


// length of the shortest supersequence 
#include<bits/stdc++.h>
using namespace std;
  
int superSeq(char* X, char* Y, int m, int n)
{
    if (!m) return n;
    if (!n) return m;
  
    if (X[m - 1] == Y[n - 1])
        return 1 + superSeq(X, Y, m - 1, n - 1);
  
    return 1 + min(superSeq(X, Y, m - 1, n),
                superSeq(X, Y, m, n - 1));
}
  
// Driver Code
int main()
{
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
    cout << "Length of the shortest supersequence is "
        << superSeq(X, Y, strlen(X), strlen(Y));
    return 0;
}

Java

2658
Chapter 368. Shortest Common Supersequence

// A Naive recursive Java program to find 


// length of the shortest supersequence
class GFG 
{
    static int superSeq(String X, String Y, 
                                  int m, int n)
    {
        if (m == 0) return n;
        if (n == 0) return m;
      
        if (X.charAt(m - 1) == Y.charAt(n - 1))
            return 1 + superSeq(X, Y, m - 1, n - 1);
      
        return 1 + Math.min(superSeq(X, Y, m - 1, n),
                    superSeq(X, Y, m, n - 1));
    }
      
    // Driver code 
    public static void main(String args[])
    {
    String X = "AGGTAB";
    String Y = "GXTXAYB";
    System.out.println("Length of the shortest" + 
                        "supersequence is: "
            + superSeq(X, Y, X.length(),Y.length()));
    }
}
  
// This article is contributed by Sumit Ghosh

Python3

# A Naive recursive python program to find


# length of the shortest supersequence
  
def superSeq(X, Y, m, n):
    if (not m): return n
    if (not n): return m
  
    if (X[m - 1] == Y[n - 1]) : 
       return 1 + superSeq(X, Y, m - 1, n - 1)
  
    return 1 + min(superSeq(X, Y, m - 1, n),
                superSeq(X, Y, m, n - 1))
  
# Driver Code
X = "AGGTAB"
Y = "GXTXAYB"

2659
Chapter 368. Shortest Common Supersequence

print("Length of the shortest supersequence is %d"


    % superSeq(X, Y, len(X), len(Y)))
  
# This code is contributed by Ansu Kumari

C#

// A Naive recursive C# program to find 


// length of the shortest supersequence
using System;
  
class GFG
{
static int superSeq(String X, String Y, int m, int n)
    {
        if (m == 0) return n;
        if (n == 0) return m;
      
        if (X[m - 1] == Y[n - 1])
            return 1 + superSeq(X, Y, m - 1, n - 1);
      
        return 1 + Math.Min(superSeq(X, Y, m - 1, n),
                    superSeq(X, Y, m, n - 1));
    }
      
    // Driver Code
    public static void Main()
    {
    String X = "AGGTAB";
    String Y = "GXTXAYB";
    Console.WriteLine("Length of the shortest supersequence is: "
            + superSeq(X, Y, X.Length,Y.Length));
    }
}
  
// This code is contributed by Sam007

Output:

Length of the shortest supersequence is 9

Time complexity of the above solution exponential O(2min(m, n) ). Since there are over-
lapping subproblems, we can efficiently solve this recursive problem using Dynamic
Programming. Below is Dynamic Programming based implementation. Time complexity
of this solution is O(mn).

C++

2660
Chapter 368. Shortest Common Supersequence

// A dynamic programming based C program to 


// find length of the shortest supersequence
#include<bits/stdc++.h>
using namespace std;
  
// Returns length of the shortest 
// supersequence of X and Y
int superSeq(char* X, char* Y, int m, int n)
{
    int dp[m + 1][n + 1];
  
    // Fill table in bottom up manner
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
        // Below steps follow above recurrence
        if (!i)
            dp[i][j] = j;
        else if (!j)
            dp[i][j] = i;
        else if (X[i - 1] == Y[j - 1])
                dp[i][j] = 1 + dp[i - 1][j - 1];
        else
                dp[i][j] = 1 + min(dp[i - 1][j], 
                                  dp[i][j - 1]);
        }
    }
  
    return dp[m][n];
}
  
// Driver Code
int main()
{
    char X[] = "AGGTAB";
    char Y[] = "GXTXAYB";
    cout << "Length of the shortest supersequence is "
        << superSeq(X, Y, strlen(X), strlen(Y));
    return 0;
}

Java

// A dynamic programming based Java program to


// find length of the shortest supersequence
class GFG {
      

2661
Chapter 368. Shortest Common Supersequence

    // Returns length of the shortest 


    // supersequence of X and Y
    static int superSeq(String X, String Y, 
                                 int m, int n)
    {
        int[][] dp = new int[m + 1][n + 1];
      
        // Fill table in bottom up manner
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
            // Below steps follow above recurrence
            if (i == 0)
                dp[i][j] = j;
            else if (j == 0)
                dp[i][j] = i;
            else if (X.charAt(i - 1) == Y.charAt(j - 1))
                    dp[i][j] = 1 + dp[i - 1][j - 1];
            else
                    dp[i][j] = 1 + Math.min(dp[i - 1][j], 
                                           dp[i][j - 1]);
            }
        }
      
        return dp[m][n];
    }
  
    // Driver Code
    public static void main(String args[])
    {
    String X = "AGGTAB";
    String Y = "GXTXAYB";
    System.out.println("Length of the shortest supersequence is "
            + superSeq(X, Y, X.length(),Y.length()));
    }
}
  
// This article is contributed by Sumit Ghosh

Python3

# A dynamic programming based python program 


# to find length of the shortest supersequence
  
# Returns length of the shortest supersequence of X and Y
def superSeq(X, Y, m, n):
    dp = [[0] * (n + 2) for i in range(m + 2)]

2662
Chapter 368. Shortest Common Supersequence

  
    # Fill table in bottom up manner
    for i in range(m + 1):
        for j in range(n + 1):
             
            #Below steps follow above recurrence
            if (not i): dp[i][j] = j
            elif (not j): dp[i][j] = i
              
            elif (X[i - 1] == Y[j - 1]): 
                 dp[i][j] = 1 + dp[i - 1][j - 1]
                   
            else: dp[i][j] = 1 + min(dp[i - 1][j], 
                                     dp[i][j - 1])
             
    return dp[m][n]
  
# Driver Code
X = "AGGTAB"
Y = "GXTXAYB"
print("Length of the shortest supersequence is %d"
     % superSeq(X, Y, len(X), len(Y)))
  
# This code is contributed by Ansu Kumari

C#

// A dynamic programming based C# program to 


// find length of the shortest supersequence
using System;
  
class GFG
{
// Returns length of the shortest 
// supersequence of X and Y
    static int superSeq(String X, String Y, 
                                 int m, int n)
    {
        int[,] dp = new int[m + 1,n + 1];
      
        // Fill table in bottom up manner
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
            // Below steps follow above recurrence
            if (i == 0)
                dp[i, j] = j;

2663
Chapter 368. Shortest Common Supersequence

            else if (j == 0)
                dp[i, j] = i;
            else if (X[i - 1] == Y[j - 1])
                    dp[i, j] = 1 + dp[i - 1, j - 1];
            else
                    dp[i, j] = 1 + Math.Min(dp[i - 1, j], 
                                          dp[i, j - 1]);
            }
        }
      
        return dp[m, n];
    }
  
    // Driver code
    public static void Main()
    {
    String X = "AGGTAB";
    String Y = "GXTXAYB";
    Console.WriteLine("Length of the shortest supersequence is "
            + superSeq(X, Y, X.Length,Y.Length));
    }
}
  
// This code is contributed by Sam007

Output:

Length of the shortest supersequence is 9

Thanks to Gaurav Ahirwar for suggesting this solution.


Exercise:
Extend the above program to print shortest supersequence also using function to print LCS.
Please refer Printing Shortest Common Supersequencefor solution
References:
https://en.wikipedia.org/wiki/Shortest_common_supersequence
Improved By : Sam007, Vipin Sharma

Source

https://www.geeksforgeeks.org/shortest-common-supersequence/

2664
Chapter 369

Shortest Uncommon
Subsequence

Shortest Uncommon Subsequence - GeeksforGeeks


Given two strings S and T, find length of the shortest subsequence in S which is not a
subsequence in T. If no such subsequence is possible, return -1. A subsequence is a sequence
that appears in the same relative order, but not necessarily contiguous. A string of length
n has different possible subsequences.
String S of length m (1 <= m <= 1000)
String T of length n (1 <= n <= 1000)
Examples:

Input : S = “babab” T = “babba”


Output : 3
The subsequence “aab” of length 3 is
present in S but not in T.

Input : S = “abb” T = “abab”


Output : -1
There is no subsequence that is present
in S but not in T.

Brute Force Method


A simple approach will be to generate all the subsequences of string S and for each subse-
quence check if it is present in string T or not. Consider example 2 in which S = “abb”,
its subsequences are “”, ”a”, ”b”, ”ab”, ”bb”, ”abb” each of which is present in “abab”. The
time complexity of this solution will be exponential.
Efficient (Dynamic Programming)

2665
Chapter 369. Shortest Uncommon Subsequence

1.Optimal substructure : Consider two strings S and T of length m and n respectively &
let the function to find the shortest uncommon subsequence be shortestSeq (char *S, char
*T). For each character in S, if it is not present in T then that character is the answer itself.
Otherwise if it is found at index k then we have the choice of either including it in the
shortest uncommon subsequence or not.

If it is included answer = 1 + ShortestSeq( S + 1, T + k + 1)


If not included answer = ShortestSeq( S + 1, T)
The minimum of the two is the answer.

Thus we can see that this problem has optimal substructure property as it can be solved by
using solution to sub problems.
2.Overlapping Sub problems
Following is a simple recursive implementation of the above problem.

// A simple recursive C++ program to find shortest


// uncommon subsequence.
#include<bits/stdc++.h>
using namespace std;
  
#define MAX 1005
  
/* A recursive function to find the length of
   shortest uncommon subsequence*/
int shortestSeq(char *S, char *T, int m, int n)
{
    // S string is empty
    if (m == 0)
        return MAX;
  
    // T string is empty
    if (n <= 0)
        return 1;
  
    // Loop to search for current character
    int k;
    for (k=0; k < n; k++)
        if (T[k] == S[0])
            break;
  
    // char not found in T
    if (k == n)
        return 1;
  
    // Return minimum of following two
    // Not including current char in answer

2666
Chapter 369. Shortest Uncommon Subsequence

    // Including current char


    return min(shortestSeq(S+1, T, m-1, n),
            1 + shortestSeq(S+1, T+k+1, m-1, n-k-1));
}
  
// Driver program to test the above function
int main()
{
    char S[] = "babab";
    char T[] = "babba";
    int m = strlen(S), n = strlen(T);
    int ans = shortestSeq(S, T, m, n);
    if (ans >= MAX)
       ans = -1;
    cout << "Length of shortest subsequence is: "
         << ans << endl;
    return 0;
}

Length of shortest subsequence is : 3

If we draw the complete recursion tree, then we can see that there are many sub problems
which are solved again and again. So this problem has Overlapping Substructure property
and recomputation of same sub problems can be avoided by either using Memoization or
Tabulation. Following is a tabulated implementation for the problem.

// A dynamic programming based C++ program

2667
Chapter 369. Shortest Uncommon Subsequence

// to find shortest uncommon subsequence.


#include<bits/stdc++.h>
using namespace std;
  
#define MAX 1005
  
// Returns length of shortest common subsequence
int shortestSeq(char *S, char *T)
{
    int m = strlen(S), n = strlen(T);
  
    // declaring 2D array of m + 1 rows and
    // n + 1 columns dynamically
    int dp[m+1][n+1];
  
    // T string is empty
    for (int i = 0; i <= m; i++)
        dp[i][0] = 1;
  
    // S string is empty
    for (int i = 0; i <= n; i++)
        dp[0][i] = MAX;
  
    for (int i = 1; i <= m; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            char ch = S[i-1];
            int k;
            for (k = j-1; k >= 0; k--)
                if (T[k] == ch)
                    break;
  
            // char not present in T
            if (k == -1)
                dp[i][j] = 1;
            else
               dp[i][j] = min(dp[i-1][j], dp[i-1][k] + 1);
        }
    }
  
    int ans = dp[m][n];
    if (ans >= MAX)
        ans = -1;
  
    return ans;
}
  

2668
Chapter 369. Shortest Uncommon Subsequence

// Driver program to test the above function


int main()
{
    char S[] = "babab";
    char T[] = "babba";
    int m = strlen(S), n = strlen(T);
    cout << "Length of shortest subsequence is : "
         << shortestSeq(S, T) << endl;
}

Output:

Length of shortest subsequence is : 3

Time complexity : O(m)


Space Complexity : O(mn)

Source

https://www.geeksforgeeks.org/shortest-uncommon-subsequence/

2669
Chapter 370

Shortest path with exactly k


edges in a directed and
weighted graph

Shortest path with exactly k edges in a directed and weighted graph - GeeksforGeeks
Given a directed and two vertices ‘u’ and ‘v’ in it, find shortest path from ‘u’ to ‘v’ with
exactly k edges on the path.
The graph is given as adjacency matrix representation where value of graph[i][j] indicates
the weight of an edge from vertex i to vertex j and a value INF(infinite) indicates no edge
from i to j.
For example consider the following graph. Let source ‘u’ be vertex 0, destination ‘v’ be 3
and k be 2. There are two walks of length 2, the walks are {0, 2, 3} and {0, 1, 3}. The
shortest among the two is {0, 2, 3} and weight of path is 3+6 = 9.

The idea is to browse through all paths of length k from u to v using the approach discussed
in the previous post and return weight of the shortest path. A simple solution is to start

2670
Chapter 370. Shortest path with exactly k edges in a directed and weighted graph

from u, go to all adjacent vertices and recur for adjacent vertices with k as k-1, source as
adjacent vertex and destination as v. Following are C++ and Java implementations of this
simple solution.
C++

// C++ program to find shortest path with exactly k edges


#include <iostream>
#include <climits>
using namespace std;
  
// Define number of vertices in the graph and inifinite value
#define V 4
#define INF INT_MAX
  
// A naive recursive function to count walks from u to v with k edges
int shortestPath(int graph[][V], int u, int v, int k)
{
   // Base cases
   if (k == 0 && u == v)             return 0;
   if (k == 1 && graph[u][v] != INF) return graph[u][v];
   if (k <= 0)                       return INF;
  
   // Initialize result
   int res = INF;
  
   // Go to all adjacents of u and recur
   for (int i = 0; i < V; i++)
   {
       if (graph[u][i] != INF && u != i && v != i)
       {
           int rec_res = shortestPath(graph, i, v, k-1);
           if (rec_res != INF)
              res = min(res, graph[u][i] + rec_res);
       }
   }
   return res;
}
  
// driver program to test above function
int main()
{
    /* Let us create the graph shown in above diagram*/
     int graph[V][V] = { {0, 10, 3, 2},
                        {INF, 0, INF, 7},
                        {INF, INF, 0, 6},
                        {INF, INF, INF, 0}
                      };
    int u = 0, v = 3, k = 2;

2671
Chapter 370. Shortest path with exactly k edges in a directed and weighted graph

    cout << "Weight of the shortest path is " <<


          shortestPath(graph, u, v, k);
    return 0;
}

Java

// Dynamic Programming based Java program to find shortest path


// with exactly k edges
import java.util.*;
import java.lang.*;
import java.io.*;
  
class ShortestPath
{
    // Define number of vertices in the graph and inifinite value
    static final int V = 4;
    static final int INF = Integer.MAX_VALUE;
  
    // A naive recursive function to count walks from u to v
    // with k edges
    int shortestPath(int graph[][], int u, int v, int k)
    {
        // Base cases
        if (k == 0 && u == v)             return 0;
        if (k == 1 && graph[u][v] != INF) return graph[u][v];
        if (k <= 0)                       return INF;
  
        // Initialize result
        int res = INF;
  
        // Go to all adjacents of u and recur
        for (int i = 0; i < V; i++)
        {
            if (graph[u][i] != INF && u != i && v != i)
            {
                int rec_res = shortestPath(graph, i, v, k-1);
                if (rec_res != INF)
                    res = Math.min(res, graph[u][i] + rec_res);
            }
        }
        return res;
    }
  
    public static void main (String[] args)
    {
        /* Let us create the graph shown in above diagram*/
        int graph[][] = new int[][]{ {0, 10, 3, 2},

2672
Chapter 370. Shortest path with exactly k edges in a directed and weighted graph

                                     {INF, 0, INF, 7},


                                     {INF, INF, 0, 6},
                                     {INF, INF, INF, 0}
                                   };
        ShortestPath t = new ShortestPath();
        int u = 0, v = 3, k = 2;
        System.out.println("Weight of the shortest path is "+
                           t.shortestPath(graph, u, v, k));
    }
}

Output:

Weight of the shortest path is 9

The worst case time complexity of the above function is O(Vk ) where V is the number of
vertices in the given graph. We can simply analyze the time complexity by drawing recursion
tree. The worst occurs for a complete graph. In worst case, every internal node of recursion
tree would have exactly V children.
We can optimize the above solution using Dynamic Programming. The idea is to build
a 3D table where first dimension is source, second dimension is destination, third dimension
is number of edges from source to destination, and the value is count of walks. Like other
Dynamic Programming problems, we fill the 3D table in bottom up manner.
C++

// Dynamic Programming based C++ program to find shortest path with


// exactly k edges
#include <iostream>
#include <climits>
using namespace std;
  
// Define number of vertices in the graph and inifinite value
#define V 4
#define INF INT_MAX
  
// A Dynamic programming based function to find the shortest path from
// u to v with exactly k edges.
int shortestPath(int graph[][V], int u, int v, int k)
{
    // Table to be filled up using DP. The value sp[i][j][e] will store
    // weight of the shortest path from i to j with exactly k edges
    int sp[V][V][k+1];
  
    // Loop for number of edges from 0 to k
    for (int e = 0; e <= k; e++)
    {
        for (int i = 0; i < V; i++)  // for source

2673
Chapter 370. Shortest path with exactly k edges in a directed and weighted graph

        {
            for (int j = 0; j < V; j++) // for destination
            {
                // initialize value
                sp[i][j][e] = INF;
  
                // from base cases
                if (e == 0 && i == j)
                    sp[i][j][e] = 0;
                if (e == 1 && graph[i][j] != INF)
                    sp[i][j][e] = graph[i][j];
  
                //go to adjacent only when number of edges is more than 1
                if (e > 1)
                {
                    for (int a = 0; a < V; a++)
                    {
                        // There should be an edge from i to a and a 
                        // should not be same as either i or j
                        if (graph[i][a] != INF && i != a &&
                            j!= a && sp[a][j][e-1] != INF)
                          sp[i][j][e] = min(sp[i][j][e], graph[i][a] +
                                                       sp[a][j][e-1]);
                    }
                }
           }
        }
    }
    return sp[u][v][k];
}
  
// driver program to test above function
int main()
{
    /* Let us create the graph shown in above diagram*/
     int graph[V][V] = { {0, 10, 3, 2},
                        {INF, 0, INF, 7},
                        {INF, INF, 0, 6},
                        {INF, INF, INF, 0}
                      };
    int u = 0, v = 3, k = 2;
    cout << shortestPath(graph, u, v, k);
    return 0;
}

Java

// Dynamic Programming based Java program to find shortest path with

2674
Chapter 370. Shortest path with exactly k edges in a directed and weighted graph

// exactly k edges
import java.util.*;
import java.lang.*;
import java.io.*;
  
class ShortestPath
{
    // Define number of vertices in the graph and inifinite value
    static final int V = 4;
    static final int INF = Integer.MAX_VALUE;
  
    // A Dynamic programming based function to find the shortest path
    // from u to v with exactly k edges.
    int shortestPath(int graph[][], int u, int v, int k)
    {
        // Table to be filled up using DP. The value sp[i][j][e] will
        // store weight of the shortest path from i to j with exactly
        // k edges
        int sp[][][] = new int[V][V][k+1];
  
        // Loop for number of edges from 0 to k
        for (int e = 0; e <= k; e++)
        {
            for (int i = 0; i < V; i++)  // for source
            {
                for (int j = 0; j < V; j++) // for destination
                {
                    // initialize value
                    sp[i][j][e] = INF;
  
                    // from base cases
                    if (e == 0 && i == j)
                        sp[i][j][e] = 0;
                    if (e == 1 && graph[i][j] != INF)
                        sp[i][j][e] = graph[i][j];
  
                    // go to adjacent only when number of edges is
                    // more than 1
                    if (e > 1)
                    {
                        for (int a = 0; a < V; a++)
                        {
                            // There should be an edge from i to a and
                            // a should not be same as either i or j
                            if (graph[i][a] != INF && i != a &&
                                    j!= a && sp[a][j][e-1] != INF)
                                sp[i][j][e] = Math.min(sp[i][j][e],
                                          graph[i][a] + sp[a][j][e-1]);

2675
Chapter 370. Shortest path with exactly k edges in a directed and weighted graph

                        }
                    }
                }
            }
        }
        return sp[u][v][k];
    }
  
    public static void main (String[] args)
    {
        /* Let us create the graph shown in above diagram*/
        int graph[][] = new int[][]{ {0, 10, 3, 2},
                                     {INF, 0, INF, 7},
                                     {INF, INF, 0, 6},
                                     {INF, INF, INF, 0}
                                   };
        ShortestPath t = new ShortestPath();
        int u = 0, v = 3, k = 2;
        System.out.println("Weight of the shortest path is "+
                           t.shortestPath(graph, u, v, k));
    }
}
//This code is contributed by Aakash Hasija

Output:

Weight of the shortest path is 9

Time complexity of the above DP based solution is O(V3 K) which is much better than the
naive solution.
This article is contributed by Abhishek. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/shortest-path-exactly-k-edges-directed-weighted-graph/

2676
Chapter 371

Shortest possible combination of


two strings

Shortest possible combination of two strings - GeeksforGeeks


Compute the shortest string for a combination of two given strings such that the new string
consist of both the strings as its subsequences.
Examples :

Input : a = "pear"
b = "peach"
Output : pearch
pearch is the shorted string such that both
pear and peach are its subsequences.

Input : a = "geek"
b = "code"
Output : gecodek

We have discussed a solution to find length of the shortest supersequence in below post.
Shortest Common Supersequence
In this post, printing of supersequence is discussed. The solution is based on below recursive
approach discussed in above post as an alternate method.

Let a[0..m-1] and b[0..n-1] be two strings and m and


be respective lengths.

if (m == 0) return n;
if (n == 0) return m;

2677
Chapter 371. Shortest possible combination of two strings

// If last characters are same, then add 1 to


// result and recur for a[]
if (a[m-1] == b[n-1])
return 1 + SCS(a, b, m-1, n-1);

// Else find shortest of following two


// a) Remove last character from X and recur
// b) Remove last character from Y and recur
else return 1 + min( SCS(a, b, m-1, n),
SCS(a, b, m, n-1) );

We build a DP array to store lengths. After building the DP array, we traverse from bottom
right most position. The approach of printing is similar to printing LCS.
C++

/* C++ program to print supersequence of two


   strings */
#include<bits/stdc++.h>
using namespace std;
  
/* Prints super sequence of a[0..m-1] and b[0..n-1] */
void printSuperSeq(string &a, string &b)
{
    int m = a.length(), n = b.length();
    int dp[m+1][n+1];
  
    // Fill table in bottom up manner
    for (int i = 0; i <= m; i++)
    {
        for (int j = 0; j <= n; j++)
        {
           // Below steps follow above recurrence
           if (!i)
               dp[i][j] = j;
           else if (!j)
               dp[i][j] = i;
           else if (a[i-1] == b[j-1])
                dp[i][j] = 1 + dp[i-1][j-1];
           else
                dp[i][j] = 1 + min(dp[i-1][j], dp[i][j-1]);
        }
    }
  
   // Following code is used to print supersequence
   int index = dp[m][n];
  

2678
Chapter 371. Shortest possible combination of two strings

   // Create a string of size index+1 to store the result


   string res(index+1, '\0');
  
   // Start from the right-most-bottom-most corner and
   // one by one store characters in res[]
   int i = m, j = n;
   while (i > 0 && j > 0)
   {
      // If current character in a[] and b are same,
      // then current character is part of LCS
      if (a[i-1] == b[j-1])
      {
          // Put current character in result
          res[index-1] = a[i-1];
  
          // reduce values of i, j and indexs
          i--; j--; index--;
      }
  
      // If not same, then find the larger of two and
      // go in the direction of larger value
      else if (dp[i-1][j] < dp[i][j-1])
      { res[index-1] = a[i-1];   i--;  index--; }
      else
      { res[index-1] = b[j-1];  j--; index--; }
   }
  
   // Copy remaining characters of string 'a'
   while (i > 0)
   {
       res[index-1] = a[i-1];   i--;  index--;
   }
  
   // Copy remaining characters of string 'b'
   while (j > 0)
   {
       res[index-1] = b[j-1];  j--; index--;
   }
  
   // Print the result
   cout << res;
}
  
/* Driver program to test above function */
int main()
{
  string a = "algorithm", b = "rhythm";
  printSuperSeq(a, b);

2679
Chapter 371. Shortest possible combination of two strings

  return 0;
}

Java

// Java program to print supersequence of two


// strings 
public class GFG_1 {
      
    String a , b;
      
    // Prints super sequence of a[0..m-1] and b[0..n-1] 
    static void printSuperSeq(String a, String b)
    {
        int m = a.length(), n = b.length();
        int[][] dp = new int[m+1][n+1];
       
        // Fill table in bottom up manner
        for (int i = 0; i <= m; i++)
        {
            for (int j = 0; j <= n; j++)
            {
               // Below steps follow above recurrence
               if (i == 0)
                   dp[i][j] = j;
               else if (j == 0 )
                   dp[i][j] = i;
               else if (a.charAt(i-1) == b.charAt(j-1))
                    dp[i][j] = 1 + dp[i-1][j-1];
               else
                    dp[i][j] = 1 + Math.min(dp[i-1][j], dp[i][j-1]);
            }
        }
       
       // Create a string of size index+1 to store the result
       String res = "";
       
       // Start from the right-most-bottom-most corner and
       // one by one store characters in res[]
       int i = m, j = n;
       while (i > 0 && j > 0)
       {
          // If current character in a[] and b are same,
          // then current character is part of LCS
          if (a.charAt(i-1) == b.charAt(j-1))
          {
              // Put current character in result
              res = a.charAt(i-1) + res;

2680
Chapter 371. Shortest possible combination of two strings

       
              // reduce values of i, j and indexs
              i--;
              j--;
          }
       
          // If not same, then find the larger of two and
          // go in the direction of larger value
          else if (dp[i-1][j] < dp[i][j-1])
          { 
              res = a.charAt(i-1) + res;
              i--;  
          }
          else
          {
              res = b.charAt(j-1) + res; 
              j--; 
          }
       }
       
       // Copy remaining characters of string 'a'
       while (i > 0)
       {
           res = a.charAt(i-1) + res;
           i--;
       }
       
       // Copy remaining characters of string 'b'
       while (j > 0)
       {
           res = b.charAt(j-1) + res;   
           j--; 
       }
       
       // Print the result
       System.out.println(res);
    }
       
    /* Driver program to test above function */
    public static void main(String args[])
    {
      String a = "algorithm";
      String b = "rhythm";
      printSuperSeq(a, b);
        
    }
}
// This article is contributed by Sumit Ghosh

2681
Chapter 371. Shortest possible combination of two strings

Output:

algorihythm

Solution based on LCS:


We build the 2D array using LCS solution. If the character at the two pointer positions is
equal, we increment the length by 1, else we store the minimum of the adjacent positions.
Finally, we backtrack the matrix to find the index vector traversing which would yield the
shortest possible combination.

C++

// C++ implementation to find shortest string for


// a combination of two strings
#include <bits/stdc++.h>
using namespace std;
  
// Vector that store the index of string a and b
vector<int> index_a;
vector<int> index_b;
  
// Subroutine to Backtrack the dp matrix to
// find the index vector traversing which would
// yield the shortest possible combination
void index(int dp[][100], string a, string b,
           int size_a, int size_b)
{
    // Clear the index vectors
    index_a.clear();
    index_b.clear();
  
    // Return if either of a or b is reduced
    // to 0
    if (size_a == 0 || size_b == 0)
        return;
  
    // Push both to index_a and index_b with
    // the respective a and b index
    if (a[size_a - 1] == b[size_b - 1]) {
        index(dp, a, b, size_a - 1, size_b - 1);
        index_a.push_back(size_a - 1);
        index_b.push_back(size_b - 1);
    } else {
        if (dp[size_a - 1][size_b] > dp[size_a]
                                    [size_b - 1]) {
            index(dp, a, b, size_a - 1, size_b);

2682
Chapter 371. Shortest possible combination of two strings

        } else {
            index(dp, a, b, size_a, size_b - 1);
        }
    }
}
  
// function to combine the strings to form
// the shortest string
void combine(string a, string b, int size_a,
             int size_b)
{
  
    int dp[100][100];
    string ans = "";
    int k = 0;
  
    // Initialize the matrix to 0
    memset(dp, 0, sizeof(dp));
  
    // Store the increment of diagonally
    // previous value if a[i-1] and b[j-1] are
    // equal, else store the max of dp[i][j-1]
    // and dp[i-1][j]
    for (int i = 1; i <= size_a; i++) {
        for (int j = 1; j <= size_b; j++) {
            if (a[i - 1] == b[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = max(dp[i][j - 1],
                               dp[i - 1][j]);
            }
        }
    }
  
    // Get the Lowest Common Subsequence
    int lcs = dp[size_a][size_b];
  
    // Backtrack the dp array to get the index
    // vectors of two strings, used to find
    // the shortest possible combination.
    index(dp, a, b, size_a, size_b);
  
    int i, j = i = k;
  
    // Build the string combination using the
    // index found by backtracking
    while (k < lcs) {
        while (i < size_a && i < index_a[k]) {

2683
Chapter 371. Shortest possible combination of two strings

            ans += a[i++];
        }
  
        while (j < size_b && j < index_b[k]) {
            ans += b[j++];
        }
  
        ans = ans + a[index_a[k]];
        k++;
        i++;
        j++;
    }
  
    // Append the remaining characters in a
    // to answer
    while (i < size_a) {
        ans += a[i++];
    }
  
    // Append the remaining characters in b
    // to answer
    while (j < size_b) {
        ans += b[j++];
    }
  
    cout << ans;
}
  
// Driver code
int main()
{
    string a = "algorithm";
    string b = "rhythm";
  
    // Store the length of string
    int size_a = a.size();
    int size_b = b.size();
  
    combine(a, b, size_a, size_b);
    return 0;
}

Java

// Java implementation to find shortest string for


// a combination of two strings
import java.util.ArrayList;
public class GFG_2 {

2684
Chapter 371. Shortest possible combination of two strings

           
    // Vector that store the index of string a and b
    static ArrayList<Integer> index_a = new ArrayList<>();
    static ArrayList<Integer> index_b = new ArrayList<>();
       
    // Subroutine to Backtrack the dp matrix to
    // find the index vector traversing which would
    // yield the shortest possible combination
    static void index(int dp[][], String a, String b,
               int size_a, int size_b)
    {
        // Clear the index vectors
        index_a.clear();
        index_b.clear();
       
        // Return if either of a or b is reduced
        // to 0
        if (size_a == 0 || size_b == 0)
            return;
       
        // Push both to index_a and index_b with
        // the respective a and b index
        if (a.charAt(size_a - 1) == b.charAt(size_b - 1)) {
            index(dp, a, b, size_a - 1, size_b - 1);
            index_a.add(size_a - 1);
            index_b.add(size_b - 1);
        } else {
            if (dp[size_a - 1][size_b] > dp[size_a]
                                        [size_b - 1]) {
                index(dp, a, b, size_a - 1, size_b);
            } else {
                index(dp, a, b, size_a, size_b - 1);
            }
        }
    }
       
    // function to combine the strings to form
    // the shortest string
    static void combine(String a, String b, int size_a,
                 int size_b)
    {
       
        int[][] dp = new int[100][100];
        String ans = "";
        int k = 0;
       
        // Store the increment of diagonally
        // previous value if a[i-1] and b[j-1] are

2685
Chapter 371. Shortest possible combination of two strings

        // equal, else store the max of dp[i][j-1]


        // and dp[i-1][j]
        for (int i = 1; i <= size_a; i++) {
            for (int j = 1; j <= size_b; j++) {
                if (a.charAt(i - 1) == b.charAt(j - 1)) {
                    dp[i][j] = dp[i - 1][j - 1] + 1;
                } else {
                    dp[i][j] = Math.max(dp[i][j - 1],
                                   dp[i - 1][j]);
                }
            }
        }
       
        // Get the Lowest Common Subsequence
        int lcs = dp[size_a][size_b];
       
        // Backtrack the dp array to get the index
        // vectors of two strings, used to find
        // the shortest possible combination.
        index(dp, a, b, size_a, size_b);
       
        int i, j = i = k;
       
        // Build the string combination using the
        // index found by backtracking
        while (k < lcs) {
            while (i < size_a && i < index_a.get(k)) {
                ans += a.charAt(i++);
            }
       
            while (j < size_b && j < index_b.get(k)) {
                ans += b.charAt(j++);
            }
       
            ans = ans + a.charAt(index_a.get(k));
            k++;
            i++;
            j++;
        }
       
        // Append the remaining characters in a
        // to answer
        while (i < size_a) {
            ans += a.charAt(i++);
        }
       
        // Append the remaining characters in b
        // to answer

2686
Chapter 371. Shortest possible combination of two strings

        while (j < size_b) {


            ans +=  b.charAt(j++);
        }
       
        System.out.println(ans);
    }
       
       
    /* Driver program to test above function */
    public static void main(String args[])
    {
      String a = "algorithm";
      String b = "rhythm";
      combine(a, b, a.length(),b.length());
        
    }
}
// This article is contributed by Sumit Ghosh

Output:

algorihythm

Source

https://www.geeksforgeeks.org/shortest-possible-combination-two-strings/

2687
Chapter 372

Sieve of Eratosthenes

Sieve of Eratosthenes - GeeksforGeeks


Given a number n, print all primes smaller than or equal to n. It is also given that n is a
small number.
Example:

Input : n =10
Output : 2 3 5 7

Input : n = 20
Output: 2 3 5 7 11 13 17 19

The sieve of Eratosthenes is one of the most efficient ways to find all primes smaller than n
when n is smaller than 10 million or so (Ref Wiki).
Following is the algorithm to find all the prime numbers less than or equal to a given
integer n by Eratosthenes’ method:

1. Create a list of consecutive integers from 2 to n: (2, 3, 4, …, n).


2. Initially, let p equal 2, the first prime number.
3. Starting from p, count up in increments of p and mark each of these numbers greater
than p itself in the list. These numbers will be 2p, 3p, 4p, etc.; note that some of them
may have already been marked.
4. Find the first number greater than p in the list that is not marked. If there was no
such number, stop. Otherwise, let p now equal this number (which is the next prime),
and repeat from step 3.

When the algorithm terminates, all the numbers in the list that are not marked are prime.
Explanation with Example:
Let us take an example when n = 50. So we need to print all print numbers smaller than
or equal to 50.

2688
Chapter 372. Sieve of Eratosthenes

We create a list of all numbers from 2 to 50.

According to the algorithm we will mark all the numbers which are divisible by 2.

Now we move to our next unmarked number 3 and mark all the numbers which are
multiples of 3.

We move to our next unmarked number 5 and mark all multiples of 5.

We continue this process and our final table will look like below:

2689
Chapter 372. Sieve of Eratosthenes

So the prime numbers are the unmarked ones: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,
43, 47.
Thanks toKrishan Kumar for providing above explanation.

Implementation:
Following is the implementation of the above algorithm. In the following implementation,
a boolean array arr[] of size n is used to mark multiples of prime numbers.

C/C++

// C++ program to print all primes smaller than or equal to


// n using Sieve of Eratosthenes
#include <bits/stdc++.h>
using namespace std;
  
void SieveOfEratosthenes(int n)
{
    // Create a boolean array "prime[0..n]" and initialize
    // all entries it as true. A value in prime[i] will
    // finally be false if i is Not a prime, else true.
    bool prime[n+1];
    memset(prime, true, sizeof(prime));
  
    for (int p=2; p*p<=n; p++)
    {
        // If prime[p] is not changed, then it is a prime
        if (prime[p] == true)
        {
            // Update all multiples of p
            for (int i=p*2; i<=n; i += p)
                prime[i] = false;
        }
    }
  
    // Print all prime numbers
    for (int p=2; p<=n; p++)
       if (prime[p])
          cout << p << " ";

2690
Chapter 372. Sieve of Eratosthenes

}
  
// Driver Program to test above function
int main()
{
    int n = 30;
    cout << "Following are the prime numbers smaller "
         << " than or equal to " << n << endl;
    SieveOfEratosthenes(n);
    return 0;
}

Java

// Java program to print all primes smaller than or equal to


// n using Sieve of Eratosthenes
  
class SieveOfEratosthenes
{
    void sieveOfEratosthenes(int n)
    {
        // Create a boolean array "prime[0..n]" and initialize
        // all entries it as true. A value in prime[i] will
        // finally be false if i is Not a prime, else true.
        boolean prime[] = new boolean[n+1];
        for(int i=0;i<n;i++)
            prime[i] = true;
          
        for(int p = 2; p*p <=n; p++)
        {
            // If prime[p] is not changed, then it is a prime
            if(prime[p] == true)
            {
                // Update all multiples of p
                for(int i = p*2; i <= n; i += p)
                    prime[i] = false;
            }
        }
          
        // Print all prime numbers
        for(int i = 2; i <= n; i++)
        {
            if(prime[i] == true)
                System.out.print(i + " ");
        }
    }
      
    // Driver Program to test above function

2691
Chapter 372. Sieve of Eratosthenes

    public static void main(String args[])


    {
        int n = 30;
        System.out.print("Following are the prime numbers ");
        System.out.println("smaller than or equal to " + n);
        SieveOfEratosthenes g = new SieveOfEratosthenes();
        g.sieveOfEratosthenes(n);
    }
}
  
// This code has been contributed by Amit Khandelwal.

Python

# Python program to print all primes smaller than or equal to


# n using Sieve of Eratosthenes
  
def SieveOfEratosthenes(n):
      
    # Create a boolean array "prime[0..n]" and initialize
    #  all entries it as true. A value in prime[i] will
    # finally be false if i is Not a prime, else true.
    prime = [True for i in range(n+1)]
    p = 2
    while (p * p <= n):
          
        # If prime[p] is not changed, then it is a prime
        if (prime[p] == True):
              
            # Update all multiples of p
            for i in range(p * 2, n+1, p):
                prime[i] = False
        p += 1
      
    # Print all prime numbers
    for p in range(2, n):
        if prime[p]:
            print p,
  
# driver program
if __name__=='__main__':
    n = 30
    print "Following are the prime numbers smaller",
    print "than or equal to", n
    SieveOfEratosthenes(n)

C#

2692
Chapter 372. Sieve of Eratosthenes

// C# program to print all primes


// smaller than or equal to n
// using Sieve of Eratosthenes
using System;
  
namespace prime
{
    public class GFG
    {     
                  
        public static void SieveOfEratosthenes(int n)
        {
              
        // Create a boolean array "prime[0..n]" and initialize
        // all entries it as true. A value in prime[i] will
        // finally be false if i is Not a prime, else true.
  
        bool[] prime = new bool[n+1];
          
        for(int i = 0; i < n; i++)
            prime[i] = true;
          
        for(int p = 2; p*p <= n; p++)
        {
            // If prime[p] is not changed,
            // then it is a prime
            if(prime[p] == true)
            {
                // Update all multiples of p
                for(int i = p*2; i <= n; i += p)
                    prime[i] = false;
            }
        }
          
        // Print all prime numbers
        for(int i = 2; i <= n; i++)
        {
            if(prime[i] == true)
                Console.Write(i + " ");
        }
              
        }
          
        // Driver Code
        public static void Main()
        {
            int n = 30;
            Console.WriteLine("Following are the prime numbers");

2693
Chapter 372. Sieve of Eratosthenes

            Console.WriteLine("smaller than or equal to " + n);


            SieveOfEratosthenes(n);
              
        }
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// php program to print all primes smaller
// than or equal to n using Sieve of
// Eratosthenes
  
function SieveOfEratosthenes($n)
{
    // Create a boolean array "prime[0..n]" 
    // and initialize all entries it as true.
    // A value in prime[i] will finally be 
    // false if i is Not a prime, else true.
    $prime = array_fill(0, $n+1, true);
  
    for ($p = 2; $p*$p <= $n; $p++)
    {
          
        // If prime[p] is not changed, 
        // then it is a prime
        if ($prime[$p] == true)
        {
              
            // Update all multiples of p
            for ($i = $p*2; $i <= $n; $i += $p)
                $prime[$i] = false;
        }
    }
  
    // Print all prime numbers
    for ($p = 2; $p <= $n; $p++)
        if ($prime[$p])
            echo $p." ";
}
  
// Driver Program to test above function
    $n = 30;
    echo "Following are the prime numbers "
     ."smaller than or equal to " .$n."\n" ;

2694
Chapter 372. Sieve of Eratosthenes

    SieveOfEratosthenes($n);
  
// This code is contributed by mits
?>

Output:

Following are the prime numbers below 30


2 3 5 7 11 13 17 19 23 29

Time complexity : O(sqrt(n)loglog(n))


You may also like to see :
Segmented Sieve.
Sieve of Eratosthenes in 0(n) time complexity
References:
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
This article is compiled by Abhinav Priyadarshi and reviewed by GeeksforGeeks team.
Please write comments if you find anything incorrect, or you want to share more information
about the topic discussed above
Improved By : Mithun Kumar

Source

https://www.geeksforgeeks.org/sieve-of-eratosthenes/

2695
Chapter 373

Size of The Subarray With


Maximum Sum

Size of The Subarray With Maximum Sum - GeeksforGeeks


An array is given, find length of the subarray having maximum sum.
Examples :

Input : a[] = {1, -2, 1, 1, -2, 1}


Output : Length of the subarray is 2
Explanation: Subarray with consecutive elements
and maximum sum will be {1, 1}. So length is 2

Input : ar[] = { -2, -3, 4, -1, -2, 1, 5, -3 }


Output : Length of the subarray is 5
Explanation: Subarray with consecutive elements
and maximum sum will be {4, -1, -2, 1, 5}.

This problem is mainly a variation of Largest Sum Contiguous Subarray Problem.


The idea is to update starting index whenever sum ending here becomes less than 0.
C++

// C++ program to print length of the largest 


// contiguous array sum
#include<iostream>
#include<climits>
using namespace std;
  
int maxSubArraySum(int a[], int size)
{

2696
Chapter 373. Size of The Subarray With Maximum Sum

    int max_so_far = INT_MIN, max_ending_here = 0,


       start =0, end = 0, s=0;
  
    for (int i=0; i< size; i++ )
    {
        max_ending_here += a[i];
  
        if (max_so_far < max_ending_here)
        {
            max_so_far = max_ending_here;
            start = s;
            end = i;
        }
  
        if (max_ending_here < 0)
        {
            max_ending_here = 0;
            s = i + 1;
        }
    }
      
    return (end - start + 1);
}
  
/*Driver program to test maxSubArraySum*/
int main()
{
    int a[] = {-2, -3, 4, -1, -2, 1, 5, -3};
    int n = sizeof(a)/sizeof(a[0]);
    cout << maxSubArraySum(a, n);
    return 0;
}

Java

// Java program to print length of the largest 


// contiguous array sum
class GFG {
  
    static int maxSubArraySum(int a[], int size)
    {
        int max_so_far = Integer.MIN_VALUE,
        max_ending_here = 0,start = 0,
        end = 0, s = 0;
  
        for (int i = 0; i < size; i++) 
        {
            max_ending_here += a[i];

2697
Chapter 373. Size of The Subarray With Maximum Sum

  
            if (max_so_far < max_ending_here) 
            {
                max_so_far = max_ending_here;
                start = s;
                end = i;
            }
  
            if (max_ending_here < 0) 
            {
                max_ending_here = 0;
                s = i + 1;
            }
        }
        return (end - start + 1);
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int a[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = a.length;
        System.out.println(maxSubArraySum(a, n));
    }
}

Python3

# Python program to print largest contiguous array sum


  
from sys import maxsize
  
# Function to find the maximum contiguous subarray
# and print its starting and end index
def maxSubArraySum(a,size):
  
    max_so_far = -maxsize - 1
    max_ending_here = 0
    start = 0
    end = 0
    s = 0
  
    for i in range(0,size):
  
        max_ending_here += a[i]
  
        if max_so_far < max_ending_here:
            max_so_far = max_ending_here

2698
Chapter 373. Size of The Subarray With Maximum Sum

            start = s
            end = i
  
        if max_ending_here < 0:
            max_ending_here = 0
            s = i+1
  
    return (end - start + 1)
  
# Driver program to test maxSubArraySum
a = [-2, -3, 4, -1, -2, 1, 5, -3]
print(maxSubArraySum(a,len(a)))

C#

// C# program to print length of the 


// largest contiguous array sum
using System;
  
class GFG {
  
    // Function to find maximum subarray sum
    static int maxSubArraySum(int []a, int size)
    {
        int max_so_far = int.MinValue,
        max_ending_here = 0,start = 0,
        end = 0, s = 0;
  
        for (int i = 0; i < size; i++) 
        {
            max_ending_here += a[i];
  
            if (max_so_far < max_ending_here) 
            {
                max_so_far = max_ending_here;
                start = s;
                end = i;
            }
  
            if (max_ending_here < 0) 
            {
                max_ending_here = 0;
                s = i + 1;
            }
        }
        return (end - start + 1);
    }
  

2699
Chapter 373. Size of The Subarray With Maximum Sum

    // Driver code


    public static void Main(String[] args)
    {
        int []a = {-2, -3, 4, -1, -2, 1, 5, -3};
        int n = a.Length;
        Console.Write(maxSubArraySum(a, n));
    }
}
  
// This code is contributed by parashar...

PHP

<?php
// PHP program for Bresenham’s 
// Line Generation Assumptions :
  
// 1) Line is drawn from
// left to right.
// 2) x1 < x2 and y1 < y2
// 3) Slope of the line is 
// between 0 and 1.
// We draw a line from lower 
// left to upper right.
  
// function for line generation
function bresenham($x1, $y1, $x2, $y2)
{
$m_new = 2 * ($y2 - $y1);
$slope_error_new = $m_new - ($x2 - $x1);
for ($x = $x1, $y = $y1; $x <= $x2; $x++)
{
    echo "(" ,$x , "," , $y, ")\n";
  
    // Add slope to increment
    // angle formed
    $slope_error_new += $m_new;
  
    // Slope error reached limit, 
    // time to increment y and 
    // update slope error.
    if ($slope_error_new >= 0)
    {
        $y++;
        $slope_error_new -= 2 * ($x2 - $x1);
    }
}
}

2700
Chapter 373. Size of The Subarray With Maximum Sum

  
// Driver Code
$x1 = 3; $y1 = 2; $x2 = 15; $y2 = 5;
bresenham($x1, $y1, $x2, $y2);
  
// This code is contributed by nitin mittal.
?>

Output :

Improved By : parashar, vt_m

Source

https://www.geeksforgeeks.org/size-subarray-maximum-sum/

2701
Chapter 374

Size of array after repeated


deletion of LIS

Size of array after repeated deletion of LIS - GeeksforGeeks


Given an array arr[0..n-1] of positive element. The task is to print remaining elements of
arr[] after repeated deletion of LIS (of size greater than 1). If there are multiple LIS with
same length, we need to choose the LIS that ends first.
Examples:

Input : arr[] = {1, 2, 5, 3, 6, 4, 1}


Output : 1
Explanation :
{1, 2, 5, 3, 6, 4, 1} - {1, 2, 5, 6} = {3, 4, 1}
{3, 4, 1} - {3, 4} = {1}

Input : arr[] = {1, 2, 3, 1, 5, 2}


Output : -1
Explanation :
{1, 2, 3, 1, 5, 2} - {1, 2, 3, 5} = {1, 2}
{1, 2} - {1, 2} = {}

Input : arr[] = {5, 3, 2}


Output : 3

We repeatedly find LIS and remove its elements from array.

// input vector array = arr[]


// max-sum LIS vector array = maxArray[]
while (arr.size())

2702
Chapter 374. Size of array after repeated deletion of LIS

{
// find LIS
lis = findLIS(arr, arr.size());
if (lis.size() < 2)
break;

// Remove lis elements from current array. Note


// that both lis[] and arr[] are sorted in
// increasing order.
for (i=0; i<arr.size() && lis.size()>0; i++)
{
if (arr[i] == lis[0])
{
// Remove lis element from arr[]
arr.erase(arr.begin()+i) ;
i--;

// erase the element from lis[]. This is


// needed to make sure that next element
// to be removed is first element of lis[]
lis.erase(lis.begin()) ;
}
}
}
// print remaining element of array
for (i=0; i<arr.size(); i++)
cout << arr[i] << " ";
if (i == 0)
cout << "-1";

/* C++ program to find size of array after repeated


  deletion of LIS */
#include <bits/stdc++.h>
using namespace std;
  
// Function to construct Maximum Sum LIS
vector<int> findLIS(vector<int> arr, int n)
{
    // L[i] - The Maximum Sum Increasing
    // Subsequence that ends with arr[i]
    vector <vector<int> > L(n);
  
    // L[0] is equal to arr[0]
    L[0].push_back(arr[0]);
  
    // start from index 1
    for (int i = 1; i < n; i++)
    {

2703
Chapter 374. Size of array after repeated deletion of LIS

        // for every j less than i


        for (int j = 0; j < i; j++)
        {
            /* L[i] = {MaxSum(L[j])} + arr[i]
            where j < i and arr[j] < arr[i] */
            if (arr[i] > arr[j])
                L[i] = L[j];
        }
  
        // L[i] ends with arr[i]
        L[i].push_back(arr[i]);
    }
  
    // set lis =  LIS
    // whose size is max among all
    int maxSize = 1;
    vector<int> lis;
    for (vector<int> x : L)
    {
        // The > sign makes sure that the LIS
        // ending first is chose.    
        if (x.size() > maxSize)
        {
            lis = x;
            maxSize = x.size();
        }
    }
  
    return lis;
}
  
// Function to minimize array
void minimize(int input[], int n)
{
    vector<int> arr(input, input + n);
  
    while (arr.size())
    {
        // Find LIS of current array
        vector<int> lis = findLIS(arr, arr.size());
  
        // If all elements are in decreasing order
        if (lis.size() < 2)
            break;
  
        // Remove lis elements from current array. Note
        // that both lis[] and arr[] are sorted in
        // increasing order.

2704
Chapter 374. Size of array after repeated deletion of LIS

        for (int i=0; i<arr.size() && lis.size()>0; i++)


        {
            // If first element of lis[] is found
            if (arr[i] == lis[0])
            {
                // Remove lis element from arr[]
                arr.erase(arr.begin()+i) ;
                i--;
  
                // Erase first element of lis[]
                lis.erase(lis.begin()) ;
            }
        }
    }
  
    // print remaining element of array
    int i;
    for (i=0; i < arr.size(); i++)
        cout  << arr[i] << " ";
  
    // print -1 for empty array
    if (i == 0)
        cout << "-1";
}
  
// Driver function
int main()
{
    int input[] = { 3, 2, 6, 4, 5, 1 };
    int n = sizeof(input) / sizeof(input[0]);
  
    // minimize array after deleting LIS
    minimize(input, n);
  
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/size-array-repeated-deletion-lis/

2705
Chapter 375

Smallest length string with


repeated replacement of two
distinct adjacent

Smallest length string with repeated replacement of two distinct adjacent - GeeksforGeeks
Given a string of any combination of three letters ‘a’, ‘b’, and ‘c’, find length of the smallest
string that can be obtained by applying the following operation repeatedly:
Take any two adjacent, distinct characters and replace them with the third.
Examples:

Input : cab
Output : 2
We can select any two adjacent letters,
say 'ca' and transform it into 'b', this
leaves us with string 'bb' of length two.

Input : bcab
Output : 1
Selecting 'bc' and transforming it to 'a'
leaves us with 'aab'. We can then select
'ab' and transform it to 'c', giving 'ac'.
This can further be transformed into 'b',
which is of length one.

A naive way to do this would be to find all possible replacements, and recurse until we find
the minimum string. This would take exponential time.
Lemma: Order of letters does not effect the length or value of minimum string.

2706
Chapter 375. Smallest length string with repeated replacement of two distinct adjacent

Proof By Induction
Base case: Take string ‘ab’ and ‘ba’, they both reduce to ‘c’
Inductive Hypothesis: All strings of length <= k reduce to the same string assuming
the number of occurrences of each letter in each string is the same.
Inductive Step: Take two strings of length k + 1 having same number of occurrences of
each letter. Find a pair of letters that are adjacent
in both strings. Here, two cases arise:

1. We manage to find such a pair of letters. We can then replace these letters with the
third letter, thus getting two strings of length k having same occurrences of each letter,
which by inductive hypothesis reduces to the same string. i.e. We have ‘abcacb’ and
‘accbba’ and reduce ‘ac’ in both strings, we thus get ‘abcbb’ and ‘bcbba’.
2. We cannot find such a pair. This arises when all letters in the string are the same. In
this case, the two strings themselves are the same i.e. ‘ccccccc’ and ‘ccccccc’.

Thus by induction we have proven this lemma.

Dynamic Programming Approach


We can now devise a function using Dynamic Programming to solve this problem.

// C++ program to find smallest possible length


// of a string of only three characters
#include<bits/stdc++.h>
using namespace std;
  
// Program to find length of reduced string
// in a string made of three characters.
#define MAX_LEN 110
  
// To store results of subproblems
int DP[MAX_LEN][MAX_LEN][MAX_LEN];
  
// A memoized function find result recursively.
// a, b and c are counts of 'a's, 'b's and
// 'c's in str
int length(int a, int b, int c)
{
    // If this subproblem is already evaluated
    if (DP[a][b] != -1)
        return DP[a][b];
  
    // If there is only one type of character
    if (a == 0 && b == 0)
        return (DP[a][b] = c);
    if (a == 0 && c == 0)
        return (DP[a][b] = b);

2707
Chapter 375. Smallest length string with repeated replacement of two distinct adjacent

    if (b == 0 && c == 0)
        return (DP[a][b] = a);
  
    // If only two types of characters are present
    if (a == 0)
        return (DP[a][b] =
                    length(a + 1, b - 1, c - 1));
    if (b == 0)
        return (DP[a][b] =
                    length(a - 1, b + 1, c - 1));
    if (c == 0)
        return (DP[a][b] =
                    length(a - 1, b - 1, c + 1));
  
    // If all types of characters are present.
    // Try combining all pairs.
    return (DP[a][b] =
                min(length(a - 1, b - 1, c + 1),
                    min(length(a - 1, b + 1, c - 1),
                        length(a + 1, b - 1, c - 1))));
}
  
// Returns smallest possible length with given
// operation allowed.
int stringReduction(string str)
{
    int n = str.length();
  
    // Counting occurrences of three different
    // characters 'a', 'b' and 'c' in str
    int count[3] = {0};
    for (int i=0; i<n; ++i)
        count[str[i]-'a']++;
  
    // Initialize DP[][] entries as -1
    for (int i = 0; i <= count[0]; ++i)
        for (int j = 0; j < count[1]; ++j)
            for (int k = 0; k < count[2]; ++k)
                DP[i][j][k] = -1;
  
    return length(count[0], count[1], count[2]);
}
  
// Driver code
int main()
{
    string str = "abcbbaacb";
    cout << stringReduction(str);

2708
Chapter 375. Smallest length string with repeated replacement of two distinct adjacent

    return 0;
}

Output:

In the worst case, each letter is present in 1/3rd of the whole string. This leads to auxiliary
space = O(N3 ) and time complexity = O(N3 )

Space Complexity = O(N^3)


Time Complexity = O(N^3)

Mathematical Approach
We can do better than this using three main principles:

1. If the string cannot be reduced further, then all letters in the string are the same.
2. The length of minimum string is either <= 2 or equal to the length of original string,
or 2 < minimum string length < original string length is never true.
3. If each letter of the string is present an odd amount of times, after one reduction step,
they shall all be present an even amount of times. The converse is also true, that is,
if each letter of the string is present an even amount of times, they shall be present
an odd amount of times after one reduction step.

These can be proven as follows:

1. If any two different letters are present, we can select these and reduce string length
further.
2. Proof by contradiction:
Assume we have a reduced string of length less than original string. For example
’bbbbbbb’. Then this string must have originated from a string like ’acbbbbbb’,
’bbacbbbb’ or any other such combination of the same. In this case, we could have
selected ’bc’ instead of ’ac’ and reduced further.
3. From the recursive step above, we increase one letter by one and decrease the other
two by one. So if we had a combination as (odd, odd, odd), then it would become
(odd + 1, odd – 1, odd – 1) or (even, even, even). The reverse is shown in a similar
fashion.

Now we can combine the above principles.


If the string consists of the same letter repeating, it’s minimum reduced string is itself, and
length is the length of the string.
Now, the other possible options are reduced string being of one character length or two.
Now if all characters are present an even number of times, or an odd number of times, the
only answer that is possible is 2, because (0, 2, 0) is (even, even, even) while (0, 1, 0) is
(even, odd, even) so only 2 preserves this evenness.
In any other condition, the answer becomes 1.

2709
Chapter 375. Smallest length string with repeated replacement of two distinct adjacent

// C++ program to find smallest possible length


// of a string of only three characters
#include<bits/stdc++.h>
using namespace std;
  
// Returns smallest possible length with given
// operation allowed.
int stringReduction(string str)
{
    int n = str.length();
  
    // Counint occurrences of three different
    // characters 'a', 'b' and 'c' in str
    int count[3] = {0};
    for (int i=0; i<n; ++i)
        count[str[i]-'a']++;
  
    // If all characters are same.
    if (count[0] == n || count[1] == n ||
        count[2] == n)
        return n;
  
    // If all characters are present even number
    // of times or all are present odd number of
    // times.
    if ((count[0] % 2) == (count[1] % 2) &&
        (count[1] % 2) == (count[2] % 2))
        return 2;
  
    // Answer is 1 for all other cases.
    return 1;
}
  
// Driver code
int main()
{
    string str = "abcbbaacb";
    cout << stringReduction(str);
    return 0;
}

Output:

Time Complexity = O(n)


Auxiliary Space = O(1)

2710
Chapter 375. Smallest length string with repeated replacement of two distinct adjacent

Source

https://www.geeksforgeeks.org/smallest-length-string-with-repeated-replacement-of-two-distinct-adjacent/

2711
Chapter 376

Smallest number with given


sum of digits and sum of square
of digits

Smallest number with given sum of digits and sum of square of digits - GeeksforGeeks

Given sum of digits and sum of square of digits . Find the smallest number with given
sum of digits and sum of the square of digits. The number should not contain more than
100 digits. Print -1 if no such number exists or if the number of digits is more than 100.
Examples:

Input : a = 18, b = 162


Output : 99
Explanation : 99 is the smallest possible number whose sum of digits = 9 + 9
= 18 and sum of squares of digits is 92 +92 = 162.
Input : a = 12, b = 9
Output : -1

Approach:
Since the smallest number can be of 100 digits, it cannot be stored. Hence the first step to
solve it will be to find the minimum number of digits which can give us the sum of digits
as and sum of the square of digits as . To find the minimum number of digits, we can
use Dynamic Programming. DP[a][b] signifies the minimum number of digits in a number
whose sum of the digits will be and sum of the square of digits will be . If there does
not exist any such number then DP[a][b] will be -1.
Since the number cannot exceed 100 digits, DP array will be of size 101*8101. Iterate for
every digit, and try all possible combination of digits which gives us the sum of digits as
and sum of the square of digits as . Store the minimum number of digits in DP[a][b] using
the below recurrence relation:

2712
Chapter 376. Smallest number with given sum of digits and sum of square of digits

DP[a][b] = min( minimumNumberOfDigits(a – i, b – (i * i)) + 1 )


where 1<=i<=9

After getting the minimum number of digits, find the digits. To find the digits, check for all
combinations and print those digits which satisfies the condition below:

1 + dp[a – i][b – i * i] == dp[a][b]


where 1<=i<=9

If the condition above is met by any of i, reduce by i and by i*i and break. Keep on
repeating the above process to find all the digits till is 0 and is 0.
Below is the C++ implementation of above approach:

// CPP program to find the Smallest number 


// with given sum of digits and
// sum of square of digits
#include <bits/stdc++.h>
using namespace std;
  
int dp[901][8101];
  
// Top down dp to find minimum number of digits with
// given sum of dits a and sum of square of digits as b
int minimumNumberOfDigits(int a, int b)
{
    // Invalid condition 
    if (a > b || a < 0 || b < 0 || a > 900 || b > 8100)
        return -1;
      
    // Number of digits satisfied
    if (a == 0 && b == 0)
        return 0;
      
    // Memoization
    if (dp[a][b] != -1)
        return dp[a][b];
      
    // Intialize ans as maximum as we have to find the  
    // minimum number of digits 
    int ans = 101; 
      
    // Check for all possible combinations of digits
    for (int i = 9; i >= 1; i--) {
          
        // recurrence call 
        int k = minimumNumberOfDigits(a - i, b - (i * i)); 

2713
Chapter 376. Smallest number with given sum of digits and sum of square of digits

          
        // If the combination of digits cannot give sum as a 
        // and sum of square of digits as b 
        if (k != -1)
            ans = min(ans, k + 1);
    }
      
    // Returns the minimum number of digits
    return dp[a][b] = ans;
}
  
// Function to print the digits that gives 
// sum as a and sum of square of digits as b
void printSmallestNumber(int a,int b)
{
      
    // initialize the dp array as -1
    memset(dp, -1, sizeof(dp));
      
    // base condition 
    dp[0][0] = 0;
      
    // function call to get the minimum number of digits  
    int k = minimumNumberOfDigits(a, b); 
      
    // When there does not exists any number
    if (k == -1 || k > 100)
        cout << "-1";
    else {
        // Printing the digits from the most significant digit
        while (a > 0 && b > 0) {
  
            // Trying all combinations 
            for (int i = 1; i <= 9; i++) {
                // checking conditions for minimum digits
                if (a >= i && b >= i * i && 
                    1 + dp[a - i][b - i * i] == dp[a][b]) {
                    cout << i;
                    a -= i;
                    b -= i * i;
                    break;
                }
            }
        }
    }
}
  
// Driver Code

2714
Chapter 376. Smallest number with given sum of digits and sum of square of digits

int main()
{
    int a = 18, b = 162;
    // Function call to print the smallest number 
    printSmallestNumber(a,b); 
}

Output:

99

Time Complexity : O(900*8100*9)


Auxiliary Space : O(900*8100)
Note: Time complexity is in terms of numbers as we are trying all possible combinations
of digits.

Source

https://www.geeksforgeeks.org/smallest-number-with-given-sum-of-digits-and-sum-of-square-of-digits/

2715
Chapter 377

Smallest sum contiguous


subarray

Smallest sum contiguous subarray - GeeksforGeeks


Given an array containing n integers. The problem is to find the sum of the elements of the
contiguous subarray having the smallest(minimum) sum.
Examples:

Input : arr[] = {3, -4, 2, -3, -1, 7, -5}


Output : -6
Subarray is {-4, 2, -3, -1} = -6

Input : arr = {2, 6, 8, 1, 4}


Output : 1

Naive Approach: Consider all the contiguous subarrays of diiferent sizes and find their
sum. The subarray having the smallest(minimum) sum is the required answer.
Efficient Approach: It is a variation to the problem of finding the largest sum contiguous
subarray based on the idea of Kadane’s algorithm.
Algorithm:

smallestSumSubarr(arr, n)
Initialize min_ending_here = INT_MAX
Initialize min_so_far = INT_MAX

for i = 0 to n-1
if min_ending_here > 0
min_ending_here = arr[i]

2716
Chapter 377. Smallest sum contiguous subarray

else
min_ending_here += arr[i]
min_so_far = min(min_so_far, min_ending_here)

return min_so_far

C++

// C++ implementation to find the smallest sum


// contiguous subarray
#include <bits/stdc++.h>
  
using namespace std;
  
// function to find the smallest sum contiguous subarray
int smallestSumSubarr(int arr[], int n)
{
    // to store the minimum value that is ending
    // up to the current index
    int min_ending_here = INT_MAX;
      
    // to store the minimum value encountered so far
    int min_so_far = INT_MAX;
      
    // traverse the array elements
    for (int i=0; i<n; i++)
    {
        // if min_ending_here > 0, then it could not possibly
        // contribute to the minimum sum further
        if (min_ending_here > 0)
            min_ending_here = arr[i];
          
        // else add the value arr[i] to min_ending_here    
        else
            min_ending_here += arr[i];
          
        // update min_so_far
        min_so_far = min(min_so_far, min_ending_here);            
    }
      
    // required smallest sum contiguous subarray value
    return min_so_far;
}
  
  
// Driver program to test above
int main()
{

2717
Chapter 377. Smallest sum contiguous subarray

    int arr[] = {3, -4, 2, -3, -1, 7, -5};


    int n = sizeof(arr) / sizeof(arr[0]);
    cout << "Smallest sum: "
         << smallestSumSubarr(arr, n);
    return 0;     

Java

// Java implementation to find the smallest sum


// contiguous subarray
class GFG {
      
    // function to find the smallest sum contiguous
    // subarray
    static int smallestSumSubarr(int arr[], int n)
    {
          
        // to store the minimum value that is 
        // ending up to the current index
        int min_ending_here = 2147483647;
          
        // to store the minimum value encountered
        // so far
        int min_so_far = 2147483647;
          
        // traverse the array elements
        for (int i = 0; i < n; i++)
        {
              
            // if min_ending_here > 0, then it could
            // not possibly contribute to the 
            // minimum sum further
            if (min_ending_here > 0)
                min_ending_here = arr[i];
              
            // else add the value arr[i] to 
            // min_ending_here 
            else
                min_ending_here += arr[i];
              
            // update min_so_far
            min_so_far = Math.min(min_so_far,
                                   min_ending_here);         
        }
          
        // required smallest sum contiguous 
        // subarray value

2718
Chapter 377. Smallest sum contiguous subarray

        return min_so_far;
    }
      
    // Driver method
    public static void main(String[] args)
    {
          
        int arr[] = {3, -4, 2, -3, -1, 7, -5};
        int n = arr.length;
          
        System.out.print("Smallest sum: "
                + smallestSumSubarr(arr, n));
    }
}
  
// This code is contributed by Anant Agarwal.

Python

# Python program to find the smallest sum


# contiguous subarray
import sys
  
# function to find the smallest sum 
# contiguous subarray
def smallestSumSubarr(arr, n):
    # to store the minimum value that is ending
    # up to the current index
    min_ending_here = sys.maxint
      
    # to store the minimum value encountered so far
    min_so_far = sys.maxint
      
    # traverse the array elements
    for i in range(n):
        # if min_ending_here > 0, then it could not possibly
        # contribute to the minimum sum further
        if (min_ending_here > 0):
            min_ending_here = arr[i]
          
        # else add the value arr[i] to min_ending_here 
        else:
            min_ending_here += arr[i]
           
        # update min_so_far
        min_so_far = min(min_so_far, min_ending_here)
      
    # required smallest sum contiguous subarray value

2719
Chapter 377. Smallest sum contiguous subarray

    return min_so_far
      
# Driver code
arr = [3, -4, 2, -3, -1, 7, -5]
n = len(arr)
print "Smallest sum: ", smallestSumSubarr(arr, n)
  
# This code is contributed by Sachin Bisht

C#

// C# implementation to find the 


// smallest sum contiguous subarray
using System;
  
class GFG {
  
    // function to find the smallest sum 
    // contiguous subarray
    static int smallestSumSubarr(int[] arr, int n)
    {
        // to store the minimum value that is
        // ending up to the current index
        int min_ending_here = 2147483647;
  
        // to store the minimum value encountered
        // so far
        int min_so_far = 2147483647;
  
        // traverse the array elements
        for (int i = 0; i < n; i++) {
  
            // if min_ending_here > 0, then it could
            // not possibly contribute to the
            // minimum sum further
            if (min_ending_here > 0)
                min_ending_here = arr[i];
  
            // else add the value arr[i] to
            // min_ending_here
            else
                min_ending_here += arr[i];
  
            // update min_so_far
            min_so_far = Math.Min(min_so_far,
                                min_ending_here);
        }
  

2720
Chapter 377. Smallest sum contiguous subarray

        // required smallest sum contiguous


        // subarray value
        return min_so_far;
    }
  
    // Driver method
    public static void Main()
    {
  
        int[] arr = { 3, -4, 2, -3, -1, 7, -5 };
        int n = arr.Length;
  
        Console.Write("Smallest sum: " +
             smallestSumSubarr(arr, n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP implementation to find the 
// smallest sum contiguous subarray
  
// function to find the smallest
// sum contiguous subarray
function smallestSumSubarr($arr, $n)
{
      
    // to store the minimum 
    // value that is ending
    // up to the current index
    $min_ending_here = 999999;
      
    // to store the minimum value
    // encountered so far
    $min_so_far = 999999;
      
    // traverse the array elements
    for($i = 0; $i < $n; $i++)
    {
          
        // if min_ending_here > 0, 
        // then it could not possibly
        // contribute to the minimum 
        // sum further
        if ($min_ending_here > 0)

2721
Chapter 377. Smallest sum contiguous subarray

            $min_ending_here = $arr[$i];
          
        // else add the value arr[i] 
        // to min_ending_here 
        else
            $min_ending_here += $arr[$i];
          
        // update min_so_far
        $min_so_far = min($min_so_far, 
                     $min_ending_here);         
    }
      
    // required smallest sum 
    // contiguous subarray value
    return $min_so_far;
}
  
  
    // Driver Code
    $arr = array(3, -4, 2, -3, -1, 7, -5);
    $n = count($arr) ;
    echo "Smallest sum: "
         .smallestSumSubarr($arr, $n);
  
// This code is contributed by Sam007
?>

Output:

Smallest sum: -6

Time Complexity: O(n)


Improved By : Sam007

Source

https://www.geeksforgeeks.org/smallest-sum-contiguous-subarray/

2722
Chapter 378

Space and time efficient


Binomial Coefficient

Space and time efficient Binomial Coefficient - GeeksforGeeks


Write a function that takes two parameters n and k and returns the value of Binomial
Coefficient C(n, k). For example, your function should return 6 for n = 4 and k = 2, and it
should return 10 for n = 5 and k = 2.
We have discussed a O(n*k) time and O(k) extra space algorithm in thispost. The value of
C(n, k) can be calculated in O(k) time and O(1) extra space.

C(n, k) = n! / (n-k)! * k!
= [n * (n-1) *....* 1] / [ ( (n-k) * (n-k-1) * .... * 1) *
( k * (k-1) * .... * 1 ) ]
After simplifying, we get
C(n, k) = [n * (n-1) * .... * (n-k+1)] / [k * (k-1) * .... * 1]

Also, C(n, k) = C(n, n-k) // we can change r to n-r if r > n-r

Following implementation uses above formula to calculate C(n, k)

C/C++

// Program to calculate C(n ,k)


#include <stdio.h>
  
// Returns value of Binomial Coefficient C(n, k)
int binomialCoeff(int n, int k)
{
    int res = 1;

2723
Chapter 378. Space and time efficient Binomial Coefficient

  
    // Since C(n, k) = C(n, n-k)
    if ( k > n - k )
        k = n - k;
  
    // Calculate value of [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
    for (int i = 0; i < k; ++i)
    {
        res *= (n - i);
        res /= (i + 1);
    }
  
    return res;
}
  
/* Drier program to test above function*/
int main()
{
    int n = 8, k = 2;
    printf ("Value of C(%d, %d) is %d ", n, k, binomialCoeff(n, k) );
    return 0;
}

Java

// Program to calculate C(n ,k) in java


class BinomialCoefficient
{
    // Returns value of Binomial Coefficient C(n, k)
    static int binomialCoeff(int n, int k)
    {
        int res = 1;
      
        // Since C(n, k) = C(n, n-k)
        if ( k > n - k )
            k = n - k;
      
        // Calculate value of [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
        for (int i = 0; i < k; ++i)
        {
        res *= (n - i);
        res /= (i + 1);
        }
      
        return res;
    }
      
    /* Driver program to test above function*/

2724
Chapter 378. Space and time efficient Binomial Coefficient

    public static void main(String[] args)


    {
        int n = 8;
        int k = 2;
        System.out.println("Value of C("+ n + ", " + k+ ") "
                                + "is" + " "+ binomialCoeff(n, k));
    }
  
}
// This Code is Contributed by Saket Kumar

Python

# Python program to calculate C(n ,k)


  
# Returns value of Binomial Coefficient
# C(n, k)
def binomialCoefficient(n, k):
    # since C(n, k) = C(n, n - k)
    if(k > n - k):
        k = n - k
    # initialize result
    res = 1
    # Calculate value of 
    # [n * (n-1) *---* (n-k + 1)] / [k * (k-1) *----* 1]
    for i in range(k):
        res = res * (n - i)
        res = res / (i + 1)
    return res
  
# Driver program to test above function 
n = 8
k = 2
res = binomialCoefficient(n, k)
print("Value of C(%d, %d) is %d" %(n, k, res))
  
# This code is contributed by Aditi Sharma

C#

// C# Program to calculate C(n, k) 


using System;
  
class BinomialCoefficient
{
      
    // Returns value of Binomial 

2725
Chapter 378. Space and time efficient Binomial Coefficient

    // Coefficient C(n, k)


    static int binomialCoeff(int n, int k)
    {
        int res = 1;
      
        // Since C(n, k) = C(n, n-k)
        if ( k > n - k )
            k = n - k;
      
        // Calculate value of [n * ( n - 1) *---* (
        // n - k + 1)] / [k * (k - 1) *----* 1]
        for (int i = 0; i < k; ++i)
        {
        res *= (n - i);
        res /= (i + 1);
        }
      
        return res;
    }
      
    // Driver Code
    public static void Main()
    {
        int n = 8;
        int k = 2;
        Console.Write("Value of C("+ n + ", " + k+ ") "
                       + "is" + " "+ binomialCoeff(n, k));
    }
  
}
  
// This Code is Contributed by 
// Smitha Dinesh Semwal.

PHP

<?php
// Program to calculate C(n ,k)
// Returns value of Binomial 
// Coefficient C(n, k)
  
function binomialCoeff($n,$k)
{
    $res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if ( $k > $n - $k )
        $k = $n - $k;

2726
Chapter 378. Space and time efficient Binomial Coefficient

  
    // Calculate value of 
    // [n * (n-1) *---* (n-k+1)] / 
    // [k * (k-1) *----* 1]
    for ($i = 0; $i < $k; ++$i)
    {
        $res *= ($n - $i);
        $res /= ($i + 1);
    }
  
    return $res;
}
  
    // Driver Code
    $n = 8;
    $k = 2;
    echo " Value of C ($n, $k) is ",
             binomialCoeff($n, $k);
  
// This code is contributed by ajit.
?>

Value of C(8, 2) is 28

Time Complexity: O(k)


Auxiliary Space: O(1)
This article is compiled by Aashish Barnwaland reviewed by GeeksforGeeks team. Please
write comments if you find anything incorrect, or you want to share more information about
the topic discussed above.
Improved By : Smitha Dinesh Semwal, jit_t

Source

https://www.geeksforgeeks.org/space-and-time-efficient-binomial-coefficient/

2727
Chapter 379

Sub-tree with minimum color


difference in a 2-coloured tree

Sub-tree with minimum color difference in a 2-coloured tree - GeeksforGeeks


A tree with N nodes and N-1 edges is given with 2 different colours for its nodes.
Find the sub-tree with minimum colour difference i.e. abs(1-colour nodes – 2-colour nodes)
is minimum.
Examples:

Input :
Edges : 1 2
1 3
2 4
3 5
Colours : 1 1 2 2 1 [1-based indexing where
index denotes the node]
Output : 2
Explanation : The sub-tree {1-2} and {1-2-3-5}
have color difference of 2. Sub-tree {1-2} has two
1-colour nodes and zero 2-colour nodes. So, color
difference is 2. Sub-tree {1-2-3-5} has three 1-colour
nodes and one 2-colour nodes. So color diff = 2.

Method 1 : The problem can be solved by checking every possible sub-tree from every
node of the tree. This will take exponential time as we will check for sub-trees from every
node.
Method 2 : (Efficient) If we observe, we are solving a portion of the tree several times.
This produces recurring sub-problems. We can use Dynamic Programming approach to
get the minimum color difference in one traversal. To make things simpler, we can have

2728
Chapter 379. Sub-tree with minimum color difference in a 2-coloured tree

color values as 1 and -1. Now, if we have a sub-tree with both colored nodes equal, our sum
of colors will be 0. To get the minimum difference, we should have maximum negative sum
or maximum positive sum.

• Case 1 When we need to have a sub-tree with maximum sum : We take a node if its
value > 0, i.e. sum(parent) += max(0, sum(child))
• Case 2 When we need to have a sub-tree with minimum sum(or max negative sum) :
We take a node if its value < 0, i.e. sum(parent) += min(0, sum(child))

To get the minimum sum, we can interchange the colors of nodes, i.e. -1 becomes 1 and
vice-versa.
Below is the C++ implementation :

// CPP code to find the sub-tree with minimum color


// difference in a 2-coloured tree
#include <bits/stdc++.h>
using namespace std;
  
// Tree traversal to compute minimum difference
void dfs(int node, int parent, vector<int> tree[], 
                    int colour[], int answer[])
{
    // Initial min difference is the color of node
    answer[node] = colour[node];
  
    // Traversing its children
    for (auto u : tree[node]) {
  
        // Not traversing the parent
        if (u == parent)
            continue;
  
        dfs(u, node, tree, colour, answer);
  
        // If the child is adding positively to
        // difference, we include it in the answer
        // Otherwise, we leave the sub-tree and 
        // include 0 (nothing) in the answer
        answer[node] += max(answer[u], 0);
    }
}
  
int maxDiff(vector<int> tree[], int colour[], int N)
{
       int answer[N + 1];
       memset(answer, 0, sizeof(answer));
  

2729
Chapter 379. Sub-tree with minimum color difference in a 2-coloured tree

    // DFS for colour difference : 1colour - 2colour


    dfs(1, 0, tree, colour, answer);
  
    // Minimum colour difference is maximum answer value
    int high = 0;
    for (int i = 1; i <= N; i++) {
        high = max(high, answer[i]);
  
        // Clearing the current value
        // to check for colour2 as well
        answer[i] = 0;
    }
  
    // Interchanging the colours
    for (int i = 1; i <= N; i++) {
        if (colour[i] == -1)
            colour[i] = 1;
        else
            colour[i] = -1;
    }
  
    // DFS for colour difference : 2colour - 1colour
    dfs(1, 0, tree, colour, answer);
  
    // Checking if colour2 makes the minimum colour 
    // difference
    for (int i = 1; i < N; i++)
        high = max(high, answer[i]);
          
    return high;
}
  
// Driver code
int main()
{
    // Nodes
    int N = 5;
  
    // Adjacency list representation
    vector<int> tree[N + 1];
  
    // Edges
    tree[1].push_back(2);
    tree[2].push_back(1);
  
    tree[1].push_back(3);
    tree[3].push_back(1);
  

2730
Chapter 379. Sub-tree with minimum color difference in a 2-coloured tree

    tree[2].push_back(4);
    tree[4].push_back(2);
  
    tree[3].push_back(5);
    tree[5].push_back(3);
  
    // Index represent the colour of that node
    // There is no Node 0, so we start from 
    // index 1 to N
    int colour[] = { 0, 1, 1, -1, -1, 1 };
  
    // Printing the result
    cout << maxDiff(tree,  colour,  N);
      
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/sub-tree-minimum-color-difference-2-coloured-tree/

2731
Chapter 380

Subset Sum Problem in O(sum)


space

Subset Sum Problem in O(sum) space - GeeksforGeeks


Given an array of non-negative integers and a value sum, determine if there is a subset of
the given set with sum equal to given sum.
Examples:

Input : arr[] = {4, 1, 10, 12, 5, 2},


sum = 9
Output : TRUE
{4, 5} is a subset with sum 9.

Input : arr[] = {1, 8, 2, 5},


sum = 4
Output : FALSE
There exists no subset with sum 4.

We have discussed a Dynamic Programmingbased solution in below post.


Dynamic Programming | Set 25 (Subset Sum Problem)
The solution discussed above requires O(n * sum) space and O(n * sum) time. We cab opti-
mize space. We create a boolean 2D array subset[2][sum+1]. Using bottom up manner we
can fill up this table. The idea behind using 2 in “subset[2][sum+1]” is that for filling a
row only the values from previous row is required. So alternate rows are used either making
the first one as current and second as previous or the first as previous and second as current.

C++

// Returns true if there exists a subset

2732
Chapter 380. Subset Sum Problem in O(sum) space

// with given sum in arr[]


#include <stdio.h>
#include <stdbool.h>
  
bool isSubsetSum(int arr[], int n, int sum)
{
    // The value of subset[i%2][j] will be true 
    // if there exists a subset of sum j in 
    // arr[0, 1, ...., i-1]
    bool subset[2][sum + 1];
  
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= sum; j++) {
  
            // A subset with sum 0 is always possible 
            if (j == 0)
                subset[i % 2][j] = true; 
  
            // If there exists no element no sum 
            // is possible 
            else if (i == 0)
                subset[i % 2][j] = false; 
            else if (arr[i - 1] <= j)
                subset[i % 2][j] = subset[(i + 1) % 2]
             [j - arr[i - 1]] || subset[(i + 1) % 2][j];
            else
                subset[i % 2][j] = subset[(i + 1) % 2][j];
        }
    }
  
    return subset[n % 2][sum];
}
  
// Driver code
int main()
{
    int arr[] = { 6, 2, 5 };
    int sum = 7;
    int n = sizeof(arr) / sizeof(arr[0]);
    if (isSubsetSum(arr, n, sum) == true)
        printf("There exists a subset with given sum");
    else
        printf("No subset exists with given sum");
    return 0;
}

Java

2733
Chapter 380. Subset Sum Problem in O(sum) space

// Java Program to get a subset with a 


// with a sum provided by the user
public class Subset_sum {
      
    // Returns true if there exists a subset
    // with given sum in arr[]
    static boolean isSubsetSum(int arr[], int n, int sum)
    {
        // The value of subset[i%2][j] will be true 
        // if there exists a subset of sum j in 
        // arr[0, 1, ...., i-1]
        boolean subset[][] = new boolean[2][sum + 1];
       
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= sum; j++) {
       
                // A subset with sum 0 is always possible 
                if (j == 0)
                    subset[i % 2][j] = true; 
       
                // If there exists no element no sum 
                // is possible 
                else if (i == 0)
                    subset[i % 2][j] = false; 
                else if (arr[i - 1] <= j)
                    subset[i % 2][j] = subset[(i + 1) % 2]
                 [j - arr[i - 1]] || subset[(i + 1) % 2][j];
                else
                    subset[i % 2][j] = subset[(i + 1) % 2][j];
            }
        }
       
        return subset[n % 2][sum];
    }
       
    // Driver code
    public static void main(String args[])
    {
        int arr[] = { 1, 2, 5 };
        int sum = 7;
        int n = arr.length;
        if (isSubsetSum(arr, n, sum) == true)
            System.out.println("There exists a subset with" + 
                                              "given sum");
        else
            System.out.println("No subset exists with" + 
                                           "given sum");
    }

2734
Chapter 380. Subset Sum Problem in O(sum) space

}
// This code is contributed by Sumit Ghosh

Python

# Returns true if there exists a subset


# with given sum in arr[]
  
def isSubsetSum(arr, n, sum):
     
    # The value of subset[i%2][j] will be true 
    # if there exists a subset of sum j in 
    # arr[0, 1, ...., i-1]
    subset = [ [False for j in range(sum + 1)] for i in range(3) ]
   
    for i in range(n + 1):
        for j in range(sum + 1):
            # A subset with sum 0 is always possible 
            if (j == 0):
                subset[i % 2][j] = True
   
            # If there exists no element no sum 
            # is possible 
            elif (i == 0):
                subset[i % 2][j] = False
            elif (arr[i - 1] <= j):
                subset[i % 2][j] = subset[(i + 1) % 2][j - arr[i - 1]] or subset[(i + 1) 
                                                                               % 2][j]
            else:
                subset[i % 2][j] = subset[(i + 1) % 2][j]
                  
    return subset[n % 2][sum]
   
# Driver code
arr = [ 6, 2, 5 ]
sum = 7
n = len(arr)
if (isSubsetSum(arr, n, sum) == True):
    print ("There exists a subset with given sum")
else:
    print ("No subset exists with given sum")
      
# This code is contributed by Sachin Bisht

Output:

There exists a subset with given sum

2735
Chapter 380. Subset Sum Problem in O(sum) space

Source

https://www.geeksforgeeks.org/subset-sum-problem-osum-space/

2736
Chapter 381

Subset with sum divisible by m

Subset with sum divisible by m - GeeksforGeeks


Given a set of non-negative distinct integers, and a value m, determine if there is a subset
of the given set with sum divisible by m.
Input Constraints
Size of set i.e., n <= 1000000, m <= 1000
Examples:

Input : arr[] = {3, 1, 7, 5};


m = 6;
Output : YES

Input : arr[] = {1, 6};


m = 5;
Output : NO

This problem is a variant of subset sum problem. In subset sum problem we check if given
sum subset exist or not, here we need to find if there exist some subset with sum divisible
by m or not. Seeing input constraint, it looks like typical DP solution will work in O(nm)
time. But in tight time limits in competitive programming, the solution may work. Also
auxiliary space is high for DP table, but here is catch.
If n > m there will always be a subset with sum divisible by m (which is easy to prove
with pigeonhole principle). So we need to handle only cases of n <= m .
For n <= m we create a boolean DP table which will store the status of each value from
0 to m-1 which are possible subset sum (modulo m) which have been encountered so far.
Now we loop through each element of given array arr[], and we add (modulo m) j which have
DP[j] = true and store all the such (j+arr[i])%m possible subset sum in a boolean array
temp, and at the end of iteration over j, we update DP table with temp. Also we add arr[i]
to DP ie.. DP[arr[i]%m] = true.

2737
Chapter 381. Subset with sum divisible by m

In the end if DP[0] is true then it means YES there exist a subset with sum which is divisible
by m, else NO.
C++

// C++ program to check if there is a subset


// with sum divisible by m.
#include <bits/stdc++.h>
using namespace std;
  
// Returns true if there is a subset
// of arr[] with sum divisible by m
bool modularSum(int arr[], int n, int m)
{
    if (n > m)
        return true;
  
    // This array will keep track of all
    // the possible sum (after modulo m)
    // which can be made using subsets of arr[]
    // initialising boolean array with all false
    bool DP[m];
    memset(DP, false, m);
  
    // we'll loop through all the elements of arr[]
    for (int i=0; i<n; i++)
    {
        // anytime we encounter a sum divisible
        // by m, we are done
        if (DP[0])
            return true;
  
        // To store all the new encountered sum (after
        // modulo). It is used to make sure that arr[i]
        // is added only to those entries for which DP[j] 
        // was true before current iteration.  
        bool temp[m];
        memset(temp,false,m);
  
        // For each element of arr[], we loop through
        // all elements of DP table from 1 to m and
        // we add current element i. e., arr[i] to
        // all those elements which are true in DP
        // table
        for (int j=0; j<m; j++)
        {
            // if an element is true in DP table
            if (DP[j] == true)
            {

2738
Chapter 381. Subset with sum divisible by m

                if (DP[(j+arr[i]) % m] == false)


  
                    // We update it in temp and update
                    // to DP once loop of j is over
                    temp[(j+arr[i]) % m] = true;
            }
        }
  
        // Updating all the elements of temp
        // to DP table since iteration over
        // j is over
        for (int j=0; j<m; j++)
            if (temp[j])
                DP[j] = true;
  
  
        // Also since arr[i] is a single element
        // subset, arr[i]%m is one of the possible
        // sum
        DP[arr[i]%m] = true;
    }
  
    return DP[0];
}
  
// Driver code
int main()
{
    int arr[] = {1, 7};
    int n = sizeof(arr)/sizeof(arr[0]);
    int m = 5;
  
    modularSum(arr, n, m) ?  cout << "YES\n" :
                             cout << "NO\n";
  
    return 0;
}

Java

// Java program to check if there is a subset


// with sum divisible by m.
import java.util.Arrays;
  
class GFG {
      
    // Returns true if there is a subset
    // of arr[] with sum divisible by m

2739
Chapter 381. Subset with sum divisible by m

    static boolean modularSum(int arr[], 


                                int n, int m)
    {
        if (n > m)
            return true;
      
        // This array will keep track of all
        // the possible sum (after modulo m)
        // which can be made using subsets of arr[]
        // initialising boolean array with all false
        boolean DP[]=new boolean[m];
          
        Arrays.fill(DP, false);
      
        // we'll loop through all the elements
        // of arr[]
        for (int i = 0; i < n; i++)
        {
              
            // anytime we encounter a sum divisible
            // by m, we are done
            if (DP[0])
                return true;
      
            // To store all the new encountered sum
            // (after modulo). It is used to make 
            // sure that arr[i] is added only to 
            // those entries for which DP[j] 
            // was true before current iteration. 
            boolean temp[] = new boolean[m];
            Arrays.fill(temp, false);
      
            // For each element of arr[], we loop 
            // through all elements of DP table 
            // from 1 to m and we add current 
            // element i. e., arr[i] to all those 
            // elements which are true in DP table
            for (int j = 0; j < m; j++)
            {
                  
                // if an element is true in 
                // DP table
                if (DP[j] == true)
                {
                    if (DP[(j + arr[i]) % m] == false)
      
                        // We update it in temp and update
                        // to DP once loop of j is over

2740
Chapter 381. Subset with sum divisible by m

                        temp[(j + arr[i]) % m] = true;


                }
            }
      
            // Updating all the elements of temp
            // to DP table since iteration over
            // j is over
            for (int j = 0; j < m; j++)
                if (temp[j])
                    DP[j] = true;
      
      
            // Also since arr[i] is a single 
            // element subset, arr[i]%m is one 
            // of the possible sum
            DP[arr[i] % m] = true;
        }
      
        return DP[0];
    }
      
    //driver code
    public static void main(String arg[])
    {
        int arr[] = {1, 7};
        int n = arr.length;
        int m = 5;
      
        if(modularSum(arr, n, m))
            System.out.print("YES\n");
        else
            System.out.print("NO\n");
    }
}
  
//This code is contributed by Anant Agarwal.

Python3

# Python3 program to check if there is 


# a subset with sum divisible by m.
  
# Returns true if there is a subset
# of arr[] with sum divisible by m
def modularSum(arr, n, m):
  
    if (n > m):
        return True

2741
Chapter 381. Subset with sum divisible by m

  
    # This array will keep track of all
    # the possible sum (after modulo m)
    # which can be made using subsets of arr[]
    # initialising boolean array with all false
    DP = [False for i in range(m)]
  
    # we'll loop through all the elements of arr[]
    for i in range(n):
      
        # anytime we encounter a sum divisible
        # by m, we are done
        if (DP[0]):
            return True
  
        # To store all the new encountered sum (after
        # modulo). It is used to make sure that arr[i]
        # is added only to those entries for which DP[j] 
        # was true before current iteration. 
        temp = [False for i in range(m)]
  
        # For each element of arr[], we loop through
        # all elements of DP table from 1 to m and
        # we add current element i. e., arr[i] to
        # all those elements which are true in DP
        # table
        for j in range(m):
          
            # if an element is true in DP table
            if (DP[j] == True):
              
                if (DP[(j + arr[i]) % m] == False):
  
                    # We update it in temp and update
                    # to DP once loop of j is over
                    temp[(j + arr[i]) % m] = True
              
        # Updating all the elements of temp
        # to DP table since iteration over
        # j is over
        for j in range(m):
            if (temp[j]):
                DP[j] = True
  
        # Also since arr[i] is a single element
        # subset, arr[i]%m is one of the possible
        # sum
        DP[arr[i] % m] = True

2742
Chapter 381. Subset with sum divisible by m

      
    return DP[0]
  
# Driver code
arr = [1, 7]
n = len(arr)
m = 5
print("YES") if(modularSum(arr, n, m)) else print("NO")
  
# This code is contributed by Anant Agarwal.

C#

// C# program to check if there is


// a subset with sum divisible by m.
using System;
  
class GFG {
      
// Returns true if there is a subset
// of arr[] with sum divisible by m
static bool modularSum(int []arr, int n,
                                  int m)
{
    if (n > m)
        return true;
   
    // This array will keep track of all
    // the possible sum (after modulo m)
    // which can be made using subsets of arr[]
    // initialising boolean array with all false
    bool []DP=new bool[m];
    for (int l=0;l<DP.Length;l++)
        DP[l]=false;
   
    // we'll loop through all the elements of arr[]
    for (int i=0; i<n; i++)
    {
        // anytime we encounter a sum divisible
        // by m, we are done
        if (DP[0])
            return true;
   
        // To store all the new encountered sum (after
        // modulo). It is used to make sure that arr[i]
        // is added only to those entries for which DP[j] 
        // was true before current iteration.  
        bool []temp=new bool[m];

2743
Chapter 381. Subset with sum divisible by m

        for (int l=0;l<temp.Length;l++)


        temp[l]=false;
   
        // For each element of arr[], we loop through
        // all elements of DP table from 1 to m and
        // we add current element i. e., arr[i] to
        // all those elements which are true in DP
        // table
        for (int j=0; j<m; j++)
        {
            // if an element is true in DP table
            if (DP[j] == true)
            {
                if (DP[(j+arr[i]) % m] == false)
   
                    // We update it in temp and update
                    // to DP once loop of j is over
                    temp[(j+arr[i]) % m] = true;
            }
        }
   
        // Updating all the elements of temp
        // to DP table since iteration over
        // j is over
        for (int j=0; j<m; j++)
            if (temp[j])
                DP[j] = true;
   
   
        // Also since arr[i] is a single element
        // subset, arr[i]%m is one of the possible
        // sum
        DP[arr[i]%m] = true;
    }
   
    return DP[0];
}
  
//driver code
public static void Main()

     int []arr = {1, 7};
    int n = arr.Length;
    int m = 5;
  
    if(modularSum(arr, n, m))
    Console.Write("YES\n");
    else

2744
Chapter 381. Subset with sum divisible by m

    Console.Write("NO\n");
}
}
  
//This code is contributed by Anant Agarwal.

Output:

NO

Time Complexity : O(m^2)


Auxiliary Space : O(m)

Source

https://www.geeksforgeeks.org/subset-sum-divisible-m/

2745
Chapter 382

Sudo Placement[1.5] | Wolfish

Sudo Placement[1.5] | Wolfish - GeeksforGeeks


Given a N x N matrix where value at cell (i, j) is the cost of moving from a cell (i, j) to cell
(i – 1, j – 1), (i – 1, j) or (i, j – 1). Your task is to find the maximum cost path from (N – 1,
N – 1) cell to (0, 0) cell in the N x N matrix (0 – based indexing). However, you have some
restrictions on the movement from one cell to the other cell. If you are at (i, j) cell and (i +
j) is a power of 2, you can only move to (i – 1, j – 1) cell. If (i + j) is not a power of 2 then
you can move to (i – 1, j) or (i, j – 1)
Examples:

Input :[1 2 3 1
4 5 6 1
7 8 9 1
1 1 1 1]
Output: 16
The maximum cost path is:
(3, 3) -> (3, 2) -> (2, 2) -> (1, 1) -> (0, 0).
Cost pathwise is:
1 + 1 + 9 + 5 = 16.

Input: [1 2
3 4]
Output: 4

Optimal Substructure:
The problem is a variation of Min-Cost problem. The path to reach (0, 0) from (n-1, n-1)
must be through the three cells (i, j-1) or (i-1, j) or (i-1, j-1). A top-down recursive function
will be called, for every value of m and n, check if (m+n) is a power of 2 or not. If it is a
power of 2, then move to cell(m-1, n-1) and add the value at a[m][n]. Hence the cost will
be:

2746
Chapter 382. Sudo Placement[1.5] | Wolfish

cost = a[m][n] + maxCost(a, m – 1, n – 1)

If it is not a power of 2, then we can move to two of cells (m-1, n) and (m, n-1). So the cost
will be:

cost = a[m][n] + max(maxCost(a, m – 1, n), maxCost(a, m, n – 1))

Below is the recursive implementation of the above approach:

// C++ program for


// SP - Wolfish
#include <bits/stdc++.h>
using namespace std;
  
const int size = 1000;
  
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0) | recursive approach
int maxCost(int a[][size], int m, int n)
{
    // base condition
    if (n < 0 || m < 0)
        return -1e9;
  
    // reaches the point
    else if (m == 0 && n == 0)
        return 0;
  
    else {
  
        // i + j
        int num = m + n;
  
        // check if it is a power of 2,
        // then only move diagonally
        if ((num & (num - 1)) == 0)
            return a[m][n] + maxCost(a, m - 1, n - 1);
  
        // if not a power of 2
        // then move side-wise
        else
            return a[m][n] + max(maxCost(a, m - 1, n),
                                 maxCost(a, m, n - 1));
    }
}
  
// Function to return the maximum cost

2747
Chapter 382. Sudo Placement[1.5] | Wolfish

int answer(int a[][size], int n)


{
    // calling dp function to get the answer
    return maxCost(a, n - 1, n - 1);
}
  
// Driver Code
int main()
{
    int a[][size] = { { 1, 2, 3, 1 },
                      { 4, 5, 6, 1 },
                      { 7, 8, 9, 1 },
                      { 1, 1, 1, 1 } };
    int n = 4;
  
    // Function calling to get the answer
    cout << answer(a, n);
    return 0;
}

Time Complexity: O(2N )


Approach using Memoization
In the above recursion, many sub-problems are being repeatedly called. To reduce the
number of repetative calls, memoization has been used. The common point of observation
is that only two parameters value are changing at every function call. So if we memoize the
returned value in a dp[][] array, the number of calls will be reduced to N^2. Hence store the
computed value of every maxCost(m, n) in dp[m][n]. If the maxCost(m, n) is called more
than once, then the extra calls of the fucntion will be reduced by returning the value stored
at dp[m][n].
Below is the efficient implementation of the above approach:

// C++ program for SP - Wolfish


#include <bits/stdc++.h>
using namespace std;
  
const int size = 1000;
  
// Function to find the maxCost of path from
// (n-1, n-1) to (0, 0)
int maxCost(int a[][size], int m, int n, int dp[][size])
{
    // base condition
    if (n < 0 || m < 0)
        return -1e9;
  
    // reaches the point

2748
Chapter 382. Sudo Placement[1.5] | Wolfish

    else if (m == 0 && n == 0)
        return 0;
  
    // if the state has been visited previously
    else if (dp[m][n] != -1)
        return dp[m][n];
    else {
  
        // i + j
        int num = m + n;
  
        // check if it is a power of 2,
        // then only move diagonally
        if ((num & (num - 1)) == 0)
            return dp[m][n] = a[m][n] + maxCost(a, m - 1, n - 1, dp);
  
        // if not a power of 2
        // then move side-wise
        else
            return dp[m][n] = (a[m][n] + max(maxCost(a, m - 1, n, dp),
                                             maxCost(a, m, n - 1, dp)));
    }
}
  
// Function to return the maximum cost
int answer(int a[][size], int n)
{
    int dp[size][size];
    memset(dp, -1, sizeof dp);
  
    // calling dp function to get the answer
    return maxCost(a, n - 1, n - 1, dp);
}
  
// Driver Code
int main()
{
    int a[][size] = { { 1, 2, 3, 1 },
                      { 4, 5, 6, 1 },
                      { 7, 8, 9, 1 },
                      { 1, 1, 1, 1 } };
    int n = 4;
  
    // Function calling to get the answer
    cout << answer(a, n);
    return 0;
}

2749
Chapter 382. Sudo Placement[1.5] | Wolfish

Time Complexity: O(N2 )


Auxiliary Space: O(N2 )
Note: To implement a bottom-up approach, we need to check if ((m+1) + (n+1)) is a
power of 2 or not instead of (m+n) as the moves are in top-down order.

Source

https://www.geeksforgeeks.org/sudo-placement1-5-wolfish/

2750
Chapter 383

Sum of all substrings of a string


representing a number | Set 1

Sum of all substrings of a string representing a number | Set 1 - GeeksforGeeks


Given a integer represented as a string, we need to get the sum of all possible substrings of
this string.
Examples:

Input : num = “1234”


Output : 1670
Sum = 1 + 2 + 3 + 4 + 12 + 23 +
34 + 123 + 234 + 1234
= 1670

Input : num = “421”


Output : 491
Sum = 4 + 2 + 1 + 42 + 21 + 421 = 491

We can solve this problem using dynamic programming. We can write summation of all
substrings on basis of digit at which they are ending in that case,
Sum of all substrings = sumofdigit[0] + sumofdigit[1] + sumofdigit[2] … + sumofdigit[n-1]
where n is length of string.
Where sumofdigit[i] stores sum of all substring ending at ith index digit, in above example,

Example : num = "1234"


sumofdigit[0] = 1 = 1
sumofdigit[1] = 2 + 12 = 14
sumofdigit[2] = 3 + 23 + 123 = 149

2751
Chapter 383. Sum of all substrings of a string representing a number | Set 1

sumofdigit[3] = 4 + 34 + 234 + 1234 = 1506


Result = 1670

Now we can get the relation between sumofdigit values and can solve the question iteratively.
Each sumofdigit can be represented in terms of previous value as shown below,

For above example,


sumofdigit[3] = 4 + 34 + 234 + 1234
= 4 + 30 + 4 + 230 + 4 + 1230 + 4
= 4*4 + 10*(3 + 23 +123)
= 4*4 + 10*(sumofdigit[2])
In general,
sumofdigit[i] = (i+1)*num[i] + 10*sumofdigit[i-1]

Using above relation we can solve the problem in linear time. In below code a complete
array is taken to store sumofdigit, as each sumofdigit value requires just previous value, we
can solve this problem without allocating complete array also.

C++

//  C++ program to print sum of all substring of


// a number represented as a string
#include <bits/stdc++.h>
using namespace std;
  
// Utility method to covert character digit to
// integer digit
int toDigit(char ch)
{
    return (ch - '0');
}
  
// Returns sum of all substring of num
int sumOfSubstrings(string num)
{
    int n = num.length();
  
    //  allocate memory equal to length of string
    int sumofdigit[n];
  
    //  initialize first value with first digit
    sumofdigit[0] = toDigit(num[0]);
    int res = sumofdigit[0];
  
    //  loop over all digits of string
    for (int i=1; i<n; i++)

2752
Chapter 383. Sum of all substrings of a string representing a number | Set 1

    {
        int numi = toDigit(num[i]);
  
        // update each sumofdigit from previous value
        sumofdigit[i] = (i+1) * numi +
                        10 * sumofdigit[i-1];
  
        // add current value to the result
        res += sumofdigit[i];
    }
  
    return res;
}
  
//  Driver code to test above methods
int main()
{
    string num = "1234";
    cout << sumOfSubstrings(num) << endl;
    return 0;
}

Java

// Java program to print sum of all substring of


// a number represented as a string
import java.util.Arrays;
  
class GFG{
  
    // Returns sum of all substring of num
    public static int sumOfSubstrings(String num)
    {
        int n = num.length();
          
        //  allocate memory equal to length of string
        int sumofdigit[] = new int[n];
       
        //  initialize first value with first digit
        sumofdigit[0] = num.charAt(0)-'0';
        int res = sumofdigit[0];
       
        //  loop over all digits of string
        for (int i = 1; i < n; i++)
        {
            int numi = num.charAt(i)-'0';
       
            // update each sumofdigit from previous value

2753
Chapter 383. Sum of all substrings of a string representing a number | Set 1

            sumofdigit[i] = (i+1) * numi +


                            10 * sumofdigit[i-1];
       
            // add current value to the result
            res += sumofdigit[i];
        }
       
        return res;
    }
       
    //  Driver code to test above methods
     public static void main(String[] args) 
    {
        String num = "1234";
          
        System.out.println(sumOfSubstrings(num));
          
    }
}
// This code is contributed by Arnav Kr. Mandal.

Python3

# Python program to print 


# sum of all substring of
# a number represented as 
# a string
  
# Returns sum of all 
# substring of num
def sumOfSubstrings(num):
    n = len(num)
  
    # allocate memory equal 
    # to length of string
    sumofdigit = []
  
    # initialize first value
    # with first digit
    sumofdigit.append(int(num[0]))
    res = sumofdigit[0]
  
    # loop over all
    # digits of string
    for i in range(1, n):
        numi = int(num[i])
  
        # update each sumofdigit

2754
Chapter 383. Sum of all substrings of a string representing a number | Set 1

        # from previous value


        sumofdigit.append((i + 1) * 
                        numi + 10 * 
                        sumofdigit[i - 1])
  
        # add current value
        # to the result
        res += sumofdigit[i]
  
    return res
  
# Driver code 
num = "1234"
print(sumOfSubstrings(num))
  
# This code is contributed 
# by Sanjit_Prasad

C#

// C# program to print sum of 


// all substring of a number
// represented as a string
using System;
  
class GFG{
  
    // Returns sum of all 
    // substring of num
    public static int sumOfSubstrings(String num)
    {
        int n = num.Length;
          
        // allocate memory equal to 
        // length of string
        int []sumofdigit = new int[n];
      
        // initialize first value 
        // with first digit
        sumofdigit[0] = num[0] - '0';
        int res = sumofdigit[0];
      
        // loop over all digits
        // of string
        for (int i = 1; i < n; i++)
        {
            int numi = num[i] - '0';
      

2755
Chapter 383. Sum of all substrings of a string representing a number | Set 1

            // update each sumofdigit


            // from previous value
            sumofdigit[i] = (i + 1) * numi + 10 
                             * sumofdigit[i - 1];
      
            // add current value
            // to the result
            res += sumofdigit[i];
        }
      
        return res;
    }
      
    // Driver code 
    public static void Main() 
    {
        String num = "1234";
          
        Console.Write(sumOfSubstrings(num));
          
    }
}
  
// This code is contributed by Nitin Mittal.

PHP

<?php
// PHP program to print sum of all
// substring of a number represented 
// as a string
  
// Method to covert character
// digit to integer digit
function toDigit($ch)
{
    return ($ch - '0');
}
  
// Returns sum of all
// substring of num
function sumOfSubstrings($num)
{
    $n = strlen($num);
  
    // allocate memory equal to
    // length of string
    $sumofdigit[$n] = 0;

2756
Chapter 383. Sum of all substrings of a string representing a number | Set 1

  
    // initialize first value
    // with first digit
    $sumofdigit[0] = toDigit($num[0]);
    $res = $sumofdigit[0];
  
    // loop over all digits of string
    for($i = 1; $i < $n; $i++)
    {
        $numi = toDigit($num[$i]);
  
        // update each sumofdigit 
        // from previous value
        $sumofdigit[$i] = ($i + 1) * $numi + 10 * 
                              $sumofdigit[$i - 1];
  
        // add current value to the result
        $res += $sumofdigit[$i];
    }
  
    return $res;
}
  
    // Driver Code
    $num = "1234";
    echo sumOfSubstrings($num) ;
      
// This code is contributed by nitin mittal.
?>

Output:

1670

Time Complexity : O(n) where n is length of input string.


Auxiliary Space : O(n)
Sum of all substrings of a string representing a number | Set 2 (Constant Extra Space)
Improved By : nitin mittal, Sanjit_Prasad

Source

https://www.geeksforgeeks.org/sum-of-all-substrings-of-a-string-representing-a-number/

2757
Chapter 384

Sum of all substrings of a string


representing a number | Set 2
(Constant Extra Space)

Sum of all substrings of a string representing a number | Set 2 (Constant Extra Space) -
GeeksforGeeks
Given a string representing a number, we need to get the sum of all possible sub strings of
this string.
Examples :

Input : s = "6759"
Output : 8421
sum = 6 + 7 + 5 + 9 + 67 + 75 +
59 + 675 + 759 + 6759
= 8421

Input : s = "16"
Output : 23
sum = 1 + 6 + 16 = 23

We have discussed a solution in below post.


Sum of all substrings of a string representing a number | Set 1
The solution is based on different approach which does not uses any extra space.
This problem can be viewed as following.
Let number be s = “6759”

2758
Chapter 384. Sum of all substrings of a string representing a number | Set 2 (Constant
Extra Space)

1 10 100 1000
6 1 1 1 1
7 2 2 2
5 3 3
9 4

The above table indicates that, when all the sub strings are converted further to the ones,
tens, hundreds etc.. form, each index of the string will have a some fixed occurrence. The
1st index will have 1 occurrence each of ones, tens etc..The 2nd will have 2, 3rd will have 3
and so on.
One more point is that the occurrence of last element will only be restricted to ones. Last
2nd element will be restricted to ones and tens. Last 3rd will be up to hundred and so on.
From the above points lets find out the sum.

sum = 6*(1*1 + 1*10 + 1*100 + 1*1000) + 7*(2*1 + 2*10 + 2*100) +


5*(3*1 + 3*10) + 9*(4*1)
= 6*1*(1111) + 7*2*(111) + 5*3*(11) + 9*4*(1)
= 6666 + 1554 + 165 + 36
= 8421

Now, to handle the multiplication we will be having a multiplying factor which starts from
1. It’s clear from the example that the multiplying factor(in reverse) is 1, 11, 111, … and so
on. So the multiplication will be based on three factors. number, its index and multiplying
factor.

C++

// C++ program to print sum of all substring of


// a number represented as a string
#include <bits/stdc++.h>
using namespace std;
  
// Returns sum of all substring of num
int sumOfSubstrings(string num)
{
    long long int sum = 0; // Initialize result
  
    // Here traversing the array in reverse
    // order.Initializing loop from last
    // element.
    // mf is multiplying factor.
    long long int mf = 1;
    for (int i=num.size()-1; i>=0; i--)
    {
        // Each time sum is added to its previous

2759
Chapter 384. Sum of all substrings of a string representing a number | Set 2 (Constant
Extra Space)

        // sum. Multiplying the three factors as


        // explained above.
        // s[i]-'0' is done to convert char to int.
        sum += (num[i]-'0')*(i+1)*mf;
  
        // Making new multiplying factor as
        // explained above.
        mf = mf*10 + 1;
    }
  
    return sum;
}
  
//  Driver code to test above methods
int main()
{
    string num = "6759";
    cout << sumOfSubstrings(num) << endl;
    return 0;
}

Java

// Java program to print sum of all substring of


// a number represented as a string
import java.util.Arrays;
  
public class GFG {
      
    // Returns sum of all substring of num
    public static long sumOfSubstrings(String num)
    {
        long sum = 0; // Initialize result
       
        // Here traversing the array in reverse
        // order.Initializing loop from last
        // element.
        // mf is multiplying factor.
        long mf = 1;
        for (int i = num.length() - 1; i >= 0; i --)
        {
            // Each time sum is added to its previous
            // sum. Multiplying the three factors as
            // explained above.
            // s[i]-'0' is done to convert char to int.
            sum += (num.charAt(i) - '0') * (i + 1) * mf;
       
            // Making new multiplying factor as

2760
Chapter 384. Sum of all substrings of a string representing a number | Set 2 (Constant
Extra Space)

            // explained above.


            mf = mf * 10 + 1;
        }
       
        return sum;
    }
      
           
    //  Driver code to test above methods
    public static void main(String[] args) 
    {
        String num = "6759";
              
        System.out.println(sumOfSubstrings(num));
              
    }
}
  
// This code is contributed by Arnav Kr. Mandal.

C#

// C# program to print sum of all substring of


// a number represented as a string
using System;
          
public class GFG {
      
    // Returns sum of all substring of num
    public static long sumOfSubstrings(string num)
    {
          
        long sum = 0; // Initialize result
      
        // Here traversing the array in reverse
        // order.Initializing loop from last
        // element.
        // mf is multiplying factor.
        long mf = 1;
          
        for (int i = num.Length - 1; i >= 0; i --)
        {
              
            // Each time sum is added to its previous
            // sum. Multiplying the three factors as
            // explained above.
            // s[i]-'0' is done to convert char to int.
            sum += (num[i] - '0') * (i + 1) * mf;

2761
Chapter 384. Sum of all substrings of a string representing a number | Set 2 (Constant
Extra Space)

      
            // Making new multiplying factor as
            // explained above.
            mf = mf * 10 + 1;
        }
      
        return sum;
    }
      
          
    // Driver code to test above methods
    public static void Main() 
    {
        string num = "6759";
              
        Console.WriteLine(sumOfSubstrings(num));
              
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP program to print sum of
// all substring of  a number 
// represented as a string
  
// Returns sum of all 
// substring of num
function sumOfSubstrings($num)
{
    // Initialize result
    $sum = 0; 
  
    // Here traversing the array 
    // in reverse order.Initializing 
    // loop from last element.
    // mf is multiplying factor.
    $mf = 1;
    for ($i = strlen($num) - 1; $i >= 0; $i--)
    {
        // Each time sum is added to 
        // its previous sum. Multiplying 
        // the three factors as explained above.
        // s[i]-'0' is done to convert char to int.
        $sum += ($num[$i] - '0') * ($i + 1) * $mf;

2762
Chapter 384. Sum of all substrings of a string representing a number | Set 2 (Constant
Extra Space)

  
        // Making new multiplying 
        // factor as explained above.
        $mf = $mf * 10 + 1;
    }
  
    return $sum;
}
  
// Driver Code
$num = "6759";
echo sumOfSubstrings($num), "\n";
  
// This code is contributed by m_kit
?>

Output :

8421

Improved By : Sam007, jit_t

Source

https://www.geeksforgeeks.org/sum-substrings-string-representing-number-set-2-constant-extra-space/

2763
Chapter 385

Sum of average of all subsets

Sum of average of all subsets - GeeksforGeeks


Given an array arr of N integer elements, the task is to find sum of average of all subsets of
this array.
Example :

Input : arr[] = [2, 3, 5]


Output : 23.33
Explanation : Subsets with their average are,
[2] average = 2/1 = 2
[3] average = 3/1 = 3
[5] average = 5/1 = 5
[2, 3] average = (2+3)/2 = 2.5
[2, 5] average = (2+5)/2 = 3.5
[3, 5] average = (3+5)/2 = 4
[2, 3, 5] average = (2+3+5)/3 = 3.33

Sum of average of all subset is,


2 + 3 + 5 + 2.5 + 3.5 + 4 + 3.33 = 23.33

A naive solution is to iterate through all possible subsets, get average of all of them and
then add them one by one, but this will take exponential time and will be infeasible for
bigger arrays.
We can get a pattern by taking an example,

arr = [a0, a1, a2, a3]


sum of average =
a0/1 + a1/1 + a2/2 + a3/1 +
(a0+a1)/2 + (a0+a2)/2 + (a0+a3)/2 + (a1+a2)/2 +

2764
Chapter 385. Sum of average of all subsets

(a1+a3)/2 + (a2+a3)/2 +
(a0+a1+a2)/3 + (a0+a2+a3)/3 + (a0+a1+a3)/3 +
(a1+a2+a3)/3 +
(a0+a1+a2+a3)/4

If S = (a0+a1+a2+a3), then above expression


can be rearranged as below,
sum of average = (S)/1 + (3*S)/2 + (3*S)/3 + (S)/4

The coefficient with numerators can be explained as follows, suppose we are iterating over
subsets with K elements then denominator will be K and numerator will be r*S, where
‘r’ denotes number of times a particular array element will be added while iterating over
subsets of same size. By inspection we can see that r will be nCr(N – 1, n – 1) because
after placing one element in summation, we need to choose (n – 1) elements from (N –
1) elements so each element will have a frequency of nCr(N – 1, n – 1) while considering
subsets of same size, as all elements are taking part in summation equal number of times,
this will the frequency of S also and will be the numerator in final expression.
In below code nCr is implemented using dynamic programming method, you can read more
about that here,

C++

// C++ program to get sum of average of all subsets


#include <bits/stdc++.h>
using namespace std;
  
// Returns value of Binomial Coefficient C(n, k)
int nCr(int n, int k)
{
    int C[n + 1][k + 1];
    int i, j;
  
    // Calculate value of Binomial Coefficient in bottom
    // up manner
    for (i = 0; i <= n; i++) {
        for (j = 0; j <= min(i, k); j++) {
            // Base Cases
            if (j == 0 || j == i)
                C[i][j] = 1;
  
            // Calculate value using previously stored
            // values
            else
                C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
        }
    }
    return C[n][k];

2765
Chapter 385. Sum of average of all subsets

}
  
// method returns sum of average of all subsets
double resultOfAllSubsets(int arr[], int N)
{
    double result = 0.0; // Initialize result
  
    // Find sum of elements
    int sum = 0;
    for (int i = 0; i < N; i++)
        sum += arr[i];
  
    // looping once for all subset of same size
    for (int n = 1; n <= N; n++)
  
        /* each element occurs nCr(N-1, n-1) times while
           considering subset of size n  */
        result += (double)(sum * (nCr(N - 1, n - 1))) / n;
  
    return result;
}
  
// Driver code to test above methods
int main()
{
    int arr[] = { 2, 3, 5, 7 };
    int N = sizeof(arr) / sizeof(int);
    cout << resultOfAllSubsets(arr, N) << endl;
    return 0;
}

Java

// java program to get sum of


// average of all subsets
import java.io.*;
  
class GFG {
  
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int nCr(int n, int k)
    {
        int C[][] = new int[n + 1][k + 1];
        int i, j;
  
        // Calculate value of Binomial
        // Coefficient in bottom up manner

2766
Chapter 385. Sum of average of all subsets

        for (i = 0; i <= n; i++) {


            for (j = 0; j <= Math.min(i, k); j++) {
                // Base Cases
                if (j == 0 || j == i)
                    C[i][j] = 1;
  
                // Calculate value using
                // previously stored values
                else
                    C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
            }
        }
        return C[n][k];
    }
  
    // method returns sum of average of all subsets
    static double resultOfAllSubsets(int arr[], int N)
    {
        // Initialize result
        double result = 0.0;
  
        // Find sum of elements
        int sum = 0;
        for (int i = 0; i < N; i++)
            sum += arr[i];
  
        // looping once for all subset of same size
        for (int n = 1; n <= N; n++)
  
            /* each element occurs nCr(N-1, n-1) times while
            considering subset of size n */
            result += (double)(sum * (nCr(N - 1, n - 1))) / n;
  
        return result;
    }
  
    // Driver code to test above methods
    public static void main(String[] args)
    {
        int arr[] = { 2, 3, 5, 7 };
        int N = arr.length;
        System.out.println(resultOfAllSubsets(arr, N));
    }
}
  
// This code is contributed by vt_m

Python3

2767
Chapter 385. Sum of average of all subsets

# Python3 program to get sum


# of average of all subsets
  
# Returns value of Binomial
# Coefficient C(n, k)
def nCr(n, k):
  
    C = [[0 for i in range(k + 1)]
            for j in range(n + 1)]
  
    # Calculate value of Binomial 
    # Coefficient in bottom up manner
    for i in range(n + 1):
      
        for j in range(min(i, k) + 1):
          
            # Base Cases
            if (j == 0 or j == i):
                C[i][j] = 1
  
            # Calculate value using 
            # previously stored values
            else:
                C[i][j] = C[i-1][j-1] + C[i-1][j]
      
    return C[n][k]
  
# Method returns sum of
# average of all subsets
def resultOfAllSubsets(arr, N):
  
    result = 0.0 # Initialize result
  
    # Find sum of elements
    sum = 0
    for i in range(N):
        sum += arr[i]
  
    # looping once for all subset of same size
    for n in range(1, N + 1):
  
        # each element occurs nCr(N-1, n-1) times while
        # considering subset of size n */
        result += (sum * (nCr(N - 1, n - 1))) / n
  
    return result
  
# Driver code 

2768
Chapter 385. Sum of average of all subsets

arr = [2, 3, 5, 7]
N = len(arr)
print(resultOfAllSubsets(arr, N))
  
  
# This code is contributed by Anant Agarwal.

C#

// C# program to get sum of


// average of all subsets
using System;
  
class GFG {
      
    // Returns value of Binomial
    // Coefficient C(n, k)
    static int nCr(int n, int k)
    {
        int[, ] C = new int[n + 1, k + 1];
        int i, j;
  
        // Calculate value of Binomial
        // Coefficient in bottom up manner
        for (i = 0; i <= n; i++) {
            for (j = 0; j <= Math.Min(i, k); j++) 
            {
                // Base Cases
                if (j == 0 || j == i)
                    C[i, j] = 1;
  
                // Calculate value using
                // previously stored values
                else
                    C[i, j] = C[i - 1, j - 1] + C[i - 1, j];
            }
        }
        return C[n, k];
    }
  
    // method returns sum of average 
    // of all subsets
    static double resultOfAllSubsets(int[] arr, int N)
    {
        // Initialize result
        double result = 0.0;
  
        // Find sum of elements

2769
Chapter 385. Sum of average of all subsets

        int sum = 0;
        for (int i = 0; i < N; i++)
            sum += arr[i];
  
        // looping once for all subset 
        // of same size
        for (int n = 1; n <= N; n++)
  
            /* each element occurs nCr(N-1, n-1) times while
               considering subset of size n */
            result += (double)(sum * (nCr(N - 1, n - 1))) / n;
  
        return result;
    }
  
    // Driver code to test above methods
    public static void Main()
    {
        int[] arr = { 2, 3, 5, 7 };
        int N = arr.Length;
        Console.WriteLine(resultOfAllSubsets(arr, N));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program to get sum 
// of average of all subsets
  
// Returns value of Binomial
// Coefficient C(n, k)
function nCr($n, $k)
{
    $C[$n + 1][$k + 1] = 0;
    $i; $j;
  
    // Calculate value of Binomial
    // Coefficient in bottom up manner
    for ($i = 0; $i <= $n; $i++) 
    {
        for ($j = 0; $j <= min($i, $k); $j++)
        {
            // Base Cases
            if ($j == 0 || $j == $i)
                $C[$i][$j] = 1;

2770
Chapter 385. Sum of average of all subsets

  
            // Calculate value using 
            // previously stored values
            else
                $C[$i][$j] = $C[$i - 1][$j - 1] + 
                             $C[$i - 1][$j];
        }
    }
    return $C[$n][$k];
}
  
// method returns sum of
// average of all subsets
function resultOfAllSubsets($arr, $N)
{
    // Initialize result
    $result = 0.0; 
  
    // Find sum of elements
    $sum = 0;
    for ($i = 0; $i < $N; $i++)
        $sum += $arr[$i];
  
    // looping once for all 
    // subset of same size
    for ($n = 1; $n <= $N; $n++)
  
        /* each element occurs nCr(N-1, 
        n-1) times while considering 
        subset of size n */
        $result += (($sum * (nCr($N - 1, 
                                 $n - 1))) / $n);
  
    return $result;
}
  
// Driver Code
$arr = array( 2, 3, 5, 7 );
$N = sizeof($arr) / sizeof($arr[0]);
echo resultOfAllSubsets($arr, $N) ;
  
// This code is contributed by nitin mittal. 
?>

Output :

63.75

2771
Chapter 385. Sum of average of all subsets

Improved By : Sam007, nitin mittal

Source

https://www.geeksforgeeks.org/sum-average-subsets/

2772
Chapter 386

Sum of elements of all partitions


of number such that no element
is less than K

Sum of elements of all partitions of number such that no element is less than K - Geeks-
forGeeks
Given an integer N, the task is to find an aggregate sum of all integer partitions of this
number such that each partition does not contain any integer less than K.
Examples:

Input: N = 6 and K = 2
Output: 24
In this case, there are 4 valid partitions.
1) {6}
2) {4, 2}
3) {3, 3}
4) {2, 2, 2}
Therefore, aggregate sum would be
6 + 4 + 2 + 3 + 3 + 2 + 2 + 2 = 24
Input: N = 10 and K = 3
Output: 50
Here, 5 valid partitions are:
1) {10}
2) {7, 3}
3) {6, 4}
4) {5, 5}
5) {3, 3, 4}
Aggregate sum in this case would be
10 + 7 + 3 + 6 + 4 + 5 + 5 + 3 + 3 + 4 = 50

2773
Chapter 386. Sum of elements of all partitions of number such that no element is less
than K

Approach: This problem has a simple recursive solution. First, we need to count the
total number of valid partitions of number N such that each partition contains integers
greater than or equal to K. So we will iteratively apply our recursive solution to find valid
partitions that have the minimum integer K, K+1, K+2, …, N.
Our final answer would be N * no of valid partitions because each valid partition has a
sum equal to N.
Following are some key ideas for designing recursive function to find total number of valid
partitions.

• If N < K then no partition is possible.


• If N < 2*K then only one partition is possible and that is the number N itself.
• We can find number partitions in a recursive manner that contains integers at least
equal to ‘i’ (‘i’ can be from K to N) and add them all to get final answer.

Pseudo code for recursive function to find number of valid partitions:

f(N,K):
if N < K
return 0
if N < 2K
return 1
Initialize answer = 1
FOR i from K to N
answer = answer + f(N-i,i)
return answer

Below is the Dynamic Programming solution:

C++

// C++ implementation of above approach


#include <bits/stdc++.h>
using namespace std;
  
// Function that returns total number of valid
// partitions of integer N
long long int countPartitions(int n, int k)
{
  
      
    // Global declaration of 2D dp array
    // which will be later used for memoization
    long long int dp[201][201];
  
    // initializing 2D dp array with -1

2774
Chapter 386. Sum of elements of all partitions of number such that no element is less
than K

    // we will use this 2D array for memoization


    for (int i = 0; i < n + 1; i++) {
        for (int j = 0; j < n + 1; j++) {
            dp[i][j] = -1;
        }
    }
  
    // if this subproblem is already previously
    // calculated, then directly return that answer
    if (dp[n][k] >= 0)
        return dp[n][k];
  
    // if N < K, then no valid 
    // partition is possible
    if (n < k)
        return 0;
  
    // if N is between K to 2*K then
    // there is only one
    // partition and that is the number N itself
    if (n < 2 * k)
        return 1;
  
    // Initialize answer with 1 as 
    // the number N itself
    // is always a valid partition
    long long int answer = 1;
  
    // for loop to iterate over K to N
    // and find number of
    // possible valid partitions recursively.
    for (int i = k; i < n; i++)
        answer = answer + countPartitions(n - i, i);
  
    // memoization is done by storing
    // this calculated answer
    dp[n][k] = answer;
  
    // returning number of valid partitions
    return answer;
}
  
// Driver code
int main()
{
    int n = 10, k = 3;
  
    // Printing total number of valid partitions

2775
Chapter 386. Sum of elements of all partitions of number such that no element is less
than K

    cout << "Total Aggregate sum of all Valid Partitions: "


         << countPartitions(n, k) * n;
  
    return 0;
}

Java

// Java implementation of
// above approach
class GFG
{
// Function that returns
// total number of valid
// partitions of integer N
static long countPartitions(int n, int k)
{
  
    // Global declaration of 2D
    // dp array which will be 
    // later used for memoization
    long[][] dp = new long[201][201];
  
    // initializing 2D dp array 
    // with -1 we will use this 
    // 2D array for memoization
    for (int i = 0; i < n + 1; i++)
    {
        for (int j = 0; j < n + 1; j++)
        {
            dp[i][j] = -1;
        }
    }
  
    // if this subproblem is already 
    // previously calculated, then 
    // directly return that answer
    if (dp[n][k] >= 0)
        return dp[n][k];
  
    // if N < K, then no valid 
    // partition is possible
    if (n < k)
        return 0;
  
    // if N is between K to 2*K 
    // then there is only one
    // partition and that is 

2776
Chapter 386. Sum of elements of all partitions of number such that no element is less
than K

    // the number N itself


    if (n < 2 * k)
        return 1;
  
    // Initialize answer with 1
    // as the number N itself
    // is always a valid partition
    long answer = 1;
  
    // for loop to iterate over 
    // K to N and find number of
    // possible valid partitions
    // recursively.
    for (int i = k; i < n; i++)
        answer = answer + 
                 countPartitions(n - i, i);
  
    // memoization is done by storing
    // this calculated answer
    dp[n][k] = answer;
  
    // returning number of
    // valid partitions
    return answer;
}
  
// Driver code
public static void main(String[] args)
{
    int n = 10, k = 3;
  
    // Printing total number
    // of valid partitions
    System.out.println("Total Aggregate sum of " + 
                       "all Valid Partitions: " + 
                       countPartitions(n, k) * n);
}
}
  
// This code is contributed by mits

Output:

Total Aggregate sum of all Valid Partitions: 50

Time Complexity: O(N2 )


Improved By : Mithun Kumar

2777
Chapter 386. Sum of elements of all partitions of number such that no element is less
than K

Source

https://www.geeksforgeeks.org/sum-of-elements-of-all-partitions-of-number-such-that-no-element-is-less-than-k/

2778
Chapter 387

Sum of product of consecutive


Binomial Coefficients

Sum of product of consecutive Binomial Coefficients - GeeksforGeeks


Given a positive ineteger n. The task is to find the sum of product of consecutive binomial
coefficient i.e
n
C0 *n C1 + n C1 *n C2 + ….. + n Cn-1 *n Cn

Examples:

Input : n = 3
Output : 15
3C0*3C1 + 3C1*3C2 +3C2*3C3
= 1*3 + 3*3 + 3*1
= 3 + 9 + 3
= 15

Input : n = 4
Output : 56

Method 1: The idea is to find all the binomial coefficients up to nth term and find the
sum of the product of consecutive coefficients.
Below is the implementation of this approach:

C++

// CPP Program to find sum of product of


// consecutive Binomial Coefficient.
#include <bits/stdc++.h>

2779
Chapter 387. Sum of product of consecutive Binomial Coefficients

using namespace std;


#define MAX 100
  
// Find the binomial coefficient upto nth term
void binomialCoeff(int C[], int n)
{
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++) {
  
        // Compute next row of pascal triangle using
        // the previous row
        for (int j = min(i, n); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
}
  
// Return the sum of the product of
// consecutive binomial coefficient.
int sumOfproduct(int n)
{
    int sum = 0;
    int C[MAX] = { 0 };
  
    binomialCoeff(C, n);
  
    // finding the sum of product of 
    // consecutive coefficient.
    for (int i = 0; i <= n; i++) 
        sum += C[i] * C[i + 1];    
  
    return sum;
}
  
// Driven Program
int main()
{
    int n = 3;
    cout << sumOfproduct(n) << endl;
    return 0;
}

PHP

<?php
// PHP Program to find sum 
// of product of consecutive
// Binomial Coefficient.

2780
Chapter 387. Sum of product of consecutive Binomial Coefficients

$MAX = 100;
  
// Find the binomial
// coefficient upto 
// nth term
function binomialCoeff($C, $n)
{
    $C[0] = 1; // nC0 is 1
  
    for ($i = 1; 
         $i <= $n; $i++)
    {
  
        // Compute next row of
        // pascal triangle using
        // the previous row
        for ($j = min($i, $n); 
             $j > 0; $j--)
            $C[$j] = $C[$j] +
                     $C[$j - 1];
    }
    return $C;
}
  
// Return the sum of the 
// product of consecutive 
// binomial coefficient.
function sumOfproduct($n)
{
    global $MAX;
    $sum = 0;
    $C = array_fill(0, $MAX, 0);
  
    $C = binomialCoeff($C, $n);
  
    // finding the sum of 
    // product of consecutive
    // coefficient.
    for ($i = 0; $i <= $n; $i++) 
        $sum += $C[$i] * $C[$i + 1]; 
  
    return $sum;
}
  
// Driver Code
$n = 3;
echo sumOfproduct($n);
  

2781
Chapter 387. Sum of product of consecutive Binomial Coefficients

// This code is contributed by mits


?>

Output

15

Method 2:
We know,
(1 + x)n = n C0 + n C1 *x + n C2 *x2 + …. + n Cn *xn … (1)
(1 + 1/x)n = n C0 + n C1 /x + n C2 /x2 + …. + n Cn /xn … (2)
Multiplying (1) and (2), we get
(1 + x)2n /xn = (n C0 + n C1 *x + n C2 *x2 + …. + n Cn *xn ) * (n C0 + n C1 /x + n C2 /x2 + ….
+ n Cn /xn )
(2n C0 + 2n C1 *x + 2n C2 *x2 + …. + 2n Cn *xn )/xn = (n C0 + n C1 *x + n C2 *x2 + …. + n Cn *xn )
* (n C0 + n C1 /x + n C2 /x2 + …. + n Cn /xn )
Now, find the coefficient of x in LHS,
Observe rth term of expansion in numerator is 2n Cr xr .
To find the coefficient of x in (1 + x)2n /xn , r should be n + 1, because power of x in
denominator will reduce it.
So, coefficient of x in LHS = 2n Cn + 1 or 2n Cn – 1
Now, find the coefficient of x in RHS,
r th term of first expansion of multiplication is n Cr * xr
t th term of second expansion of multiplication is n Ct / xt
So term after multiply will be n Cr * xr * n Ct / xt or
n
Cr * n Ct * x r / x t
Put r = t + 1, we get,
n
Ct+1 * n Ct * x
Observe there will be n such term in the expansion of multiply, so t range from 0 to n – 1.
Therefor, coefficient of x in RHS = n C0 *n C1 + n C1 *n C2 + ….. + n Cn-1 *n Cn
Comparing coefficient of x in LHS and RHS, we can say,
n
C0 *n C1 + n C1 *n C2 + ….. + n Cn-1 *n Cn = 2n Cn – 1
Below is implementation of this approach:

C++

// CPP Program to find sum of product of 


// consecutive Binomial Coefficient.
#include <bits/stdc++.h>
using namespace std;
#define MAX 100
  
// Find the binomial coefficient up to nth 

2782
Chapter 387. Sum of product of consecutive Binomial Coefficients

// term
int binomialCoeff(int n, int k)
{
    int C[k + 1];
    memset(C, 0, sizeof(C));
  
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++) {
  
        // Compute next row of pascal triangle 
        // using the previous row
        for (int j = min(i, k); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
    return C[k];
}
  
// Return the sum of the product of
// consecutive binomial coefficient.
int sumOfproduct(int n)
{
    return binomialCoeff(2 * n, n - 1);
}
  
// Driven Program
int main()
{
    int n = 3;
  
    cout << sumOfproduct(n) << endl;
    return 0;
}

Java

// Java Program to find sum of 


// product of consecutive 
// Binomial Coefficient.
import java.io.*;
  
class GFG 
{
    static int MAX = 100;
      
    // Find the binomial coefficient 
    // up to nth term
    static int binomialCoeff(int n, 

2783
Chapter 387. Sum of product of consecutive Binomial Coefficients

                             int k)
    {
        int C[] = new int[k + 1];
          
        // memset(C, 0, sizeof(C));
        C[0] = 1; // nC0 is 1
  
        for (int i = 1; i <= n; i++) 
        {
  
            // Compute next row of 
            // pascal triangle 
            // using the previous row
            for (int j = Math.min(i, k); j > 0; j--)
                C[j] = C[j] + C[j - 1];
    }
      
    return C[k];
}
  
// Return the sum of the 
// product of consecutive
// binomial coefficient.
static int sumOfproduct(int n)
{
    return binomialCoeff(2 * n, 
                         n - 1);
}
  
// Driver Code
public static void main (String[] args) 
{
    int n = 3;
    System.out.println(sumOfproduct(n));
}
}
  
// This code is contributed
// by shiv_bhakt.

C#

// C# Program to find sum of 


// product of consecutive 
// Binomial Coefficient.
using System;
  
class GFG

2784
Chapter 387. Sum of product of consecutive Binomial Coefficients

{
      
    // Find the binomial 
    // coefficient up to 
    // nth term
    static int binomialCoeff(int n, 
                             int k)
    {
        int []C = new int[k + 1];
          
        // memset(C, 0, sizeof(C));
        C[0] = 1; // nC0 is 1
  
        for (int i = 1; i <= n; i++) 
        {
  
            // Compute next row of 
            // pascal triangle 
            // using the previous row
            for (int j = Math.Min(i, k); 
                             j > 0; j--)
                C[j] = C[j] + C[j - 1];
    }
      
    return C[k];
}
  
// Return the sum of the 
// product of consecutive
// binomial coefficient.
static int sumOfproduct(int n)
{
    return binomialCoeff(2 * n, 
                         n - 1);
}
  
// Driver Code
static public void Main ()
{
    int n = 3;
    Console.WriteLine(sumOfproduct(n));
}
}
  
// This code is contributed
// by @ajit.

Output:

2785
Chapter 387. Sum of product of consecutive Binomial Coefficients

15

Improved By : shiv_bhakt, jit_t, Mithun Kumar

Source

https://www.geeksforgeeks.org/sum-of-product-of-consecutive-binomial-coefficients/

2786
Chapter 388

Sum of product of r and rth


Binomial Coefficient (r * nCr)

Sum of product of r and rth Binomial Coefficient (r * nCr) - GeeksforGeeks


Given a positive integer n. The task is to find the sum of the product of r and rth Binomial
Coefficient. In other words find: Σ (r * n Cr ), where 0 <= r <= n.
Examples:

Input : n = 2
Output : 4
0.2C0 + 1.2C1 + 2.2C2
= 0*2 + 1*2 + 2*1
= 4

Input : n = 5
Output : 80

Method 1 (Brute Force) : The idea is to iterate a loop i from 0 to n and evaluate i *
n
Ci and add to sum variable.
Below is the implementation of this approach:

C++

// CPP Program to find sum of product of r and


// rth Binomial Coefficient i.e summation r * nCr
#include <bits/stdc++.h>
using namespace std;
#define MAX 100

2787
Chapter 388. Sum of product of r and rth Binomial Coefficient (r * nCr)

  
// Return the first n term of binomial coefficient.
void binomialCoeff(int n, int C[])
{
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++) {
  
        // Compute next row of pascal triangle 
        // using the previous row
        for (int j = min(i, n); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
}
  
// Return summation of r * nCr
int summation(int n)
{
    int C[MAX];
    memset(C, 0, sizeof(C));
  
    // finding the first n term of binomial
    // coefficient
    binomialCoeff(n, C);
  
    // Iterate a loop to find the sum.
    int sum = 0;
    for (int i = 0; i <= n; i++) 
        sum += (i * C[i]);    
  
    return sum;
}
  
// Driven Program
int main()
{
    int n = 2;
    cout << summation(n) << endl;
    return 0;
}

Java

// Java Program to find sum 


// of product of r and rth 
// Binomial Coefficient i.e
// summation r * nCr
class GFG

2788
Chapter 388. Sum of product of r and rth Binomial Coefficient (r * nCr)

{
static int MAX = 100;
  
// Return the first n term 
// of binomial coefficient.
static void binomialCoeff(int n, 
                          int C[])
{
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++)
    {
  
        // Compute next row of
        // pascal triangle using 
        // the previous row
        for (int j = Math.min(i, n); j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
}
  
// Return summation
// of r * nCr
static int summation(int n)
{
    int C[] = new int[MAX];
      
    for(int i = 0; i < MAX; i++)
    C[i] = 0;
  
    // finding the first n term  
    // of binomial coefficient
    binomialCoeff(n, C);
  
    // Iterate a loop 
    // to find the sum.
    int sum = 0;
    for (int i = 0; i <= n; i++) 
        sum += (i * C[i]); 
  
    return sum;
}
  
// Driver Code
public static void main(String args[])
{
    int n = 2;
    System.out.println( summation(n));

2789
Chapter 388. Sum of product of r and rth Binomial Coefficient (r * nCr)

}
}
  
// This code is contributed by Arnab Kundu

C#

// C# Program to find sum 


// of product of r and rth 
// Binomial Coefficient i.e
// summation r * nCr
using System;
  
class GFG
{
static int MAX = 100;
  
// Return the first n term 
// of binomial coefficient.
static void binomialCoeff(int n, 
                          int []C)
{
    C[0] = 1; // nC0 is 1
  
    for (int i = 1; i <= n; i++)
    {
  
        // Compute next row of
        // pascal triangle using 
        // the previous row
        for (int j = Math.Min(i, n); 
                 j > 0; j--)
            C[j] = C[j] + C[j - 1];
    }
}
  
// Return summation
// of r * nCr
static int summation(int n)
{
    int []C = new int[MAX];
      
    for(int i = 0; i < MAX; i++)
    C[i] = 0;
  
    // finding the first n term 
    // of binomial coefficient
    binomialCoeff(n, C);

2790
Chapter 388. Sum of product of r and rth Binomial Coefficient (r * nCr)

  
    // Iterate a loop 
    // to find the sum.
    int sum = 0;
    for (int i = 0; i <= n; i++) 
        sum += (i * C[i]); 
  
    return sum;
}
  
// Driver Code
public static void Main()
{
    int n = 2;
    Console.Write( summation(n));
}
}
  
// This code is contributed 
// by shiv_bhakt

Output:

Method 2 (Using formula) :


Mathematically we need to find,
Σ (i * n Ci ), where 0 <= i <= n
= Σ (i C1 * n Ci ), (Since n C1 = n, we can write i as i C1 )
= Σ ( (i! / (i – 1)! * 1!) * (n! / (n – i)! * i!)
On cancelling i! from numerator and denominator
= Σ (n! / (i – 1)! * (n – i)!)
= Σ n * ((n – 1)!/ (i – 1)! * (n – i)!)
(Using reverse of n Cr = (n)!/ (r)! * (n – r)!)
= n * Σ n – 1 Cr – 1
= n * 2n – 1 (Since Σ n Cr = 2n )
Below is the implementation of this approach:

C++

// CPP Program to find sum of product of r and


// rth Binomial Coefficient i.e summation r * nCr
#include <bits/stdc++.h>
using namespace std;
#define MAX 100

2791
Chapter 388. Sum of product of r and rth Binomial Coefficient (r * nCr)

  
// Return summation of r * nCr
int summation(int n)
{
    return n << (n - 1);
}
  
// Driven Program
int main()
{
    int n = 2;
    cout << summation(n) << endl;
    return 0;
}

Java

// Java Program to find sum of product of


// r and rth Binomial Coefficient i.e 
// summation r * nCr
import java.io.*;
  
class GFG {
  
    static int MAX = 100;
      
    // Return summation of r * nCr
    static int summation(int n)
    {
        return n << (n - 1);
    }
      
    // Driven Program
    public static void main (String[] args)
    {
        int n = 2;
        System.out.println( summation(n));
    }
}
  
// This code is contributed by anuj_67.

Python3

# Python3 Program to 


# find sum of product 
# of r and rth Binomial 

2792
Chapter 388. Sum of product of r and rth Binomial Coefficient (r * nCr)

# Coefficient i.e 
# summation r * nCr
  
# Return summation 
# of r * nCr
def summation( n):
    return n << (n - 1);
  
# Driver Code
n = 2;
print(summation(n));
  
# This code is contributed 
# by mits

C#

// C# Program to find sum of product of


// r and rth Binomial Coefficient i.e 
// summation r * nCr
using System;
  
class GFG {
  
    //static int MAX = 100;
      
    // Return summation of r * nCr
    static int summation(int n)
    {
        return n << (n - 1);
    }
      
    // Driver Code
    public static void Main ()
    {
        int n = 2;
        Console.WriteLine( summation(n));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP Program to find sum 
// of product of r and

2793
Chapter 388. Sum of product of r and rth Binomial Coefficient (r * nCr)

// rth Binomial Coefficient


// i.e summation r * nCr
  
// Return summation of r * nCr
function summation( $n)
{
    return $n << ($n - 1);
}
  
// Driver Code
$n = 2;
echo summation($n) ;
  
// This code is contributed 
// by shiv_bhakt
?>

Output:

Improved By : vt_m, andrew1234, shiv_bhakt, Mithun Kumar

Source

https://www.geeksforgeeks.org/sum-product-r-rth-binomial-coefficient-r-ncr/

2794
Chapter 389

Sum of products of all


combination taken (1 to n) at a
time

Sum of products of all combination taken (1 to n) at a time - GeeksforGeeks


Given N, we have to find the sum of products of all combination taken 1 to N at a time. In
simple words, we have to find the sum of products of all combination taken 1 at time, then
2 at a time, then 3 at a time till N at a time.
If you think closely about the problem, a large value of N could result in producing a large
number of combinations.
Examples:

Input : N = 3
Output : f(1) = 6
f(2) = 11
f(3) = 6

Explanation: f(x) is sum of products of all


combination taken x at a time
1 + 2 + 3 = 6
f(2) = (1*2) + (1*3) + (2*3) = 11
f(3) = (1*2*3)

Input : N = 4
Output : f(1) = 10
f(2) = 35
f(3) = 50
f(4) = 24

2795
Chapter 389. Sum of products of all combination taken (1 to n) at a time

Explanation: f(1) = 1 + 2 + 3 + 4 = 10
f(2) = (1*2) + (1*3) + (1*4) +
(2*3) + (2*4) + (3*4)
= 35
f(3) = (1*2*3) + (1*2*4) +(1*3*4) +
(2*3*4)
= 50
f(4) = (1*2*3*4) = 24

A Brute force approach would be to produce all the combinations and then find their
products and sum.
Recursion would do the trick to produce the combinations taken x at a time.
Example : N = 4 taken 3 at a time

C++

// Program to find SOP of all combination taken


// (1 to N) at a time using brute force
#include <iostream>
using namespace std;
  
// to store sum of every combination
int sum = 0;
  
void Combination(int a[], int combi[], int n, 
                int r, int depth, int index) {
  
  // if we have reached sufficient depth
  if (index == r) {
      
    // find the product of combination

2796
Chapter 389. Sum of products of all combination taken (1 to n) at a time

    int product = 1;
    for (int i = 0; i < r; i++)
      product = product * combi[i];
  
    // add the product into sum
    sum += product;
    return;
  }
  
  // recursion to produce different combination
  for (int i = depth; i < n; i++) {
    combi[index] = a[i];
    Combination(a, combi, n, r, i + 1, index + 1);
  }
}
  
// function to print sum of products of
// all combination taken 1-N at a time
void allCombination(int a[], int n) {
  for (int i = 1; i <= n; i++) {
  
    // creating temporary array for storing
    // combination
    int *combi = new int[i];
  
    // call combination with r = i
    // for combination taken i at a time
    Combination(a, combi, n, i, 0, 0);
  
    // displaying sum
    cout << "f(" << i << ") --> " << sum << "\n";
    sum = 0;
  
    // free from heap area
    free(combi);
  }
}
  
// Driver's code
int main() {
  int n = 5;
  int *a = new int[n];
  
  // storing numbers from 1-N in array
  for (int i = 0; i < n; i++)
    a[i] = i + 1;
  
  // calling allCombination

2797
Chapter 389. Sum of products of all combination taken (1 to n) at a time

  allCombination(a, n);
  
  return 0;
}

Java

// Program to find SOP of 


// all combination taken
// (1 to N) at a time using
// brute force
import java.io.*;
  
class GFG
{
    // to store sum of
    // every combination
    static int sum = 0;
      
    static void Combination(int []a, int []combi, 
                            int n, int r, 
                            int depth, int index) 
    {
      
    // if we have reached
    // sufficient depth
    if (index == r) 
    {
          
        // find the product
        // of combination
        int product = 1;
        for (int i = 0; i < r; i++)
        product = product * combi[i];
      
        // add the product into sum
        sum += product;
        return;
    }
      
    // recursion to produce 
    // different combination
    for (int i = depth; i < n; i++) 
    {
        combi[index] = a[i];
        Combination(a, combi, n, r, 
                    i + 1, index + 1);
    }

2798
Chapter 389. Sum of products of all combination taken (1 to n) at a time

    }
      
    // function to print sum of 
    // products of all combination
    // taken 1-N at a time
    static void allCombination(int []a, 
                               int n)
    {
        for (int i = 1; i <= n; i++) 
        {
          
            // creating temporary array 
            // for storing combination
            int []combi = new int[i];
          
            // call combination with 
            // r = i for combination 
            // taken i at a time
            Combination(a, combi, n,
                        i, 0, 0);
          
            // displaying sum
            System.out.print("f(" + i + ") --> " + 
                                      sum + "\n");
            sum = 0;
        }
    }
      
    // Driver code
    public static void main(String args[]) 
    {
        int n = 5;
        int []a = new int[n];
          
        // storing numbers 
        // from 1-N in array
        for (int i = 0; i < n; i++)
            a[i] = i + 1;
          
        // calling allCombination
        allCombination(a, n);
    }

  
// This code is contributed by 
// Manish Shaw(manishshaw1)

C#

2799
Chapter 389. Sum of products of all combination taken (1 to n) at a time

// Program to find SOP of 


// all combination taken
// (1 to N) at a time using
// brute force
using System;
  
class GFG
{
    // to store sum of
    // every combination
    static int sum = 0;
      
    static void Combination(int []a, int []combi, 
                            int n, int r, 
                            int depth, int index) 
    {
      
    // if we have reached
    // sufficient depth
    if (index == r) 
    {
          
        // find the product
        // of combination
        int product = 1;
        for (int i = 0; i < r; i++)
        product = product * combi[i];
      
        // add the product into sum
        sum += product;
        return;
    }
      
    // recursion to produce 
    // different combination
    for (int i = depth; i < n; i++) 
    {
        combi[index] = a[i];
        Combination(a, combi, n, r, 
                    i + 1, index + 1);
    }
    }
      
    // function to print sum of 
    // products of all combination
    // taken 1-N at a time
    static void allCombination(int []a, 
                               int n)

2800
Chapter 389. Sum of products of all combination taken (1 to n) at a time

    {
    for (int i = 1; i <= n; i++) 
    {
      
        // creating temporary array 
        // for storing combination
        int []combi = new int[i];
      
        // call combination with 
        // r = i for combination 
        // taken i at a time
        Combination(a, combi, n,
                    i, 0, 0);
      
        // displaying sum
        Console.Write("f(" + i + ") --> " + 
                               sum + "\n");
        sum = 0;
    }
    }
      
    // Driver code
    static void Main() 
    {
        int n = 5;
        int []a = new int[n];
          
        // storing numbers 
        // from 1-N in array
        for (int i = 0; i < n; i++)
            a[i] = i + 1;
          
        // calling allCombination
        allCombination(a, n);
    }
}
  
// This code is contributed by 
// Manish Shaw(manishshaw1)

Output:

f(1) --> 15
f(2) --> 85
f(3) --> 225
f(4) --> 274

2801
Chapter 389. Sum of products of all combination taken (1 to n) at a time

f(5) --> 120

The Time complexity of above code is exponential when the value of N is large.
An Efficient Method is to use the concept of dynamic programming. We don’t have to
find sum of products every time. We can make use of previous results.
Let’s take an example: N = 4

C++

// CPP Program to find sum of all combination takne


// (1 to N) at a time using dynamic programming
#include <iostream>
using namespace std;
  
// find the postfix sum array
void postfix(int a[], int n) {
  for (int i = n - 1; i > 0; i--)
    a[i - 1] = a[i - 1] + a[i];
}
  
// modify the array such that we don't have to
// compute the products which are obtained before
void modify(int a[], int n) {
  for (int i = 1; i < n; i++)
    a[i - 1] = i * a[i];

2802
Chapter 389. Sum of products of all combination taken (1 to n) at a time

}
  
// finding sum of all combination taken 1 to N at a time
void allCombination(int a[], int n) {
  
  int sum = 0;
  
  // sum taken 1 at time is simply sum of 1 - N
  for (int i = 1; i <= n; i++)
    sum += i;
  cout << "f(1) --> " << sum << "\n";
  
  // for sum of products for all combination
  for (int i = 1; i < n; i++) {
  
    // finding postfix array
    postfix(a, n - i + 1);
      
    // sum of products taken i+1 at a time
    sum = 0;
    for (int j = 1; j <= n - i; j++) {
      sum += (j * a[j]);
    }
    cout << "f(" << i + 1 << ") --> " << sum << "\n";
  
    // modify the array for overlapping problem
    modify(a, n);
  }
}
  
// Driver's Code
int main() {
  int n = 5;
  int *a = new int[n];
  
  // storing numbers from 1 to N
  for (int i = 0; i < n; i++)
    a[i] = i + 1;
  
  // calling allCombination
  allCombination(a, n);
  
  return 0;
}

Output:

2803
Chapter 389. Sum of products of all combination taken (1 to n) at a time

f(1) --> 15
f(2) --> 85
f(3) --> 225
f(4) --> 274
f(5) --> 120

The Time Complexity of above method is O(n^2) which far more better than the brute
force method.
You can also find the execution time of both the method for large value of N and can see
the difference for yourself.
Improved By : manishshaw1

Source

https://www.geeksforgeeks.org/sum-products-combination-taken-1-n-time/

2804
Chapter 390

Super Ugly Number (Number


whose prime factors are in given
set)

Super Ugly Number (Number whose prime factors are in given set) - GeeksforGeeks
Super ugly numbers are positive numbers whose all prime factors are in the given prime list.
Given a number n, the task is to find n’th Super Ugly number.
It may be assumed that given set of primes is sorted. Also, first Super Ugly number is 1 by
convention.
Examples:

Input : primes[] = [2, 5]


n = 5
Output : 8
Super Ugly numbers with given prime factors
are 1, 2, 4, 5, 8, ...
Fifth Super Ugly number is 8

Input : primes[] = [2, 3, 5]


n = 50
Output : 243

Input : primes[] = [3, 5, 7, 11, 13]


n = 9
Output: 21

In our previous post we discussed about Ugly Number. This problem is basically extension
of Ugly Numbers.

2805
Chapter 390. Super Ugly Number (Number whose prime factors are in given set)

A simple solution for this problem is to one by one pick each number starting from 1
and find its all primes factors, if all prime factors lie in the given set of primes that means
number is Super Ugly. Repeat this process until we get n’th Super Ugly Number .
An efficient solution for this problem is similar to Method-2 of Ugly Number. Here is
the algorithm :

1. Let k be size of given array of prime numbers.


2. Declare a set for super ugly numbers.
3. Insert first ugly number (which is always 1) into set.
4. Initialize array multiple_of[k] of size k with 0. Each element of this array is iterator
for corresponding prime in primes[k] array.
5. Initialize nextMultipe[k] array with primes[k]. This array behaves like next multi-
ple variables of each prime in given primes[k] array i.e; nextMultiple[i] = primes[i] *
ugly[++multiple_of[i]].
6. Now loop until there are n elements in set ugly.
a). Find minimum among current multiples of primes in nextMultiple[] array and
insert it in the set of ugly numbers.
b). Then find this current minimum is multiple of which prime .
c). Increase iterator by 1 i.e; ++multiple_Of[i], for next multiple of current selected
prime and update nextMultiple for it.

Below is implementation of above steps.

// C++ program to find n'th Super Ugly number


#include<bits/stdc++.h>
using namespace std;
  
// Function to get the nth super ugly number
// primes[]       --> given list of primes f size k
// ugly           --> set which holds all super ugly
//                    numbers from 1 to n
// k              --> Size of prime[]
int superUgly(int n, int primes[], int k)
{
    // nextMultiple holds multiples of given primes
    vector<int> nextMultiple(primes, primes+k);
  
    // To store iterators of all primes
    int multiple_Of[k];
    memset(multiple_Of, 0, sizeof(multiple_Of));
  
    // Create a set to store super ugly numbers and
    // store first Super ugly number
    set<int> ugly;
    ugly.insert(1);
  
    // loop until there are total n Super ugly numbers

2806
Chapter 390. Super Ugly Number (Number whose prime factors are in given set)

    // in set
    while (ugly.size() != n)
    {
        // Find minimum element among all current
        // multiples of given prime
        int next_ugly_no = *min_element(nextMultiple.begin(),
                                    nextMultiple.end());
  
        // insert this super ugly number in set
        ugly.insert(next_ugly_no);
  
        // loop to find current minimum is multiple
        // of which prime
        for (int j=0; j<k; j++)
        {
            if (next_ugly_no == nextMultiple[j])
            {
                // increase iterator by one for next multiple
                // of current prime
                multiple_Of[j]++;
  
                // this loop is similar to find  dp[++index[j]]
                // it -->  dp[++index[j]]
                set<int>::iterator it = ugly.begin();
                for (int i=1; i<=multiple_Of[j]; i++)
                    it++;
  
                nextMultiple[j] = primes[j] * (*it);
                break;
            }
        }
    }
  
    // n'th super ugly number
    set<int>::iterator it = ugly.end();
    it--;
    return *it;
}
  
/* Driver program to test above functions */
int main()
{
    int primes[] = {2,  5};
    int k = sizeof(primes)/sizeof(primes[0]);
    int n = 5;
    cout << superUgly(n, primes, k);
    return 0;
}

2807
Chapter 390. Super Ugly Number (Number whose prime factors are in given set)

Output:

References :
http://stackoverflow.com/questions/34103076/super-ugly-number

Source

https://www.geeksforgeeks.org/super-ugly-number-number-whose-prime-factors-given-set/

2808
Chapter 391

Tabulation vs Memoizatation

Tabulation vs Memoizatation - GeeksforGeeks


Prerequisite – Dynamic Programming, How to solve Dynamic Programming problems?
There are following two different ways to store the values so that the values of a problem
can be reused. Here, will discuss two patterns of solving DP problem:

1. Tabulation: Bottom Up
2. Memoization: Top Down

Before getting to the definitions of the above two terms consider the below statements:

• Version 1: I will study the theory of Dynamic Programming from GeeksforGeeks,


then I will practice some problems on classic DP and hence I will master Dynamic
Programming.
• Version 2: To Master Dynamic Programming, I would have to practice Dynamic
problems and to practice problems – Firstly, I would have to study some theory of
Dynamic Programming from GeeksforGeeks

Both the above versions say the same thing, just the difference lies in the way of conveying
the message and that’s exactly what Bottom Up and Top Down DP do. Version 1 can be
related to as Bottom Up DP and Version-2 can be related as Top Down Dp.
Tabulation Method – Bottom Up Dynamic Programming
As the name itself suggests starting from the bottom and cumulating answers to the top.
Let’s discuss in terms of state transition.
Let’s describe a state for our DP problem to be dp[x] with dp[0] as base state and dp[n] as
our destination state. So, we need to find the value of destination state i.e dp[n].
If we start our transition from our base state i.e dp[0] and follow our state transition relation
to reach our destination state dp[n], we call it Bottom Up approach as it is quite clear that
we started our transition from the bottom base state and reached the top most desired state.
Now, Why do we call it tabulation method?

2809
Chapter 391. Tabulation vs Memoizatation

To know this let’s first write some code to calculate the factorial of a number using bottom
up approach. Once, again as our general procedure to solve a DP we first define a state. In
this case, we define a state as dp[x], where dp[x] is to find the factorial of x.
Now, it is quite obvious that dp[x+1] = dp[x] * (x+1)

// Tabulated version to find factorial x.


int dp[MAXN];

// base case
int dp[0] = 1;
for (int i = 1; i< =n; i++)
{
dp[i] = dp[i-1] * i;
}

The above code clearly follows the bottom-up approach as it starts its transition from the
bottom-most base case dp[0] and reaches its destination state dp[n]. Here, we may notice
that the dp table is being populated sequentially and we are directly accessing the calculated
states from the table itself and hence, we call it tabulation method.
Memoization Method – Top Down Dynamic Programming
Once, again let’s describe it in terms of state transition. If we need to find the value for some
state say dp[n] and instead of starting from the base state that i.e dp[0] we ask our answer
from the states that can reach the destination state dp[n] following the state transition
relation, then it is the top-down fashion of DP.
Here, we start our journey from the top most destination state and compute its answer by
taking in count the values of states that can reach the destination state, till we reach the
bottom most base state.
Once again, let’s write the code for the factorial problem in the top-down fashion

// Memoized version to find factorial x.


// To speed up we store the values
// of calculated states

// initialized to -1
int dp[MAXN]

// return fact x!
int solve(int x)
{
if (x==0)
return 1;
if (dp[x]!=-1)
return dp[x];

2810
Chapter 391. Tabulation vs Memoizatation

return (dp[x] = x * solve(x-1));


}

As we can see we are storing the most recent cache up to a limit so that if next time we got
a call from the same state we simply return it from the memory. So, this is why we call it
memoization as we are storing the most recent state values.
In this case the memory layout is linear that’s why it may seem that the memory is being
filled in a sequential manner like the tabulation method, but you may consider any other
top down DP having 2D memory layout like Min Cost Path, here the memory is not filled
in a sequential manner.

Source

https://www.geeksforgeeks.org/tabulation-vs-memoizatation/

2811
Chapter 392

Temple Offerings

Temple Offerings - GeeksforGeeks


Consider a devotee wishing to give offerings to temples along a mountain range. The temples
are located in a row at different heights. Each temple should receive at least one offering.
If two adjacent temples are at different altitudes, then the temple that is higher up should
receive more offerings than the one that is lower down. If two adjacent temples are at the
same height, then their offerings relative to each other does not matter. Given the number
of temples and the heights of the temples in order, find the minimum number of offerings
to bring.
Examples:

Input : 3
1 2 2
Output : 4
All temples must receive at-least one offering.
Now, the second temple is at a higher altitude
compared to the first one. Thus it receives one
extra offering.
The second temple and third temple are at the
same height, so we do not need to modify the
offerings. Offerings given are therefore: 1, 2,
1 giving a total of 4.

Input : 6
1 4 3 6 2 1
Output : 10
We can distribute the offerings in the following
way, 1, 2, 1, 3, 2, 1. The second temple has to
receive more offerings than the first due to its
height being higher. The fourth must receive more
than the fifth, which in turn must receive more

2812
Chapter 392. Temple Offerings

than the sixth. Thus the total becomes 10.

We notice that each temple can either be above, below, or at the same level as the temple
next to it. The offerings required at each temple is equal to the maximum length of the
chain of temples at lower height as shown in the image.

Naive Approach
To follow the given rule, a temple must be offered at least x+1 where x is maximum of
following two.

1. Number of temples on left in increasing order.


2. Number of temples on right in increasing order.

A naive method of solving this problem would be for each temple, go to the left until altitude
increases, and do the same for the right.
C++

2813
Chapter 392. Temple Offerings

// Program to find minimum total offerings required


#include <iostream>
using namespace std;
  
// Returns minimum offerings required
int offeringNumber(int n, int templeHeight[])
{
    int sum = 0;  // Initialize result
  
    // Go through all templs one by one
    for (int i = 0; i < n; ++i)
    {
        // Go to left while height keeps increasing
        int left = 0, right = 0;
        for (int j = i - 1; j >= 0; --j)
        {
            if (templeHeight[j] < templeHeight[j + 1])
                ++left;
            else
                break;
        }
  
        // Go to right while height keeps increasing
        for (int j = i + 1; j < n; ++j)
        {
            if (templeHeight[j] < templeHeight[j - 1])
                ++right;
            else
                break;
        }
  
        // This temple should offer maximum of two
        // values to follow the rule.
        sum += max(right, left) + 1;
    }
  
    return sum;
}
  
// Driver code
int main()
{
    int arr1[3] = {1, 2, 2};
    cout << offeringNumber(3, arr1) << "\n";
    int arr2[6] = {1, 4, 3, 6, 2, 1};
    cout << offeringNumber(6, arr2) << "\n";
    return 0;
}

2814
Chapter 392. Temple Offerings

Java

// Program to find minimum


// total offerings required
import java.io.*;
  
class GFG 
{
      
// Returns minimum
// offerings required
static int offeringNumber(int n, 
                          int templeHeight[])
{
    int sum = 0; // Initialize result
  
    // Go through all
    // temples one by one
    for (int i = 0; i < n; ++i)
    {
        // Go to left while 
        // height keeps increasing
        int left = 0, right = 0;
        for (int j = i - 1; j >= 0; --j)
        {
            if (templeHeight[j] < 
                templeHeight[j + 1])
                ++left;
            else
                break;
        }
  
        // Go to right while
        // height keeps increasing
        for (int j = i + 1; j < n; ++j)
        {
            if (templeHeight[j] < 
                templeHeight[j - 1])
                ++right;
            else
                break;
        }
  
        // This temple should offer
        // maximum of two values
        // to follow the rule.
        sum += Math.max(right, left) + 1;
    }

2815
Chapter 392. Temple Offerings

  
    return sum;
}
  
// Driver code
public static void main (String[] args) 
{
int arr1[] = {1, 2, 2};
System.out.println(offeringNumber(3, arr1));
int arr2[] = {1, 4, 3, 
              6, 2, 1};
System.out.println(offeringNumber(6, arr2));
}
}
  
// This code is contributed by akt_mit

C#

// Program to find minimum


// total offerings required
using System;
  
class GFG
{
      
// Returns minimum
// offerings required
static int offeringNumber(int n, 
                          int []templeHeight)
{
    int sum = 0; // Initialize result
  
    // Go through all
    // temples one by one
    for (int i = 0; i < n; ++i)
    {
        // Go to left while 
        // height keeps increasing
        int left = 0, right = 0;
        for (int j = i - 1; j >= 0; --j)
        {
            if (templeHeight[j] < 
                templeHeight[j + 1])
                ++left;
            else
                break;
        }

2816
Chapter 392. Temple Offerings

  
        // Go to right while
        // height keeps increasing
        for (int j = i + 1; j < n; ++j)
        {
            if (templeHeight[j] < 
                templeHeight[j - 1])
                ++right;
            else
                break;
        }
  
        // This temple should offer
        // maximum of two values
        // to follow the rule.
        sum += Math.Max(right, left) + 1;
    }
  
    return sum;
}
  
// Driver code
static public void Main ()
{
    int []arr1 = {1, 2, 2};
    Console.WriteLine(offeringNumber(3, arr1));
      
    int []arr2 = {1, 4, 3, 
                  6, 2, 1};
    Console.WriteLine(offeringNumber(6, arr2));
}
}
  
// This code is contributed by aj_36

PHP

<?php
// Program to find minimum total offerings required
  
// Returns minimum offerings required
function offeringNumber($n, $templeHeight)
{
    $sum = 0; // Initialize result
  
    // Go through all templs one by one
    for ($i = 0; $i < $n; ++$i)
    {

2817
Chapter 392. Temple Offerings

        // Go to left while height keeps increasing


        $left = 0; $right = 0;
        for ($j = $i - 1; $j >= 0; --$j)
        {
            if ($templeHeight[$j] < $templeHeight[$j + 1])
                ++$left;
            else
                break;
        }
  
        // Go to right while height keeps increasing
        for ($j = $i + 1; $j < $n; ++$j)
        {
            if ($templeHeight[$j] < $templeHeight[$j - 1])
                ++$right;
            else
                break;
        }
  
        // This temple should offer maximum of two
        // values to follow the rule.
        $sum += max($right, $left) + 1;
    }
  
    return $sum;
}
  
// Driver code
    $arr1 = array (1, 2, 2);
    echo offeringNumber(3, $arr1) , "\n";
    $arr2 = array (1, 4, 3, 6, 2, 1);
    echo offeringNumber(6, $arr2) ,"\n";
      
// This code is contributed by ajit
?>

Output:

4
10

Time complexity: O(n2 )


Space complexity: O(1)
Dynamic Programming Approach
By using Dynamic Programming, we can improve the time complexity. In this method, we
create a structure of length n which maintains the maximum decreasing chain to the left of

2818
Chapter 392. Temple Offerings

each temple and the maximum decreasing chain to the right of each temple. We go through
once from 0 to N setting the value of left for each temple. We then go from N to 0 setting
the value of right for each temple. We then compare the two and pick the maximum for
each temple.
C++

// Program to find total offerings required


#include <iostream>
using namespace std;
  
// To store count of increasing order temples
// on left and right (including current temple)
struct Temple
{
    int L;
    int R;
};
  
// Returns count of minimum offerings for
// n temples of given heights.
int offeringNumber(int n, int templeHeight[])
{
    // Initialize counts for all temples
    Temple chainSize[n];
    for (int i = 0; i < n; ++i)
    {
        chainSize[i].L = -1;
        chainSize[i].R = -1;
    }
  
    // Values corner temples
    chainSize[0].L = 1;
    chainSize[n-1].R = 1;
  
    // Filling left and right values using same
    // values of previous(or next)
    for (int i=1; i<n; ++i)
    {
        if (templeHeight[i - 1] < templeHeight[i])
            chainSize[i].L = chainSize[i - 1].L + 1;
        else
            chainSize[i].L = 1;
    }
    for (int i=n-2; i>=0; --i)
    {
        if (templeHeight[i + 1] < templeHeight[i])
            chainSize[i].R = chainSize[i + 1].R + 1;
        else

2819
Chapter 392. Temple Offerings

            chainSize[i].R = 1;
    }
  
    // Computing max of left and right for all
    // temples and returing sum.
    int sum = 0;
    for (int i = 0; i < n; ++i)
        sum += max(chainSize[i].L, chainSize[i].R);
    return sum;
}
  
// Driver function
int main()
{
    int arr1[3] = {1, 2, 2};
    cout << offeringNumber(3, arr1) << "\n";
    int arr2[6] = {1, 4, 3, 6, 2, 1};
    cout << offeringNumber(6, arr2) << "\n";
    return 0;
}

Output:

4
10

Improved By : jit_t

Source

https://www.geeksforgeeks.org/temple-offerings/

2820
Chapter 393

Tetranacci Numbers

Tetranacci Numbers - GeeksforGeeks


The tetranacci numbers are a generalization of the Fibonacci numbers defined by the recur-
rence relation

T(n) = T(n-1) + T(n-2) + T(n-3) + T(n-4)


with T(0)=0, T(1)=1, T(2)=1, T(3)=2,

For n>=4. They represent the n=4 case of the Fibonacci n-step numbers. The first few
terms for n=0, 1, … are 0, 1, 1, 2, 4, 8, 15, 29, 56, 108, 208, …
Given a number N. The task is to find the N-th tetranacci number.
Examples:

Input: 5
Output: 4

Input: 9
Output: 108

A naive approach is to follow the recurrence for finding the number and use recursion to
solve it.
Below is the implementation of the above approach.

C++

// A simple recursive CPP program to print


// the nth tetranacci numbers.
#include <iostream>

2821
Chapter 393. Tetranacci Numbers

using namespace std;


  
// Function to return the
// N-th tetranacci number
int printTetraRec(int n)
{
    // base cases
    if (n == 0)
        return 0;
    // base cases
    if (n == 1 || n == 2)
        return 1;
    // base cases
    if (n == 3)
        return 2;
  
    else
        return printTetraRec(n - 1) + printTetraRec(n - 2)
               + printTetraRec(n - 3) + printTetraRec(n - 4);
}
  
// function to print the nth tetranacci number
void printTetra(int n)
{
    cout << printTetraRec(n) << " ";
}
  
// Driver code
int main()
{
    int n = 10;
    printTetra(n);
    return 0;
}

Java
// A simple recursive Java
// program to print the nth
// tetranacci numbers.
class GFG
{
// Function to return the
// N-th tetranacci number
static int printTetraRec(int n)
{
// base cases
if (n == 0)
return 0;

2822
Chapter 393. Tetranacci Numbers

// base cases
if (n == 1 || n == 2)
return 1;
// base cases
if (n == 3)
return 2;
else
return printTetraRec(n – 1) +
printTetraRec(n – 2) +
printTetraRec(n – 3) +
printTetraRec(n – 4);
}
// function to print the
// Nth tetranacci number
static void printTetra(int n)
{
System.out.println(printTetraRec(n) + ” “);
}
// Driver code
public static void main(String[] args)
{
int n = 10;
printTetra(n);
}
}
// This code is contributed by mits
Output:

208

Time Complexity: O(4N )


A better solution is to use Dynamic Programming(memoisation) as there are multiple
overlaps.
Given below is the recursive tree for N=10.

rec(10)

/ / \ \

rec(9) rec(8) rec(7) rec(6)

/ / \ \

2823
Chapter 393. Tetranacci Numbers

rec(8) rec(7) rec(6) rec(5)

In the above partial recursion tree, rec(8), rec(7), rec(6) has been solved twice. On draw-
ing the complete recursion tree, it has been observed that there are many subproblems
which are solved again and again. So this problem has Overlapping Substructure property
and recomputation of same subproblems can be avoided by either using Memoization or
Tabulation.
Below is the implementation of the above approach

// A DP based CPP
// program to print
// the nth tetranacci number
#include <iostream>
using namespace std;
  
// Function to print the
// N-th tetranacci number
int printTetra(int n)
{
    int dp[n + 5];
    // base cases
    dp[0] = 0;
    dp[1] = dp[2] = 1;
    dp[3] = 2;
  
    for (int i = 4; i <= n; i++)
        dp[i] = dp[i - 1] + dp[i - 2] +
                dp[i - 3] + dp[i - 4];
  
    cout << dp[n];
}
  
// Driver code
int main()
{
    int n = 10;
    printTetra(n);
    return 0;
}

Output:

208

2824
Chapter 393. Tetranacci Numbers

Time Complexity: O(N)


Auxiliary Space: O(N)
The time complexity of above is linear, but it requires extra space. Space used can be ot-
pimized in above solution by using four variables to keep track of the previous four numbers.
Below is the implementation of the above approach

// A space optimized
// based CPP program to
// print the nth tetranacci number
#include <iostream>
using namespace std;
  
// Function to print the
// N-th tetranacci number
void printTetra(int n)
{
    if (n < 0)
        return;
  
    // Initialize first
    // four numbers to base cases
    int first = 0, second = 1;
    int third = 1, fourth = 2;
  
    // declare a current variable
    int curr;
  
    if (n == 0)
        cout << first;
    else if (n == 1 || n == 2)
        cout << second;
  
    else if (n == 3)
        cout << fourth;
  
    else {
  
        // Loop to add previous
        // four numbers for
        // each number starting
        // from 4 and then assign
        // first, second, third
        // to second, third, fourth and
        // curr to fourth respectively
        for (int i = 4; i <= n; i++) {
            curr = first + second + third + fourth;
            first = second;

2825
Chapter 393. Tetranacci Numbers

            second = third;
            third = fourth;
            fourth = curr;
        }
        cout << curr;
    }
}
  
// Driver code
int main()
{
    int n = 10;
    printTetra(n);
    return 0;
}

Output:

208

Time Complexity: O(N)


Auxiliary Space: O(1)
Improved By : Mithun Kumar

Source

https://www.geeksforgeeks.org/tetranacci-numbers/

2826
Chapter 394

The Two Water Jug Puzzle

The Two Water Jug Puzzle - GeeksforGeeks


You are at the side of a river. You are given a m litre jug and a n litre jug where 0 < m < n.
Both the jugs are initially empty. The jugs don’t have markings to allow measuring smaller
quantities. You have to use the jugs to measure d litres of water where d < n. Determine
the minimum no of operations to be performed to obtain d litres of water in one of jug.
The operations you can perform are:

1. Empty a Jug
2. Fill a Jug
3. Pour water from one jug to the other until one of the jugs is either empty or full.

There are several ways of solving this problem including BFS and DP. In this article an
arithmetic approach to solve the problem is discussed. The problem can be modeled by
means of Diophantine equation of the form mx + ny = d which is solvable if and only if
gcd(m, n) divides d. Also, the solution x,y for which equation is satisfied can be given using
the Extended Euclid algorithm for GCD.
For example, if we have a jug J1 of 5 litre (n = 5) and another jug J2 of 3 litre (m = 3) and
we have to measure 1 litre of water using them. The associated equation will be 5n + 3m
= 1. First of all this problem can be solved since gcd(3,5) = 1 which divides 1 (See this for
detailed explanation). Using the Extended Euclid algorithm, we get values of n and m for
which the equation is satisfied which are n = 2 and m = -3. These values of n, m also have
some meaning like here n = 2 and m = -3 means that we have to fill J1 twice and empty J2
thrice.
Now to find the minimum no of operations to be performed we have to decide which jug
should be filled first. Depending upon which jug is chosen to be filled and which to be
emptied we have two different solutions and the minimum among them would be our answer.
Solution 1 (Always pour from m litre jug into n litre jug)

1. Fill the m litre jug and empty it into n litre jug.


2. Whenever the m litre jug becomes empty fill it.

2827
Chapter 394. The Two Water Jug Puzzle

3. Whenever the n litre jug becomes full empty it.


4. Repeat steps 1,2,3 till either n litre jug or the m litre jug contains d litres of water.

Each of steps 1, 2 and 3 are counted as one operation that we perform. Let us say algorithm
1 achieves the task in C1 no of operations.
Solution 2 (Always pour from n litre jug into m litre jug)

1. Fill the n litre jug and empty it into m litre jug.


2. Whenever the n litre jug becomes empty fill it.
3. Whenever the m litre jug becomes full empty it.
4. Repeat steps 1, 2 and 3 till either n litre jug or the m litre jug contains d litres of
water.

Let us say solution 2 achieves the task in C2 no of operations.


Now our final solution will be minimum of C1 and C2.
Now we illustrate how both of the solutions work. Suppose there are a 3 litre jug and a 5
litre jug to measure 4 litres water so m = 3,n = 5 and d = 4. The associated Diophantine
equation will be 3m + 5n = 4. We us pair (x, y) to represent amounts of water inside 3
litre jug and 5 litre jug respectively in each pouring step.
Using Solution 1, successive pouring steps are:

(0,0)->(3,0)->(0,3)->(3,3)->(1,5)->(1,0)->(0,1)->(3,1)->(0,4)

Hence the no of operations you need to perform are 8.


Using Solution 2, successive pouring steps are:

(0,0)->(0,5)->(3,2)->(0,2)->(2,0)->(2,5)->(3,4)

Hence the no of operations you need to perform are 6.


Therefore we would use solution 2 to measure 4 liters of water in 6 operations or moves.
Based on the explanation here is an implementation in C++.

// C++ program to count minimum number of steps


// required to measure d litres water using jugs
// of m litres and n litres capacity.
#include <bits/stdc++.h>
using namespace std;
  
// Utility function to return GCD of 'a'
// and 'b'.
int gcd(int a, int b)
{

2828
Chapter 394. The Two Water Jug Puzzle

    if (b==0)
       return a;
    return gcd(b, a%b);
}
  
/* fromCap -- Capacity of jug from which
              water is poured
   toCap   -- Capacity of jug to which
              water is poured
   d       -- Amount to be measured */
int pour(int fromCap, int toCap, int d)
{
    // Initialize current amount of water
    // in source and destination jugs
    int from = fromCap;
    int to = 0;
  
    // Initialize count of steps required
    int step = 1; // Needed to fill "from" Jug
  
    // Break the loop when either of the two
    // jugs has d litre water
    while (from != d && to != d)
    {
        // Find the maximum amount that can be
        // poured
        int temp = min(from, toCap - to);
  
        // Pour "temp" litres from "from" to "to"
        to   += temp;
        from -= temp;
  
        // Increment count of steps
        step++;
  
        if (from == d || to == d)
            break;
  
        // If first jug becomes empty, fill it
        if (from == 0)
        {
            from = fromCap;
            step++;
        }
  
        // If second jug becomes full, empty it
        if (to == toCap)
        {

2829
Chapter 394. The Two Water Jug Puzzle

            to = 0;
            step++;
        }
    }
    return step;
}
  
// Returns count of minimum steps needed to
// measure d litre
int minSteps(int m, int n, int d)
{
    // To make sure that m is smaller than n
    if (m > n)
        swap(m, n);
  
    // For d > n we cant measure the water
    // using the jugs
    if (d > n)
        return -1;
  
    // If gcd of n and m does not divide d
    // then solution is not possible
    if ((d % gcd(n,m)) != 0)
        return -1;
  
    // Return minimum two cases:
    // a) Water of n litre jug is poured into
    //    m litre jug
    // b) Vice versa of "a"
    return min(pour(n,m,d),   // n to m
               pour(m,n,d));  // m to n
}
  
// Driver code to test above
int main()
{
    int n = 3, m = 5, d = 4;
  
    printf("Minimum number of steps required is %d",
           minSteps(m, n, d));
  
    return 0;
}

Minimum number of steps required is 6

2830
Chapter 394. The Two Water Jug Puzzle

Source

https://www.geeksforgeeks.org/two-water-jug-puzzle/

2831
Chapter 395

The painter’s partition problem

The painter’s partition problem - GeeksforGeeks


We have to paint n boards of length {A1, A2…An}. There are k painters available and each
takes 1 unit time to paint 1 unit of board. The problem is to find the minimum time to get
this job done under the constraints that any painter will only paint continuous sections of
boards, say board {2, 3, 4} or only board {1} or nothing but not board {2, 4, 5}.
Examples:

Input : k = 2, A = {10, 10, 10, 10}


Output : 20.
Here we can divide the boards into 2
equal sized partitions, so each painter
gets 20 units of board and the total
time taken is 20.

Input : k = 2, A = {10, 20, 30, 40}


Output : 60.
Here we can divide first 3 boards for
one painter and the last board for
second painter.

From the above examples, it is obvious that the strategy of dividing the boards into k equal
partitions won’t work for all the cases. We can observe that the problem can be broken
down into: Given an array A of non-negative integers and a positive integer k, we have to
divide A into k of fewer partitions such that the maximum sum of the elements in a partition,
overall partitions is minimized. So for the second example above, possible divisions are:
* One partition: so time is 100.
* Two partitions: (10) & (20, 30, 40), so time is 90. Similarly we can put the first divider
after 20 (=> time 70) or 30 (=> time 60); so this means the minimum time: (100, 90, 70,
60) is 60.

2832
Chapter 395. The painter’s partition problem

A brute force solution is to consider all possible set of contiguous partitions and calculate
the maximum sum partition in each case and return the minimum of all these cases.
1) Optimal Substructure:
We can implement the naive solution using recursion with the following optimal substructure
property:
Assuming that we already have k-1 partitions in place (using k-2 dividers), we now have to
put the k-1 th divider to get k partitions.
How can we do this? We can put the k-1 th divider between the i th and i+1 th element
where i = 1 to n. Please note that putting it before the first element is the same as putting
it after the last element.
The total cost of this arrangement can be calculated as the maximum of the following:
a) The cost of the last partition: sum(Ai..An), where the k-1 th divider is
before element i.
b) The maximum cost of any partition already formed to the left of the k-1 th divider.
Here a) can be found out using a simple helper function to calculate sum
of elements between two indices in the array. How to find out b) ?
We can observe that b) actually is to place the k-2 separators as fairly as
possible, so it is a subproblem of the given problem. Thus we can write the optimal
substructure property as the following recurrence relation:

Following is the implementation of the above recursive equation:

C++

// CPP program for The painter's partition problem


#include <climits>
#include <iostream>
using namespace std;
  
// function to calculate sum between two indices 
// in array
int sum(int arr[], int from, int to)

2833
Chapter 395. The painter’s partition problem

{
    int total = 0;
    for (int i = from; i <= to; i++)
        total += arr[i];
    return total;
}
  
// for n boards and k partitions
int partition(int arr[], int n, int k)
{
    // base cases    
    if (k == 1) // one partition
        return sum(arr, 0, n - 1);    
    if (n == 1)  // one board
        return arr[0];
  
    int best = INT_MAX;
  
    // find minimum of all possible maximum
    // k-1 partitions to the left of arr[i],
    // with i elements, put k-1 th divider 
    // between arr[i-1] & arr[i] to get k-th 
    // partition
    for (int i = 1; i <= n; i++)
        best = min(best, max(partition(arr, i, k - 1), 
                                sum(arr, i, n - 1)));
  
    return best;
}
  
int main()
{
    int arr[] = { 10, 20, 60, 50, 30, 40 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
    cout << partition(arr, n, k) << endl;
  
    return 0;
}

Java

// Java Program for The painter's partition problem


import java.util.*;
import java.io.*;
  
class GFG
{

2834
Chapter 395. The painter’s partition problem

// function to calculate sum between two indices 


// in array
static int sum(int arr[], int from, int to)
{
    int total = 0;
    for (int i = from; i <= to; i++)
        total += arr[i];
    return total;
}
   
// for n boards and k partitions
static int partition(int arr[], int n, int k)
{
    // base cases    
    if (k == 1) // one partition
        return sum(arr, 0, n - 1);    
    if (n == 1)  // one board
        return arr[0];
   
    int best = Integer.MAX_VALUE;
   
    // find minimum of all possible maximum
    // k-1 partitions to the left of arr[i],
    // with i elements, put k-1 th divider 
    // between arr[i-1] & arr[i] to get k-th 
    // partition
    for (int i = 1; i <= n; i++)
        best = Math.min(best, Math.max(partition(arr, i, k - 1), 
                                sum(arr, i, n - 1)));
   
    return best;
}
  
// Driver code
public static void main(String args[])
{
 int arr[] = { 10, 20, 60, 50, 30, 40 };
   
    // Calculate size of array.
    int n = arr.length;
        int k = 3;
 System.out.println(partition(arr, n, k));
}
}
  
// This code is contributed by Sahil_Bansall

C#

2835
Chapter 395. The painter’s partition problem

// C# Program for The painter's partition problem


using System;
  
class GFG {
      
// function to calculate sum 
// between two indices in array
static int sum(int []arr, int from, int to)
{
    int total = 0;
    for (int i = from; i <= to; i++)
        total += arr[i];
    return total;
}
  
// for n boards and k partitions
static int partition(int []arr, int n, int k)
{
    // base cases 
    if (k == 1) // one partition
        return sum(arr, 0, n - 1); 
          
    if (n == 1) // one board
        return arr[0];
  
    int best = int.MaxValue;
  
    // find minimum of all possible maximum
    // k-1 partitions to the left of arr[i],
    // with i elements, put k-1 th divider 
    // between arr[i-1] & arr[i] to get k-th 
    // partition
    for (int i = 1; i <= n; i++)
        best = Math.Min(best, Math.Max(partition(arr, i, k - 1), 
                                           sum(arr, i, n - 1)));
  
    return best;
}
  
// Driver code
public static void Main()
{
    int []arr = {10, 20, 60, 50, 30, 40};
  
    // Calculate size of array.
    int n = arr.Length;
    int k = 3;
      

2836
Chapter 395. The painter’s partition problem

    // Function calling


    Console.WriteLine(partition(arr, n, k));
}
}
  
// This code is contributed by vt_m

PHP

<?php
// PHP program for The 
// painter's partition problem
  
// function to calculate sum 
// between two indices in array
function sum($arr, $from, $to)
{
    $total = 0;
    for ($i = $from; $i <= $to; $i++)
        $total += $arr[$i];
    return $total;
}
  
// for n boards 
// and k partitions
function partition($arr, $n, $k)
{
    // base cases 
    if ($k == 1) // one partition
        return sum($arr, 0, $n - 1); 
    if ($n == 1) // one board
        return $arr[0];
  
    $best = PHP_INT_MAX;
  
    // find minimum of all possible 
    // maximum k-1 partitions to the 
    // left of arr[i], with i elements,
    // put k-1 th divider between 
    // arr[i-1] & arr[i] to get k-th 
    // partition
    for ($i = 1; $i <= $n; $i++)
        $best = min($best, 
                max(partition($arr, $i, $k - 1), 
                          sum($arr, $i, $n - 1)));
  
    return $best;
}

2837
Chapter 395. The painter’s partition problem

// Driver Code
$arr = array(10, 20, 60, 
             50, 30, 40);
$n = sizeof($arr);
$k = 3;
echo partition($arr, $n, $k), "\n";
  
// This code is contributed by ajit
?>

Output :

90

The time complexity of the above solution is exponential.


2) Overlapping subproblems:
Following is the partial recursion tree for T(4, 3) in above equation.

T(4, 3)
/ / \ ..
T(1, 2) T(2, 2) T(3, 2)
/.. /..
T(1, 1) T(1, 1)

We can observe that many subproblems like T(1, 1) in the above problem are being solved
again and again. Because of these two properties of this problem, we can solve it using
dynamic programming, either by top down memoized method or bottom up
tabular method. Following is the bottom up tabular implementation:

C++

// A DP based CPP program for painter's partition problem


#include <climits>
#include <iostream>
using namespace std;
  
// function to calculate sum between two indices
// in array
int sum(int arr[], int from, int to)
{
    int total = 0;
    for (int i = from; i <= to; i++)
        total += arr[i];
    return total;

2838
Chapter 395. The painter’s partition problem

}
  
// bottom up tabular dp
int findMax(int arr[], int n, int k)
{
    // initialize table
    int dp[k + 1][n + 1] = { 0 };
  
    // base cases
    // k=1
    for (int i = 1; i <= n; i++)
        dp[1][i] = sum(arr, 0, i - 1);
  
    // n=1
    for (int i = 1; i <= k; i++)
        dp[i][1] = arr[0];
  
    // 2 to k partitions
    for (int i = 2; i <= k; i++) { // 2 to n boards
        for (int j = 2; j <= n; j++) {
  
            // track minimum
            int best = INT_MAX;
  
            // i-1 th separator before position arr[p=1..j]
            for (int p = 1; p <= j; p++) 
                best = min(best, max(dp[i - 1][p],
                              sum(arr, p, j - 1)));       
  
            dp[i][j] = best;
        }
    }
  
    // required
    return dp[k][n];
}
  
// driver function
int main()
{
    int arr[] = { 10, 20, 60, 50, 30, 40 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
    cout << findMax(arr, n, k) << endl;
    return 0;
}

Java

2839
Chapter 395. The painter’s partition problem

// A DP based Java program for


// painter's partition problem
import java.util.*;
import java.io.*;
  
class GFG
{
// function to calculate sum between two indices
// in array
static int sum(int arr[], int from, int to)
{
    int total = 0;
    for (int i = from; i <= to; i++)
        total += arr[i];
    return total;
}
   
// bottom up tabular dp
static int findMax(int arr[], int n, int k)
{
    // initialize table
    int dp[][] = new int[k+1][n+1];
   
    // base cases
    // k=1
    for (int i = 1; i <= n; i++)
        dp[1][i] = sum(arr, 0, i - 1);
   
    // n=1
    for (int i = 1; i <= k; i++)
        dp[i][1] = arr[0];
   
    // 2 to k partitions
    for (int i = 2; i <= k; i++) { // 2 to n boards
        for (int j = 2; j <= n; j++) {
   
            // track minimum
            int best = Integer.MAX_VALUE;
   
            // i-1 th separator before position arr[p=1..j]
            for (int p = 1; p <= j; p++) 
                best = Math.min(best, Math.max(dp[i - 1][p],
                              sum(arr, p, j - 1)));       
   
            dp[i][j] = best;
        }
    }
   

2840
Chapter 395. The painter’s partition problem

    // required
    return dp[k][n];
}
  
// Driver code
public static void main(String args[])
{
 int arr[] = { 10, 20, 60, 50, 30, 40 };
   
    // Calculate size of array.
    int n = arr.length;
        int k = 3;
 System.out.println(findMax(arr, n, k));
}
}
  
// This code is contributed by Sahil_Bansall

C#

// A DP based C# program for


// painter's partition problem
using System;
  
class GFG {
      
// function to calculate sum between 
// two indices in array
static int sum(int []arr, int from, int to)
{
    int total = 0;
    for (int i = from; i <= to; i++)
        total += arr[i];
    return total;
}
  
// bottom up tabular dp
static int findMax(int []arr, int n, int k)
{
    // initialize table
    int [,]dp = new int[k+1,n+1];
  
    // base cases
    // k=1
    for (int i = 1; i <= n; i++)
        dp[1,i] = sum(arr, 0, i - 1);
  
    // n=1

2841
Chapter 395. The painter’s partition problem

    for (int i = 1; i <= k; i++)


        dp[i,1] = arr[0];
  
    // 2 to k partitions
    for (int i = 2; i <= k; i++) { // 2 to n boards
        for (int j = 2; j <= n; j++) {
  
            // track minimum
            int best = int.MaxValue;
  
            // i-1 th separator before position arr[p=1..j]
            for (int p = 1; p <= j; p++) 
                best = Math.Min(best, Math.Max(dp[i - 1,p],
                                      sum(arr, p, j - 1))); 
  
            dp[i,j] = best;
        }
    }
  
    // required
    return dp[k,n];
}
  
// Driver code
public static void Main()
{
    int []arr = {10, 20, 60, 50, 30, 40};
  
    // Calculate size of array.
    int n = arr.Length;
    int k = 3;
    Console.WriteLine(findMax(arr, n, k));
}
}
  
// This code is contributed by vt_m

PHP

<?php
// A DP based PHP program for
// painter's partition problem
  
// function to calculate sum 
// between two indices in array
function sum($arr, $from, $to)
{
    $total = 0;

2842
Chapter 395. The painter’s partition problem

    for ($i = $from; $i <= $to; $i++)


        $total += $arr[$i];
    return $total;
}
  
// bottom up tabular dp
function findMax($arr, $n, $k)
{
    // initialize table
    $dp[$k + 1][$n + 1] = array( 0 );
  
    // base cases
    // k=1
    for ($i = 1; $i <= $n; $i++)
        $dp[1][$i] = sum($arr, 0, 
                         $i - 1);
  
    // n=1
    for ($i = 1; $i <= $k; $i++)
        $dp[$i][1] = $arr[0];
  
    // 2 to k partitions
    for ($i = 2; $i <= $k; $i++) 
    { 
        // 2 to n boards
        for ($j = 2; $j <= $n; $j++) 
        {
  
            // track minimum
            $best = PHP_INT_MAX;
  
            // i-1 th separator before
            // position arr[p=1..j]
            for ($p = 1; $p <= $j; $p++) 
                $best = min($best, max($dp[$i - 1][$p],
                               sum($arr, $p, $j - 1)));     
  
            $dp[$i][$j] = $best;
        }
    }
  
    // required
    return $dp[$k][$n];
}
  
// Driver Code
$arr = array (10, 20, 60, 
              50, 30, 40 );

2843
Chapter 395. The painter’s partition problem

$n = sizeof($arr);
$k = 3;
echo findMax($arr, $n, $k) ,"\n";
  
// This code is contribted by m_kit
?>

Output:

90

Optimizations:

1) The time complexity of the above program is . It can be easily

brought down to by precomputing the cumulative sums in an array


thus avoiding repeated calls to the sum function:

    
 int sum[n+1] = {0};
  
 // sum from 1 to i elements of arr
 for (int i = 1; i <= n; i++)
   sum[i] = sum[i-1] + arr[i-1];
  
 for (int i = 1; i <= n; i++)
   dp[1][i] = sum[i];
 
and using it to calculate the result as:
best = min(best, max(dp[i-1][p], sum[j] - sum[p]));

2) Though here we consider to divide A into k or fewer partitions, we can observe that
the optimal case always occurs when we divide A into exactly k partitions. So we can use:

for (int i = k-1; i <= n; i++)


    best = min(best, max( partition(arr, i, k-1),
                            sum(arr, i, n-1)));

and modify the other implementations accordingly.


Exercise:
1) Can you come up with a solution using binary search which runs in O(N lg N)
time? Prerequisite for this: https://www.topcoder.com/community/data-science/
data-science-tutorials/binary-search/

2844
Chapter 395. The painter’s partition problem

References:
https://articles.leetcode.com/the-painters-partition-problem/
Asked in: Google, CodeNation
Improved By : vt_m, jit_t

Source

https://www.geeksforgeeks.org/painters-partition-problem/

2845
Chapter 396

The painter’s partition problem


| Set 2

The painter’s partition problem | Set 2 - GeeksforGeeks


We have to paint n boards of length {A1, A2, .. An}. There are k painters available and
each takes 1 unit time to paint 1 unit of board. The problem is to find the minimum time to
get this job done under the constraints that any painter will only paint continuous sections
of boards, say board {2, 3, 4} or only board {1} or nothing but not board {2, 4, 5}.
Examples :

Input : k = 2, A = {10, 10, 10, 10}


Output : 20.
Here we can divide the boards into 2
equal sized partitions, so each painter
gets 20 units of board and the total
time taken is 20.

Input : k = 2, A = {10, 20, 30, 40}


Output : 60.
Here we can divide first 3 boards for
one painter and the last board for
second painter.

In the previous post we discussed a dynamic programming based approach having time

complexity of and extra space.


In this post we will look into a more efficient approach using binary search. We know that
the invariant of binary search has two main parts:
* the target value would always be in the searching range.
* the searching range will decrease in each loop so that the termination can be reached.

2846
Chapter 396. The painter’s partition problem | Set 2

We also know that the values in this range must be in sorted order. Here our target value
is the maximum sum of a contiguous section in the optimal allocation of boards. Now how
can we apply binary search for this? We can fix the possible low to high range for the target
value and narrow down our search to get the optimal allocation.
We can see that the highest possible value in this range is the sum of all the elementsin the
array and this happens when we allot 1 painter all the sections of the board. The lowest
possible value of this range is the maximum value of the array max, as in this allocation we
can allot max to one painter and divide the other sections such
that the cost of them is less than or equal to max and as close as possible to max. Now if we
consider we use x painters in the above scenarios, it is obvious that as the value in the range
increases, the value of x decreases and vice-versa. From this we can find the target value
when x=k and use a helper function to find x, the minimum number of painters required
when the maximum length of section a painter can paint is given.
C++

// CPP program for painter's partition problem


#include <iostream>
using namespace std;
  
// return the maximum element from the array
int getMax(int arr[], int n)
{
    int max = INT_MIN;
    for (int i = 0; i < n; i++) 
        if (arr[i] > max)
            max = arr[i]; 
    return max;
}
  
// return the sum of the elements in the array
int getSum(int arr[], int n)
{
    int total = 0;
    for (int i = 0; i < n; i++)
        total += arr[i];
    return total;
}
  
// find minimum required painters for given maxlen
// which is the maximum length a painter can paint
int numberOfPainters(int arr[], int n, int maxLen)
{
    int total = 0, numPainters = 1;
  
    for (int i = 0; i < n; i++) {
        total += arr[i];
  

2847
Chapter 396. The painter’s partition problem | Set 2

        if (total > maxLen) {


  
            // for next count
            total = arr[i];
            numPainters++;
        }
    }
  
    return numPainters;
}
  
int partition(int arr[], int n, int k)
{
    int lo = getMax(arr, n);
    int hi = getSum(arr, n);
  
    while (lo < hi) {
        int mid = lo + (hi - lo) / 2;
        int requiredPainters = numberOfPainters(arr, n, mid);
  
        // find better optimum in lower half
        // here mid is included because we
        // may not get anything better
        if (requiredPainters <= k)
            hi = mid;
  
        // find better optimum in upper half
        // here mid is excluded because it gives 
        // required Painters > k, which is invalid
        else
            lo = mid + 1;
    }
  
    // required
    return lo;
}
  
// driver function
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int k = 3;
    cout << partition(arr, n, k) << endl;
    return 0;
}

Java

2848
Chapter 396. The painter’s partition problem | Set 2

// Java Program for painter's partition problem


import java.util.*;
import java.io.*;
  
class GFG
{
// return the maximum element from the array
static int getMax(int arr[], int n)
{
    int max = Integer.MIN_VALUE;
    for (int i = 0; i < n; i++) 
        if (arr[i] > max)
            max = arr[i]; 
    return max;
}
   
// return the sum of the elements in the array
static int getSum(int arr[], int n)
{
    int total = 0;
    for (int i = 0; i < n; i++)
        total += arr[i];
    return total;
}
   
// find minimum required painters for given maxlen
// which is the maximum length a painter can paint
static int numberOfPainters(int arr[], int n, int maxLen)
{
    int total = 0, numPainters = 1;
   
    for (int i = 0; i < n; i++) {
        total += arr[i];
   
        if (total > maxLen) {
   
            // for next count
            total = arr[i];
            numPainters++;
        }
    }
   
    return numPainters;
}
   
static int partition(int arr[], int n, int k)
{
    int lo = getMax(arr, n);

2849
Chapter 396. The painter’s partition problem | Set 2

    int hi = getSum(arr, n);


   
    while (lo < hi) {
        int mid = lo + (hi - lo) / 2;
        int requiredPainters = numberOfPainters(arr, n, mid);
   
        // find better optimum in lower half
        // here mid is included because we
        // may not get anything better
        if (requiredPainters <= k)
            hi = mid;
   
        // find better optimum in upper half
        // here mid is excluded because it gives 
        // required Painters > k, which is invalid
        else
            lo = mid + 1;
    }
   
    // required
    return lo;
}
  
// Driver code
public static void main(String args[])
{
 int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
   
    // Calculate size of array.
    int n = arr.length;
        int k = 3;
 System.out.println(partition(arr, n, k));
}
}
  
// This code is contributed by Sahil_Bansall

C#

// C# Program for painter's


// partition problem
using System;
  
class GFG
{
      
// return the maximum 
// element from the array

2850
Chapter 396. The painter’s partition problem | Set 2

static int getMax(int []arr, int n)


{
    int max = int.MinValue;
    for (int i = 0; i < n; i++) 
        if (arr[i] > max)
            max = arr[i]; 
    return max;
}
  
// return the sum of the
// elements in the array
static int getSum(int []arr, int n)
{
    int total = 0;
    for (int i = 0; i < n; i++)
        total += arr[i];
    return total;
}
  
// find minimum required 
// painters for given 
// maxlen which is the 
// maximum length a painter
// can paint
static int numberOfPainters(int []arr, 
                            int n, int maxLen)
{
    int total = 0, numPainters = 1;
  
    for (int i = 0; i < n; i++) 
    {
        total += arr[i];
  
        if (total > maxLen) 
        {
  
            // for next count
            total = arr[i];
            numPainters++;
        }
    }
  
    return numPainters;
}
  
static int partition(int []arr, 
                     int n, int k)
{

2851
Chapter 396. The painter’s partition problem | Set 2

    int lo = getMax(arr, n);


    int hi = getSum(arr, n);
  
    while (lo < hi) 
    {
        int mid = lo + (hi - lo) / 2;
        int requiredPainters = 
                       numberOfPainters(arr, n, mid);
  
        // find better optimum in lower 
        // half here mid is included 
        // because we may not get 
        // anything better
        if (requiredPainters <= k)
            hi = mid;
  
        // find better optimum in upper 
        // half here mid is excluded 
        // because it gives required
        // Painters > k, which is invalid
        else
            lo = mid + 1;
    }
  
    // required
    return lo;
}
  
// Driver code
static public void Main ()
{
    int []arr = {1, 2, 3, 4, 5, 
                 6, 7, 8, 9};
  
    // Calculate size of array.
    int n = arr.Length;
    int k = 3;
    Console.WriteLine(partition(arr, n, k));
}
}
  
// This code is contributed by ajit

PHP

<?php
// PHP program for painter's 
// partition problem

2852
Chapter 396. The painter’s partition problem | Set 2

  
// return the maximum 
// element from the array
function getMax($arr, $n)
{
    $max = PHP_INT_MIN;
    for ($i = 0; $i < $n; $i++) 
        if ($arr[$i] > $max)
            $max = $arr[$i]; 
    return $max;
}
  
// return the sum of the
// elements in the array
function getSum($arr, $n)
{
    $total = 0;
    for ($i = 0; $i < $n; $i++)
        $total += $arr[$i];
    return $total;
}
  
// find minimum required painters 
// for given maxlen which is the
// maximum length a painter can paint
function numberOfPainters($arr, $n, 
                          $maxLen)
{
    $total = 0; $numPainters = 1;
  
    for ($i = 0; $i < $n; $i++)
    {
        $total += $arr[$i];
  
        if ($total > $maxLen) 
        {
  
            // for next count
            $total = $arr[$i];
            $numPainters++;
        }
    }
  
    return $numPainters;
}
  
function partition($arr, $n, $k)
{

2853
Chapter 396. The painter’s partition problem | Set 2

    $lo = getMax($arr, $n);


    $hi = getSum($arr, $n);
  
    while ($lo < $hi) 
    {
        $mid = $lo + ($hi - $lo) / 2;
        $requiredPainters = 
                    numberOfPainters($arr, 
                                     $n, $mid);
  
        // find better optimum in
        // lower half here mid is 
        // included because we may 
        // not get anything better
        if ($requiredPainters <= $k)
            $hi = $mid;
  
        // find better optimum in 
        // upper half here mid is 
        // excluded because it 
        // gives required Painters > k,
        // which is invalid
        else
            $lo = $mid + 1;
    }
  
    // required
    return floor($lo);
}
  
// Driver Code
$arr = array(1, 2, 3, 
             4, 5, 6, 
             7, 8, 9);
$n = sizeof($arr);
$k = 3;
  
echo partition($arr, $n, $k) , "\n";
  
// This code is contributed by ajit
?>

Output :

17

For better understanding, please trace the example given in the program in pen and paper.

2854
Chapter 396. The painter’s partition problem | Set 2

The time complexity of the above approach is .


References:
https://articles.leetcode.com/the-painters-partition-problem-part-ii/
https://www.topcoder.com/community/data-science/data-science-tutorials/binary-search/
Asked in: Google, Codenation.
Improved By : jit_t

Source

https://www.geeksforgeeks.org/painters-partition-problem-set-2/

2855
Chapter 397

Tile Stacking Problem

Tile Stacking Problem - GeeksforGeeks


A stable tower of height n is a tower consisting of exactly n tiles of unit height stacked
vertically in such a way, that no bigger tile is placed on a smaller tile. An example is shown
below :

We have infinite number of tiles of sizes 1, 2, …, m. The task is calculate the number of
different stable tower of height n that can be built from these tiles, with a restriction that
you can use at most k tiles of each size in the tower.
Note: Two tower of height n are different if and only if there exists a height h (1 <= h <=
n), such that the towers have tiles of different sizes at height h.
Examples:

Input : n = 3, m = 3, k = 1.

2856
Chapter 397. Tile Stacking Problem

Output : 1
Possible sequences: { 1, 2, 3}.
Hence answer is 1.

Input : n = 3, m = 3, k = 1.
Output : 7
{1, 1, 2}, {1, 1, 3}, {1, 2, 2},
{1, 2, 3}, {1, 3, 3}, {2, 2, 3},
{2, 3, 3}.

We basically need to count number of decreasing sequences of length n using numbers from
1 to m where every number can be used at most k times. We can recursively compute count
for n using count for n-1.
The idea is to use Dynamic Programming. Declare a 2D array dp[][], where each state dp[i][j]
denotes the number of decreasing sequences of length i using numbers from j to m. We need
to take care of the fact that a number can be used a most k times. This can be done by
considering 1 to k occurrences of a number. Hence our recurrence relation becomes:

Also, we can use the fact that for a fixed j we are using the consecutive values of previous
k values of i. Hence, we can maintain a prefix sum array for each state. Now we have got
rid of the k factor for each state.
Below is the C++ implemantation of this approach:

// CPP program to find number of ways to make stable


// tower of given height.
#include <bits/stdc++.h>
using namespace std;
#define N 100
  
int possibleWays(int n, int m, int k)
{
    int dp[N][N];
    int presum[N][N];
    memset(dp, 0, sizeof dp);
    memset(presum, 0, sizeof presum);
  
    // Initialing 0th row to 0.
    for (int i = 1; i < n + 1; i++) {
        dp[0][i] = 0;
        presum[0][i] = 1;
    }
  
    // Initialing 0th column to 0.
    for (int i = 0; i < m + 1; i++)
        presum[i][0] = dp[i][0] = 1;

2857
Chapter 397. Tile Stacking Problem

  
    // For each row from 1 to m
    for (int i = 1; i < m + 1; i++) {
  
        // For each column from 1 to n.
        for (int j = 1; j < n + 1; j++) {
  
            // Initialing dp[i][j] to presum of (i - 1, j).
            dp[i][j] = presum[i - 1][j];
            if (j > k) {
                dp[i][j] -= presum[i - 1][j - k - 1];
            }
        }
  
        // Calculating presum for each i, 1 <= i <= n.
        for (int j = 1; j < n + 1; j++)
            presum[i][j] = dp[i][j] + presum[i][j - 1];
    }
  
    return dp[m][n];
}
  
// Driver Program
int main()
{
    int n = 3, m = 3, k = 2;
    cout << possibleWays(n, m, k) << endl;
    return 0;
}

Output:

Source

https://www.geeksforgeeks.org/tile-stacking-problem/

2858
Chapter 398

Tiling Problem

Tiling Problem - GeeksforGeeks


Given a “2 x n” board and tiles of size “2 x 1”, count the number of ways to tile the given
board using the 2 x 1 tiles. A tile can either be placed horizontally i.e., as a 1 x 2 tile or
vertically i.e., as 2 x 1 tile.
Examples:

Input n = 3
Output: 3
Explanation:
We need 3 tiles to tile the board of size 2 x 3.
We can tile the board using following ways
1) Place all 3 tiles vertically.
2) Place first tile vertically and remaining 2 tiles horizontally.
3) Place first 2 tiles horizontally and remaining tiles vertically

Input n = 4
Output: 5
Explanation:
For a 2 x 4 board, there are 5 ways
1) All 4 vertical
2) All 4 horizontal
3) First 2 vertical, remaining 2 horizontal
4) First 2 horizontal, remaining 2 vertical
5) Corner 2 vertical, middle 2 horizontal

2859
Chapter 398. Tiling Problem

Let “count(n)” be the count of ways to place tiles on a “2 x n” grid, we have following two
ways to place first tile.
1) If we place first tile vertically, the problem reduces to “count(n-1)”
2) If we place first tile horizontally, we have to place second tile also horizontally. So the
problem reduces to “count(n-2)”
Therefore, count(n) can be written as below.

count(n) = n if n = 1 or n = 2
count(n) = count(n-1) + count(n-2)

The above recurrence is noting but Fibonacci Number expression. We can find n’th Fi-
bonacci number in O(Log n) time, see below for all method to find n’th Fibonacci Number.
Different methods for n’th Fibonacci Number.
Count the number of ways to tile the floor of size n x m using 1 x m size tiles
This article is contributed by Saurabh Jain. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/tiling-problem/

2860
Chapter 399

Tiling with Dominoes

Tiling with Dominoes - GeeksforGeeks


Given a 3 x n board, find the number of ways to fill it with 2 x 1 dominoes.
Example 1
Following are all the 3 possible ways to fill up a 3 x 2 board.

Example 2
Here is one possible way of filling a 3 x 8 board. You have to find all the possible ways to
do so.

Examples :

Input : 2
Output : 3

Input : 8
Output : 153

2861
Chapter 399. Tiling with Dominoes

Input : 12
Output : 2131

Defining Subproblems:
At any point while filling the board, there are three possible states that the last column
can be in:

An = No. of ways to completely fill a 3 x n board. (We need to find this)


Bn = No. of ways to fill a 3 x n board with top corner in last column not filled.
Cn = No. of ways to fill a 3 x n board with bottom corner in last column not filled.

Note: The following states are impossible to reach:

Finding Reccurences
Note: Even though Bn and Cn are different states, they will be equal for same ‘n’. i.e
Bn = Cn
Hence, we only need to calculate one of them.
Calculating An:

2862
Chapter 399. Tiling with Dominoes

Calculating Bn:

Final Recursive Relations are:

Base Cases:

C++

// C++ program to find no. of ways


// to fill a 3xn board with 2x1 dominoes.
#include <iostream>
using namespace std;
  
int countWays(int n)
{
    int A[n + 1], B[n + 1];

2863
Chapter 399. Tiling with Dominoes

    A[0] = 1, A[1] = 0, B[0] = 0, B[1] = 1;


    for (int i = 2; i <= n; i++) {
        A[i] = A[i - 2] + 2 * B[i - 1];
        B[i] = A[i - 1] + B[i - 2];
    }
  
    return A[n];
}
  
int main()
{
    int n = 8;
    cout << countWays(n);
    return 0;
}

Java

// Java program to find no. of ways


// to fill a 3xn board with 2x1 dominoes.
import java.io.*;
  
class GFG {
  
    static int countWays(int n)
    {
        int []A = new int[n+1];
        int []B = new int[n+1];
        A[0] = 1; A[1] = 0;
        B[0] = 0; B[1] = 1;
        for (int i = 2; i <= n; i++) 
        {
            A[i] = A[i - 2] + 2 * B[i - 1];
            B[i] = A[i - 1] + B[i - 2];
        }
      
        return A[n];
    }
  
    // Driver code
    public static void main (String[] args) 
    {
        int n = 8;
        System.out.println(countWays(n));
    }
}
  
// This code is contributed by anuj_67.

2864
Chapter 399. Tiling with Dominoes

Python 3

# Python 3 program to find no. of ways


# to fill a 3xn board with 2x1 dominoes.
  
def countWays(n):
  
    A = [0] * (n + 1)
    B = [0] * (n + 1)
    A[0] = 1
    A[1] = 0
    B[0] = 0
    B[1] = 1
    for i in range(2, n+1):
        A[i] = A[i - 2] + 2 * B[i - 1]
        B[i] = A[i - 1] + B[i - 2]
      
    return A[n]
  
n = 8
print(countWays(n))
  
# This code is contributed by Smitha

C#

// C# program to find no. of ways


// to fill a 3xn board with 2x1 dominoes.
using System;
  
class GFG {
  
    static int countWays(int n)
    {
        int []A = new int[n+1];
        int []B = new int[n+1];
        A[0] = 1; A[1] = 0;
        B[0] = 0; B[1] = 1;
        for (int i = 2; i <= n; i++) 
        {
            A[i] = A[i - 2] + 2 * B[i - 1];
            B[i] = A[i - 1] + B[i - 2];
        }
      
        return A[n];
    }
  

2865
Chapter 399. Tiling with Dominoes

    // Driver code


    public static void Main () 
    {
        int n = 8;
        Console.WriteLine(countWays(n));
    }
}
  
// This code is contributed by anuj_67.

PHP

<?php
// PHP program to find no. of ways
// to fill a 3xn board with 2x1 dominoes.
  
function countWays($n)
{
    $A = array();
    $B = array();
    $A[0] = 1; $A[1] = 0; 
    $B[0] = 0; $B[1] = 1;
    for ( $i = 2; $i <= $n; $i++) 
    {
        $A[$i] = $A[$i - 2] + 2 * 
                 $B[$i - 1];
        $B[$i] = $A[$i - 1] + 
                 $B[$i - 2];
    }
  
    return $A[$n];
}
  
// Driver Code
$n = 8;
echo countWays($n);
  
// This code is contributed by anuj_67.
?>

Output :

153

Improved By : vt_m, Smitha Dinesh Semwal

2866
Chapter 399. Tiling with Dominoes

Source

https://www.geeksforgeeks.org/tiling-with-dominoes/

2867
Chapter 400

Total number of decreasing


paths in a matrix

Total number of decreasing paths in a matrix - GeeksforGeeks


Given a matrix of size N X N of integers. The task is to find the number of decreasing
path in the matrix. You are allowed to start from any cell and from the cell (i, j), you are
allowed to move to (i + 1, j), (i – 1, j), (i, j + 1) and (i, j – 1) cell.
Examples:

Input : m[][] = { { 1, 2 },
{ 1, 3 } }
Output : 8
Explanation : Decreasing paths are { 1 }, { 1 }, { 2 }, { 3 },
{ 2, 1 }, { 3, 1 }, { 3, 2 }, { 3, 2, 1 }

Input : m[][] = { { 1, 2, 3 },
{ 1, 3, 4 },
{ 1, 5, 6 } }
Output : 41

The idea to solve this problem is to use Dynamic Programming. Declare a dp[][] array,
where dp[i][j] stores the number of decreasing path that can be formed from cell
(i, j). So, we will define a recursive function to evaluate the number of decreasing path
with parameters, say i, j, the row number and column number of the current cell. Make
every possible move from the cell(i,j) and keep a count of the total number of paths. First,
we will check in the function that the number of decreasing paths for input position (i, j) is
already calculated or not. If yes, return the value dp[i][j] else find the number of decreasing
sequence in allowed four directions and return the value. Meanwhile, we will also store the

2868
Chapter 400. Total number of decreasing paths in a matrix

number of decreasing for intermediate cells. Since DP[i][j] stores the number of decreasing
paths for every cell, so the summation of all the cells of DP[][] will answer to count of
decreasing paths in the complete matrix.
Below is the implementation of the above approach:

C++

// CPP program to count number


// of decreasing path in a matrix
#include <bits/stdc++.h>
using namespace std;
#define MAX 100
  
// Function that returns the number of
// decreasing paths from a cell(i, j)
int CountDecreasingPathsCell(int mat[MAX][MAX], int dp[MAX][MAX], 
                                              int n, int x, int y)
{
    // checkinf if already calculated
    if (dp[x][y] != -1)
        return dp[x][y];
  
    // all possible paths
    int delta[4][2] = { { 0, 1 }, { 1, 0 }, { -1, 0 }, { 0, -1 } };
    int newx, newy;
  
    // counts the total number of paths
    int ans = 1;
  
    // In all four allowed direction.
    for (int i = 0; i < 4; i++) {
  
        // new co-ordinates
        newx = x + delta[i][0];
        newy = y + delta[i][1];
  
        // Checking if not going out of matrix and next
        // cell value is less than current cell value.
        if (newx >= 0 && newx < n && newy >= 0
            && newy < n && mat[newx][newy] < mat[x][y]) {
            ans += CountDecreasingPathsCell(mat, dp, n, newx, newy);
        }
    }
    // fucntion that returns the answer
    return dp[x][y] = ans;
}
  

2869
Chapter 400. Total number of decreasing paths in a matrix

// Function that counts the total


// decreasing path in the matrix
int countDecreasingPathsMatrix(int n,
                               int mat[MAX][MAX])
{
    int dp[MAX][MAX];
  
    // Initalising dp[][] to -1.
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            dp[i][j] = -1;
  
    int sum = 0;
  
    // Calculating number of decreasing path from each cell.
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            sum += CountDecreasingPathsCell(mat, dp, n, i, j);
  
    return sum;
}
  
// Driver Code
int main()
{
    int n = 2;
  
    int mat[MAX][MAX] = { { 1, 2 }, { 1, 3 } };
    // function call that returns the
    // count of decreasing paths in a matrix
    cout << countDecreasingPathsMatrix(n, mat)
         << endl;
    return 0;
}

Java

// Java program to count number


// of decreasing path in a matrix
import java.util.*;
import java.lang.*;
import java.io.*;
  
class GFG
{
public static Scanner scn = 
      new Scanner(System.in);
  

2870
Chapter 400. Total number of decreasing paths in a matrix

// Function that returns the number of


// decreasing paths from a cell(i, j)
public static int CountDecreasingPathsCell(int mat[][], int dp[][], 
                                           int n, int x, int y)
    {
        // checkinf if already calculated
        if (dp[x][y] != -1)
            return dp[x][y];
      
        // all possible paths
        int delta[][] = { { 0, 1 }, { 1, 0 }, 
                          { -1, 0}, { 0, -1}};
        int newx, newy;
      
        // counts the total
        // number of paths
        int ans = 1;
      
        // In all four allowed direction.
        for (int i = 0; i < 4; i++) 
        {
      
            // new co-ordinates
            newx = x + delta[i][0];
            newy = y + delta[i][1];
      
            // Checking if not going out 
            // of matrix and next cell 
            // value is less than current 
            // cell value.
            if (newx >= 0 && newx < n && newy >= 0 && 
                newy < n && mat[newx][newy] < mat[x][y]) 
            {
                ans += CountDecreasingPathsCell(mat, dp, n, 
                                                newx, newy);
            }
        }
          
        // fucntion that 
        // returns the answer
        return dp[x][y] = ans;
    }
      
// Function that counts the total
// decreasing path in the matrix
public static int countDecreasingPathsMatrix(int n, 
                                             int mat[][])
    {

2871
Chapter 400. Total number of decreasing paths in a matrix

        int dp[][] = new int[n][n];


      
        // Initalising dp[][] to -1.
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                dp[i][j] = -1;
      
        int sum = 0;
      
        // Calculating number of 
        // decreasing path from each cell.
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                sum += CountDecreasingPathsCell(mat, dp, 
                                                n, i, j);
      
        return sum;
    }
  
// Driver Code
public static void main(String[] args) 
{
    int n = 2;
          
    int mat[][]= {{1, 2}, 
                  {1, 3}};
      
    // function call that returns the
    // count of decreasing paths in a matrix
    System.out.println(countDecreasingPathsMatrix(n, mat));
  

}
  
// This code is contributed by khyati grover

C#

// C# program to count number


// of decreasing path in a matrix
using System;
  
class GFG
{
      
// Function that returns 
// the number of decreasing 
// paths from a cell(i, j)

2872
Chapter 400. Total number of decreasing paths in a matrix

public static int CountDecreasingPathsCell(int[,] mat, int[,] dp, 


                                           int n, int x, int y)
{
    // checkinf if already 
    // calculated
    if (dp[x, y] != -1)
        return dp[x, y];
  
    // all possible paths
    int[,] delta = {{0, 1}, {1, 0}, 
                    {-1, 0},{0, -1}};
    int newx, newy;
  
    // counts the total
    // number of paths
    int ans = 1;
  
    // In all four 
    // allowed direction.
    for (int i = 0; i < 4; i++) 
    {
  
        // new co-ordinates
        newx = x + delta[i,0];
        newy = y + delta[i,1];
  
        // Checking if not going out 
        // of matrix and next cell 
        // value is less than current 
        // cell value.
        if (newx >= 0 && newx < n && 
            newy >= 0 && newy < n && 
            mat[newx,newy] < mat[x,y]) 
        {
            ans += CountDecreasingPathsCell(mat, dp, n, 
                                            newx, newy);
        }
    }
      
    // fucntion that 
    // returns the answer
    return dp[x,y] = ans;
}
  
// Function that counts the total
// decreasing path in the matrix
public static int countDecreasingPathsMatrix(int n, 
                                        int[,] mat)

2873
Chapter 400. Total number of decreasing paths in a matrix

{
    int[,] dp = new int[n, n];
  
    // Initalising dp[][] to -1.
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            dp[i, j] = -1;
  
    int sum = 0;
  
    // Calculating number of 
    // decreasing path from each cell.
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            sum += CountDecreasingPathsCell(mat, dp, 
                                            n, i, j);
  
    return sum;
}
  
// Driver code
static public void Main ()
{
    int n = 2;
      
    int[,] mat= {{1, 2}, 
                {1, 3}};
      
    // function call that returns the
    // count of decreasing paths in a matrix
    Console.WriteLine(countDecreasingPathsMatrix(n, mat));
}
}
  
// This code is contributed by vij.

Output:

Time Complexity : O(N2 )


Auxiliary Space : O(N2 )
Improved By : khyatigrover, Mahadev99

2874
Chapter 400. Total number of decreasing paths in a matrix

Source

https://www.geeksforgeeks.org/total-number-of-decreasing-paths-in-a-matrix/

2875
Chapter 401

Total number of non-decreasing


numbers with n digits

Total number of non-decreasing numbers with n digits - GeeksforGeeks


A number is non-decreasing if every digit (except the first one) is greater than or equal to
previous digit. For example, 223, 4455567, 899, are non-decreasing numbers.
So, given the number of digits n, you are required to find the count of total non-decreasing
numbers with n digits.
Examples:

Input: n = 1
Output: count = 10

Input: n = 2
Output: count = 55

Input: n = 3
Output: count = 220

We strongly recommend you to minimize your browser and try this yourself
first.
One way to look at the problem is, count of numbers is equal to count n digit number ending
with 9 plus count of ending with digit 8 plus count for 7 and so on. How to get count ending
with a particular digit? We can recur for n-1 length and digits smaller than or equal to the
last digit. So below is recursive formula.

Count of n digit numbers = (Count of (n-1) digit numbers Ending with digit 9) +
(Count of (n-1) digit numbers Ending with digit 8) +

2876
Chapter 401. Total number of non-decreasing numbers with n digits

.............................................+
.............................................+
(Count of (n-1) digit numbers Ending with digit 0)

Let count ending with digit ‘d’ and length n be count(n, d)

count(n, d) = �(count(n-1, i)) where i varies from 0 to d

Total count = �count(n-1, d) where d varies from 0 to n-1

The above recursive solution is going to have many overlapping subproblems. Therefore, we
can use Dynamic Programming to build a table in bottom up manner.
Below is the implementation of above idea :
C++

// C++ program to count non-decreasing number with n digits


#include<bits/stdc++.h>
using namespace std;
  
long long int countNonDecreasing(int n)
{
    // dp[i][j] contains total count of non decreasing
    // numbers ending with digit i and of length j
    long long int dp[10][n+1];
    memset(dp, 0, sizeof dp);
  
    // Fill table for non decreasing numbers of length 1
    // Base cases 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
    for (int i = 0; i < 10; i++)
        dp[i][1] = 1;
  
    // Fill the table in bottom-up manner
    for (int digit = 0; digit <= 9; digit++)
    {
        // Compute total numbers of non decreasing
        // numbers of length 'len'
        for (int len = 2; len <= n; len++)
        {
            // sum of all numbers of length of len-1
            // in which last digit x is <= 'digit'
            for (int x = 0; x <= digit; x++)
                dp[digit][len] += dp[x][len-1];
        }
    }
  
    long long int count = 0;

2877
Chapter 401. Total number of non-decreasing numbers with n digits

  
    // There total nondecreasing numbers of length n
    // wiint be dp[0][n] +  dp[1][n] ..+ dp[9][n]
    for (int i = 0; i < 10; i++)
        count += dp[i][n];
  
    return count;
}
  
// Driver program
int main()
{
    int n = 3;
    cout << countNonDecreasing(n);
    return 0;
}

Java

class NDN
{
    static int countNonDecreasing(int n)
    {
        // dp[i][j] contains total count of non decreasing
        // numbers ending with digit i and of length j
        int dp[][] = new int[10][n+1];
       
        // Fill table for non decreasing numbers of length 1
        // Base cases 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
        for (int i = 0; i < 10; i++)
            dp[i][1] = 1;
       
        // Fill the table in bottom-up manner
        for (int digit = 0; digit <= 9; digit++)
        {
            // Compute total numbers of non decreasing
            // numbers of length 'len'
            for (int len = 2; len <= n; len++)
            {
                // sum of all numbers of length of len-1
                // in which last digit x is <= 'digit'
                for (int x = 0; x <= digit; x++)
                    dp[digit][len] += dp[x][len-1];
            }
        }
       
        int count = 0;
       

2878
Chapter 401. Total number of non-decreasing numbers with n digits

        // There total nondecreasing numbers of length n


        // wiint be dp[0][n] +  dp[1][n] ..+ dp[9][n]
        for (int i = 0; i < 10; i++)
            count += dp[i][n];
       
        return count;
    }
    public static void main(String args[])
    {
       int n = 3;
       System.out.println(countNonDecreasing(n));
    }
}/* This code is contributed by Rajat Mishra */

C#

// C# program to print sum 


// triangle for a given array
using System;
  
class GFG {
      
    static int countNonDecreasing(int n)
    {
        // dp[i][j] contains total count
        // of non decreasing numbers ending
        // with digit i and of length j
        int [,]dp = new int[10,n + 1];
      
        // Fill table for non decreasing
        // numbers of length 1 Base cases 
        // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
        for (int i = 0; i < 10; i++)
            dp[i, 1] = 1;
      
        // Fill the table in bottom-up manner
        for (int digit = 0; digit <= 9; digit++)
        {
              
            // Compute total numbers of non decreasing
            // numbers of length 'len'
            for (int len = 2; len <= n; len++)
            {
                  
                // sum of all numbers of length of len-1
                // in which last digit x is <= 'digit'
                for (int x = 0; x <= digit; x++)
                    dp[digit, len] += dp[x, len - 1];

2879
Chapter 401. Total number of non-decreasing numbers with n digits

            }
        }
      
        int count = 0;
      
        // There total nondecreasing numbers
        // of length n wiint be dp[0][n]
        // + dp[1][n] ..+ dp[9][n]
        for (int i = 0; i < 10; i++)
            count += dp[i, n];
      
        return count;
    }
      
    // Driver code
    public static void Main()
    {
        int n = 3;
        Console.WriteLine(countNonDecreasing(n));
    }
}
  
// This code is contributed by Sam007.

Output:

220

Thanks to Gaurav Ahirwar for suggesting above method.


Another method is based on below direct formula

Count of non-decreasing numbers with n digits =


N*(N+1)/2*(N+2)/3* ....*(N+n-1)/n
Where N = 10

Below is the program to compute count using above formula.

C++

// C++ program to count non-decreasing numner with n digits


#include<bits/stdc++.h>
using namespace std;
  
long long int countNonDecreasing(int n)

2880
Chapter 401. Total number of non-decreasing numbers with n digits

{
    int N = 10;
  
    // Compute value of N*(N+1)/2*(N+2)/3* ....*(N+n-1)/n
    long long count = 1;
    for (int i=1; i<=n; i++)
    {
        count *= (N+i-1);
        count /= i;
    }
  
    return count;
}
  
// Driver program
int main()
{
    int n = 3;
    cout << countNonDecreasing(n);
    return 0;
}

Java

// java program to count non-decreasing


// numner with n digits
public class GFG {
      
    static long countNonDecreasing(int n)
    {
        int N = 10;
       
        // Compute value of N * (N+1)/2 *
        // (N+2)/3 * ....* (N+n-1)/n
        long count = 1;
           
        for (int i = 1; i <= n; i++)
        {
            count *= (N + i - 1);
            count /= i;
        }
       
        return count;
    }
  
    // Driver code
    public static void main(String args[]) {
          

2881
Chapter 401. Total number of non-decreasing numbers with n digits

        int n = 3;
        System.out.print(countNonDecreasing(n));
    }   
}
  
// This code is contributed by Sam007.

Python3

# python program to count non-decreasing


# numner with n digits
  
def countNonDecreasing(n):
    N = 10
  
    # Compute value of N*(N+1)/2*(N+2)/3
    # * ....*(N+n-1)/n
    count = 1
    for i in range(1, n+1):
        count = int(count * (N+i-1))
        count = int(count / i )
          
    return count
  
# Driver program
n = 3;
print(countNonDecreasing(n))
      
# This code is contributed by Sam007

C#

// C# program to count non-decreasing


// numner with n digits
using System;
  
class GFG {
      
    static long countNonDecreasing(int n)
    {
        int N = 10;
      
        // Compute value of N * (N+1)/2 *
        // (N+2)/3 * ....* (N+n-1)/n
        long count = 1;
          
        for (int i = 1; i <= n; i++)

2882
Chapter 401. Total number of non-decreasing numbers with n digits

        {
            count *= (N + i - 1);
            count /= i;
        }
      
        return count;
    }
  
      
    public static void Main()
    {
        int n = 3;
          
        Console.WriteLine(countNonDecreasing(n));
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP program to count non-decreasing
// numner with n digits
  
function countNonDecreasing($n)
{
    $N = 10;
  
    // Compute value of N*(N+1)/2*(N+2)/3* ...
    // ....*(N+n-1)/n
    $count = 1;
    for ($i = 1; $i <= $n; $i++)
    {
        $count *= ($N + $i - 1);
        $count /= $i;
    }
  
    return $count;
}
  
    // Driver Code
    $n = 3;
    echo countNonDecreasing($n);
      
// This code is contributed by Sam007
?>

2883
Chapter 401. Total number of non-decreasing numbers with n digits

Output:

220

Thanks to Abhishek Somani for suggesting this method.


How does this formula work?

N * (N+1)/2 * (N+2)/3 * .... * (N+n-1)/n


Where N = 10

Let us try for different values of n.

For n = 1, the value is N from formula.


Which is true as for n = 1, we have all single digit
numbers, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9.

For n = 2, the value is N(N+1)/2 from formula


We can have N numbers beginning with 0, (N-1) numbers
beginning with 1, and so on.
So sum is N + (N-1) + .... + 1 = N(N+1)/2

For n = 3, the value is N(N+1)/2(N+2)/3 from formula


We can have N(N+1)/2 numbers beginning with 0, (N-1)N/2
numbers beginning with 1 (Note that when we begin with 1,
we have N-1 digits left to consider for remaining places),
(N-2)(N-1)/2 beginning with 2, and so on.
Count = N(N+1)/2 + (N-1)N/2 + (N-2)(N-1)/2 +
(N-3)(N-2)/2 .... 3 + 1
[Combining first 2 terms, next 2 terms and so on]
= 1/2[N2 + (N-2)2 + .... 4]
= N*(N+1)*(N+2)/6 [Refer this , putting n=N/2 in the
even sum formula]

For general n digit case, we can apply Mathematical Induction. The count would be equal
to count n-1 digit beginning with 0, i.e., N*(N+1)/2*(N+2)/3* ….*(N+n-1-1)/(n-1). Plus
count of n-1 digit numbers beginning with 1, i.e., (N-1)*(N)/2*(N+1)/3* ….*(N-1+n-1-
1)/(n-1) (Note that N is replaced by N-1) and so on.
Improved By : Sam007

Source

https://www.geeksforgeeks.org/total-number-of-non-decreasing-numbers-with-n-digits/

2884
Chapter 402

Total number of possible Binary


Search Trees and Binary Trees
with n keys

Total number of possible Binary Search Trees and Binary Trees with n keys - GeeksforGeeks
Total number of possible Binary Search Trees with n different keys (countBST(n)) = Catalan
number Cn = (2n)!/(n+1)!*n!
For n = 0, 1, 2, 3, … values of Catalan numbers are 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862,
…. So are numbers of Binary Search Trees.
Total number of possible Binary Trees with n different keys (countBT(n)) = countBST(n)
* n!
Below is code for finding count of BSTs and Binary Trees with n numbers. The code to find
n’th Catalan number is taken from here.
C++

// See https://www.geeksforgeeks.org/program-nth-catalan-number/
// for reference of below code.
  
#include <bits/stdc++.h>
using namespace std;
  
// A function to find factorial of a given number
unsigned long int factorial(unsigned int n)
{
    unsigned long int res = 1;
  
    // Calculate value of [1*(2)*---*(n-k+1)] / [k*(k-1)*---*1]
    for (int i = 1; i <= n; ++i)

2885
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

    {
        res *= i;
    }
  
    return res;
}
  
unsigned long int binomialCoeff(unsigned int n, unsigned int k)
{
    unsigned long int res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if (k > n - k)
        k = n - k;
  
    // Calculate value of [n*(n-1)*---*(n-k+1)] / [k*(k-1)*---*1]
    for (int i = 0; i < k; ++i)
    {
        res *= (n - i);
        res /= (i + 1);
    }
  
    return res;
}
  
  
// A Binomial coefficient based function to find nth catalan
// number in O(n) time
unsigned long int catalan(unsigned int n)
{
    // Calculate value of 2nCn
    unsigned long int c = binomialCoeff(2*n, n);
  
    // return 2nCn/(n+1)
    return c/(n+1);
}
  
// A function to count number of BST with n nodes 
// using catalan
unsigned long int countBST(unsigned int n)
{
    // find nth catalan number
    unsigned long int count = catalan(n);
  
    // return nth catalan number
    return count;
}
  

2886
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

// A function to count number of binary trees with n nodes 


unsigned long int countBT(unsigned int n)
{
    // find count of BST with n numbers
    unsigned long int count = catalan(n);
  
    // return count * n!
    return count * factorial(n);
}
  
// Driver Program to test above functions
int main()
{
  
    int count1,count2, n = 5;
  
    // find count of BST and binary trees with n nodes
        count1 = countBST(n);
        count2 = countBT(n); 
      
    // print count of BST and binary trees with n nodes
    cout<<"Count of BST with "<<n<<" nodes is "<<count1<<endl;
        cout<<"Count of binary trees with "<<n<<" nodes is "<<count2;
  
    return 0;
}

Java

// See https://www.geeksforgeeks.org/program-nth-catalan-number/
// for reference of below code.
import java.io.*;
  
class GFG 
{
      
// A function to find 
// factorial of a given number
static int factorial(int n)
{
    int res = 1;
  
    // Calculate value of 
    // [1*(2)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for (int i = 1; i <= n; ++i)
    {
        res *= i;

2887
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

    }
  
    return res;
}
  
static int binomialCoeff(int n,
                         int k)
{
    int res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if (k > n - k)
        k = n - k;
  
    // Calculate value of 
    // [n*(n-1)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for (int i = 0; i < k; ++i)
    {
        res *= (n - i);
        res /= (i + 1);
    }
  
    return res;
}
  
  
// A Binomial coefficient 
// based function to find 
// nth catalan number in 
// O(n) time
static int catalan( int n)
{
      
    // Calculate value of 2nCn
    int c = binomialCoeff(2 * n, n);
  
    // return 2nCn/(n+1)
    return c / (n + 1);
}
  
// A function to count number of
// BST with n nodes using catalan
static int countBST( int n)
{
    // find nth catalan number
    int count = catalan(n);
  

2888
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

    // return nth catalan number


    return count;
}
  
// A function to count number
// of binary trees with n nodes 
static int countBT(int n)
{
    // find count of BST
    // with n numbers
    int count = catalan(n);
  
    // return count * n!
    return count * factorial(n);
}
  
// Driver Code
public static void main (String[] args)
{
    int count1, count2, n = 5;
  
    // find count of BST and 
    // binary trees with n nodes
    count1 = countBST(n);
    count2 = countBT(n); 
  
    // print count of BST and 
    // binary trees with n nodes
    System.out.println("Count of BST with "+ 
                            n +" nodes is "+ 
                                    count1);
    System.out.println("Count of binary " + 
                             "trees with "+ 
                         n + " nodes is " + 
                                   count2);
}
}
  
// This code is contributed by ajit

C#

// See https://www.geeksforgeeks.org/program-nth-catalan-number/
// for reference of below code.
using System;
  
class GFG
{

2889
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

      
// A function to find 
// factorial of a given number
static int factorial(int n)
{
    int res = 1;
  
    // Calculate value of 
    // [1*(2)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for (int i = 1; i <= n; ++i)
    {
        res *= i;
    }
  
    return res;
}
  
static int binomialCoeff(int n,
                         int k)
{
    int res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if (k > n - k)
        k = n - k;
  
    // Calculate value of 
    // [n*(n-1)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for (int i = 0; i < k; ++i)
    {
        res *= (n - i);
        res /= (i + 1);
    }
  
    return res;
}
  
// A Binomial coefficient 
// based function to find 
// nth catalan number in 
// O(n) time
static int catalan(int n)
{
      
    // Calculate value
    // of 2nCn

2890
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

    int c = binomialCoeff(2 * n, n);


  
    // return 2nCn/(n+1)
    return c / (n + 1);
}
  
// A function to count 
// number of BST with 
// n nodes using catalan
static int countBST(int n)
{
    // find nth catalan number
    int count = catalan(n);
  
    // return nth catalan number
    return count;
}
  
// A function to count number
// of binary trees with n nodes 
static int countBT(int n)
{
    // find count of BST
    // with n numbers
    int count = catalan(n);
  
    // return count * n!
    return count * factorial(n);
}
  
// Driver Code
static public void Main ()
{
    int count1, count2, n = 5;
      
    // find count of BST  
    // and binary trees 
    // with n nodes
    count1 = countBST(n);
    count2 = countBT(n); 
      
    // print count of BST and 
    // binary trees with n nodes
    Console.WriteLine("Count of BST with "+ 
                           n +" nodes is "+ 
                                   count1);
    Console.WriteLine("Count of binary " + 
                            "trees with "+ 

2891
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

                        n + " nodes is " + 


                                   count2);
    }
}
  
// This code is contributed
// by akt_mit

PHP

<?php
// See https://www.geeksforgeeks.org/program-nth-catalan-number/
// for reference of below code.
// A function to find factorial
// of a given number
function factorial($n)
{
    $res = 1;
  
    // Calculate value of
    // [1*(2)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for ($i = 1; $i <= $n; ++$i)
    {
        $res *= $i;
    }
  
    return $res;
}
  
function binomialCoeff($n, $k)
{
    $res = 1;
  
    // Since C(n, k) = C(n, n-k)
    if ($k > $n - $k)
        $k = $n - $k;
  
    // Calculate value of 
    // [n*(n-1)*---*(n-k+1)] / 
    // [k*(k-1)*---*1]
    for ($i = 0; $i < $k; ++$i)
    {
        $res *= ($n - $i);
        $res = (int)$res / ($i + 1);
    }
  
    return $res;

2892
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

}
  
// A Binomial coefficient 
// based function to find 
// nth catalan number in
// O(n) time
function catalan($n)
{
    // Calculate value of 2nCn
    $c = binomialCoeff(2 * $n, $n);
  
    // return 2nCn/(n+1)
    return (int)$c / ($n + 1);
}
  
// A function to count
// number of BST with 
// n nodes using catalan
function countBST($n)
{
    // find nth catalan number
    $count = catalan($n);
  
    // return nth 
    // catalan number
    return $count;
}
  
// A function to count 
// number of binary 
// trees with n nodes 
function countBT($n)
{
    // find count of 
    // BST with n numbers
    $count = catalan($n);
  
    // return count * n!
    return $count * 
           factorial($n);
}
  
// Driver Code
$count1;
$count2;
$n = 5;
  
// find count of BST and 

2893
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

// binary trees with n nodes


$count1 = countBST($n);
$count2 = countBT($n); 
  
// print count of BST and 
// binary trees with n nodes
echo "Count of BST with " , $n ,
     " nodes is ", $count1,"\n";
       
echo "Count of binary trees with " , 
           $n ," nodes is ",$count2;
  
// This code is contributed by ajit
?>

Output:

Count of BST with 5 nodes is 42


Count of binary trees with 5 nodes is 5040

Proof of Enumeration
Consider all possible binary search trees with each element at the root. If there are n nodes,
then for each choice of root node, there are n – 1 non-root nodes and these non-root nodes
must be partitioned into those that are less than a chosen root and those that are greater
than the chosen root.
Let’s say node i is chosen to be the root. Then there are i – 1 nodes smaller than i and n
– i nodes bigger than i. For each of these two sets of nodes, there is a certain number of
possible subtrees.
Let t(n) be the total number of BSTs with n nodes. The total number of BSTs with i at the
root is t(i – 1) t(n – i). The two terms are multiplied together because the arrangements in
the left and right subtrees are independent. That is, for each arrangement in the left tree
and for each arrangement in the right tree, you get one BST with i at the root.
Summing over i gives the total number of binary search trees with n nodes.

The base case is t(0) = 1 and t(1) = 1, i.e. there is one empty BST and there is one BST
with one node.

2894
Chapter 402. Total number of possible Binary Search Trees and Binary Trees with n keys

Also, the relationship countBT(n) = countBST(n) * n! holds. As for every possible BST,
there can have n! binary trees where n is the number of nodes in BST.
Improved By : jit_t

Source

https://www.geeksforgeeks.org/total-number-of-possible-binary-search-trees-with-n-keys/

2895
Chapter 403

Travelling Salesman Problem |


Set 1 (Naive and Dynamic
Programming)

Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming) - GeeksforGeeks


Travelling Salesman Problem (TSP): Given a set of cities and distance between every
pair of cities, the problem is to find the shortest possible route that visits every city exactly
once and returns to the starting point.
Note the difference between Hamiltonian Cycle and TSP. The Hamiltoninan cycle problem
is to find if there exist a tour that visits every city exactly once. Here we know that
Hamiltonian Tour exists (because the graph is complete) and in fact many such tours exist,
the problem is to find a minimum weight Hamiltonian Cycle.

For example, consider the graph shown in figure on right side. A TSP tour in the graph is
1-2-4-3-1. The cost of the tour is 10+25+30+15 which is 80.
The problem is a famous NP hardproblem. There is no polynomial time know solution for
this problem.
Following are different solutions for the traveling salesman problem.

2896
Chapter 403. Travelling Salesman Problem | Set 1 (Naive and Dynamic Programming)

Naive Solution:
1) Consider city 1 as the starting and ending point.
2) Generate all (n-1)! Permutationsof cities.
3) Calculate cost of every permutation and keep track of minimum cost permutation.
4) Return the permutation with minimum cost.
Time Complexity: Θ(n!)
Dynamic Programming:
Let the given set of vertices be {1, 2, 3, 4,….n}. Let us consider 1 as starting and ending
point of output. For every other vertex i (other than 1), we find the minimum cost path
with 1 as the starting point, i as the ending point and all vertices appearing exactly once.
Let the cost of this path be cost(i), the cost of corresponding Cycle would be cost(i) + dist(i,
1) where dist(i, 1) is the distance from i to 1. Finally, we return the minimum of all [cost(i)
+ dist(i, 1)] values. This looks simple so far. Now the question is how to get cost(i)?
To calculate cost(i) using Dynamic Programming, we need to have some recursive relation
in terms of sub-problems. Let us define a term C(S, i) be the cost of the minimum cost path
visiting each vertex in set S exactly once, starting at 1 and ending at i.
We start with all subsets of size 2 and calculate C(S, i) for all subsets where S is the subset,
then we calculate C(S, i) for all subsets S of size 3 and so on. Note that 1 must be present
in every subset.

If size of S is 2, then S must be {1, i},


C(S, i) = dist(1, i)
Else if size of S is greater than 2.
C(S, i) = min { C(S-{i}, j) + dis(j, i)} where j belongs to S, j != i and j != 1.

For a set of size n, we consider n-2 subsets each of size n-1 such that all subsets don’t have
nth in them.
Using the above recurrence relation, we can write dynamic programming based solution.
There are at most O(n*2n ) subproblems, and each one takes linear time to solve. The total
running time is therefore O(n2 *2n ). The time complexity is much less than O(n!), but still
exponential. Space required is also exponential. So this approach is also infeasible even for
slightly higher number of vertices.
We will soon be discussing approximate algorithms for travelling salesman problem.
Next Article: Traveling Salesman Problem | Set 2
References:
http://www.lsi.upc.edu/~mjserna/docencia/algofib/P07/dynprog.pdf
http://www.cs.berkeley.edu/~vazirani/algorithms/chap6.pdf

Source

https://www.geeksforgeeks.org/travelling-salesman-problem-set-1/

2897
Chapter 404

Traversal of tree with k jumps


allowed between nodes of same
height

Traversal of tree with k jumps allowed between nodes of same height - GeeksforGeeks
Consider a tree with n nodes and root. You can jump from one node to any other node on
the same height a maximum of k times on total jumps. Certain nodes of the tree contain a
fruit, find out the maximum number of fruits he can collect.
Example :

Input Tree :
Number of Nodes = 12
Number of jumps allowed : 2
Edges:
1 2
1 3
2 4
2 5
5 9
9 10
9 11
11 12
1 3
3 7
7 6
7 8
Nodes Containing Fruits : 2 4 5 7 8 9 11 12
Output: 7

2898
Chapter 404. Traversal of tree with k jumps allowed between nodes of same height

Tree for above testcase :

Explanation:

2899
Chapter 404. Traversal of tree with k jumps allowed between nodes of same height

Approach: The idea is to use DFS to create a Height Adjacency List of the Nodes and to
store the parents. Then use another dfs to compute the maximum no of special nodes that
can be reached using the following dp state:

dp[current_node][j] = max( max{ dp[child_i][j], for all children of current_node },


max{ dp[node_at_same_height_i][j - 1],
for all nodes at same height as current_node} )

Thus, dp[Root_Node][Total_no_of_Jumps] gives the answer to the problem.


Below is the implementation of above approach :

// Program to demonstrate tree traversal with


// ability to jump between nodes of same height
#include <bits/stdc++.h>
using namespace std;
  
#define N 1000
  
vector<int> H[N];
  
// Arrays declaration

2900
Chapter 404. Traversal of tree with k jumps allowed between nodes of same height

int Fruit[N];
int Parent[N];
int dp[N][20];
  
// Function for DFS
void dfs1(vector<int> tree[], int s,
          int p, int h)
{
    Parent[s] = p;
    int i;
    H[h].push_back(s);
    for (i = 0; i < tree[s].size(); i++) {
        int v = tree[s][i];
        if (v != p)
            dfs1(tree, v, s, h + 1);
    }
}
  
// Function for DFS
int dfs2(vector<int> tree[], int s,
         int p, int h, int j)
{
    int i;
    int ans = 0;
    if (dp[s][j] != -1)
        return dp[s][j];
  
    // jump
    if (j > 0) {
        for (i = 0; i < H[h].size(); i++) {
            int v = H[h][i];
            if (v != s)
                ans = max(ans, dfs2(tree, v,
                        Parent[v], h, j - 1));
        }
    }
  
    // climb
    for (i = 0; i < tree[s].size(); i++) {
        int v = tree[s][i];
        if (v != p)
            ans = max(ans, dfs2(tree, v, s, h + 1, j));
    }
  
    if (Fruit[s] == 1)
        ans++;
    dp[s][j] = ans;
  

2901
Chapter 404. Traversal of tree with k jumps allowed between nodes of same height

    return ans;
}
  
// Function to calculate and
// return maximum number of fruits
int maxFruit(vector<int> tree[],
             int NodesWithFruits[],
             int n, int m, int k)
{
    // reseting dp table and Fruit array
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < 20; j++)
            dp[i][j] = -1;
        Fruit[i] = 0;
    }
  
    // This array is used to mark
    // which nodes contain Fruits
    for (int i = 0; i < m; i++)
        Fruit[NodesWithFruits[i]] = 1;
  
    dfs1(tree, 1, 0, 0);
    int ans = dfs2(tree, 1, 0, 0, k);
  
    return ans;
}
  
// Function to add Edge
void addEdge(vector<int> tree[], int u, int v)
{
    tree[u].push_back(v);
    tree[v].push_back(u);
}
  
// Driver Code
int main()
{
    int n = 12; // Number of nodes
    int k = 2; // Number of allowed jumps
  
    vector<int> tree[N];
  
    // Edges
    addEdge(tree, 1, 2);
    addEdge(tree, 1, 3);
    addEdge(tree, 2, 4);
    addEdge(tree, 2, 5);
    addEdge(tree, 5, 9);

2902
Chapter 404. Traversal of tree with k jumps allowed between nodes of same height

    addEdge(tree, 9, 10);
    addEdge(tree, 9, 11);
    addEdge(tree, 11, 12);
    addEdge(tree, 1, 3);
    addEdge(tree, 3, 7);
    addEdge(tree, 7, 6);
    addEdge(tree, 7, 8);
  
    int NodesWithFruits[] = { 2, 4, 5, 7, 8, 9, 11, 12 };
  
    // Number of nodes with fruits
    int m = sizeof(NodesWithFruits) / sizeof(NodesWithFruits[0]);
  
    int ans = maxFruit(tree, NodesWithFruits, n, m, k);
  
    cout << ans << endl;
  
    return 0;
}

Output:

Time Complexity : O(n*n*k) (worst case, eg: 2 level tree with the root having n-1 child
nodes)

Source

https://www.geeksforgeeks.org/traversal-tree-ability-jump-nodes-height/

2903
Chapter 405

Ugly Numbers

Ugly Numbers - GeeksforGeeks


Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4,
5, 6, 8, 9, 10, 12, 15, … shows the first 11 ugly numbers. By convention, 1 is included.
Given a number n, the task is to find n’th Ugly number.
Examples:

Input : n = 7
Output : 8

Input : n = 10
Output : 12

Input : n = 15
Output : 24

Input : n = 150
Output : 5832

Method 1 (Simple)
Loop for all positive integers until ugly number count is smaller than n, if an integer is ugly
than increment ugly number count.
To check if a number is ugly, divide the number by greatest divisible powers of 2, 3 and 5,
if the number becomes 1 then it is an ugly number otherwise not.
For example, let us see how to check for 300 is ugly or not. Greatest divisible power of 2 is
4, after dividing 300 by 4 we get 75. Greatest divisible power of 3 is 3, after dividing 75 by
3 we get 25. Greatest divisible power of 5 is 25, after dividing 25 by 25 we get 1. Since we
get 1 finally, 300 is ugly number.

2904
Chapter 405. Ugly Numbers

Implementation:

C/C++

// CPP program to find nth ugly number


# include<stdio.h>
# include<stdlib.h>
  
/*This function divides a by greatest divisible 
  power of b*/
int maxDivide(int a, int b)
{
  while (a%b == 0)
   a = a/b; 
  return a;
}    
  
/* Function to check if a number is ugly or not */
int isUgly(int no)
{
  no = maxDivide(no, 2);
  no = maxDivide(no, 3);
  no = maxDivide(no, 5);
    
  return (no == 1)? 1 : 0;
}    
  
/* Function to get the nth ugly number*/
int getNthUglyNo(int n)
{
  int i = 1; 
  int count = 1;   /* ugly number count */ 
  
  /*Check for all integers untill ugly count 
    becomes n*/ 
  while (n > count)
  {
    i++;      
    if (isUgly(i))
      count++; 
  }
  return i;
}
  
/* Driver program to test above functions */
int main()
{
    unsigned no = getNthUglyNo(150);

2905
Chapter 405. Ugly Numbers

    printf("150th ugly no. is %d ",  no);


    getchar();
    return 0;
}

Java

// Java program to find nth ugly number


class GFG {
      
    /*This function divides a by greatest
    divisible power of b*/
    static int maxDivide(int a, int b)
    {
        while(a % b == 0)
            a = a/b;
        return a;
    }
      
    /* Function to check if a number 
    is ugly or not */
    static int isUgly(int no)
    {
        no = maxDivide(no, 2);
        no = maxDivide(no, 3);
        no = maxDivide(no, 5);
          
        return (no == 1)? 1 : 0;
    }
      
    /* Function to get the nth ugly 
    number*/
    static int getNthUglyNo(int n)
    {
        int i = 1;
          
        // ugly number count 
        int count = 1; 
          
        // check for all integers 
        // until count becomes n 
        while(n > count)
        {
            i++;
            if(isUgly(i) == 1)
                count++;
        }
        return i;

2906
Chapter 405. Ugly Numbers

    }
      
    /* Driver program to test above
    functions */
    public static void main(String args[])
    {
        int no = getNthUglyNo(150);
        System.out.println("150th ugly "
                       + "no. is "+ no);
    }
}
  
// This code has been contributed by 
// Amit Khandelwal (Amit Khandelwal 1)

Python3

# Python3 code to find nth ugly number


  
# This function divides a by greatest 
# divisible power of b
def maxDivide( a, b ):
    while a % b == 0:
        a = a / b
    return a 
  
# Function to check if a number 
# is ugly or not
def isUgly( no ):
    no = maxDivide(no, 2)
    no = maxDivide(no, 3)
    no = maxDivide(no, 5)
    return 1 if no == 1 else 0
  
# Function to get the nth ugly number
def getNthUglyNo( n ):
    i = 1
    count = 1 # ugly number count
  
    # Check for all integers untill 
    # ugly count becomes n
    while n > count:
        i += 1
        if isUgly(i):
            count += 1
    return i
  
# Driver code to test above functions

2907
Chapter 405. Ugly Numbers

no = getNthUglyNo(150)
print("150th ugly no. is ", no)
  
# This code is contributed by "Sharad_Bhardwaj".

C#

// C# program to find nth ugly number


using System;
  
class GFG {
  
    /*This function divides a by 
    greatest divisible power of b*/
    static int maxDivide(int a, int b)
    {
        while(a % b == 0)
            a = a / b;
        return a;
    }
      
    /* Function to check if a number 
    is ugly or not */
    static int isUgly(int no)
    {
        no = maxDivide(no, 2);
        no = maxDivide(no, 3);
        no = maxDivide(no, 5);
          
        return (no == 1)? 1 : 0;
    }
      
    /* Function to get the nth ugly
    number*/
    static int getNthUglyNo(int n)
    {
        int i = 1;
          
        // ugly number count 
        int count = 1; 
          
        // check for all integers
        // until count becomes n 
        while(n > count)
        {
            i++;
            if(isUgly(i) == 1)
                count++;

2908
Chapter 405. Ugly Numbers

        }
        return i;
    }
      
    // Driver code
    public static void Main()
    {
        int no = getNthUglyNo(150);
          
        Console.WriteLine("150th ugly"
                  + " no. is " + no);
    }
}
  
// This code is contributed by Sam007.

PHP

<?php
// PHP program to find nth ugly number
  
// This function divides a by 
// greatest divisible power of b
function maxDivide($a, $b)
{
    while ($a % $b == 0)
    $a = $a / $b; 
    return $a;

  
// Function to check if a 
// number is ugly or not 
function isUgly($no)
{
    $no = maxDivide($no, 2);
    $no = maxDivide($no, 3);
    $no = maxDivide($no, 5);
      
    return ($no == 1)? 1 : 0;

  
// Function to get the nth
// ugly number
function getNthUglyNo($n)
{
    $i = 1; 
      
    // ugly number count

2909
Chapter 405. Ugly Numbers

    $count = 1; 
  
// Check for all integers 
// untill ugly count becomes n
while ($n > $count)
{
    $i++;     
    if (isUgly($i))
    $count++; 
}
return $i;
}
  
    // Driver Code
    $no = getNthUglyNo(150);
    echo "150th ugly no. is ". $no;
  
// This code is contributed by Sam007
?>

Output:

150th ugly no. is 5832

This method is not time efficient as it checks for all integers until ugly number count becomes
n, but space complexity of this method is O(1)

Method 2 (Use Dynamic Programming)


Here is a time efficient solution with O(n) extra space. The ugly-number sequence is 1, 2,
3, 4, 5, 6, 8, 9, 10, 12, 15, …
because every number can only be divided by 2, 3, 5, one way to look at the sequence
is to split the sequence to three groups as below:
(1) 1×2, 2×2, 3×2, 4×2, 5×2, …
(2) 1×3, 2×3, 3×3, 4×3, 5×3, …
(3) 1×5, 2×5, 3×5, 4×5, 5×5, …
We can find that every subsequence is the ugly-sequence itself (1, 2, 3, 4, 5, …) multiply
2, 3, 5. Then we use similar merge method as merge sort, to get every ugly number from
the three subsequence. Every step we choose the smallest one, and move one step after.

1 Declare an array for ugly numbers: ugly[n]


2 Initialize first ugly no: ugly[0] = 1
3 Initialize three array index variables i2, i3, i5 to point to
1st element of the ugly array:
i2 = i3 = i5 =0;
4 Initialize 3 choices for the next ugly no:

2910
Chapter 405. Ugly Numbers

next_mulitple_of_2 = ugly[i2]*2;
next_mulitple_of_3 = ugly[i3]*3
next_mulitple_of_5 = ugly[i5]*5;
5 Now go in a loop to fill all ugly numbers till 150:
For (i = 1; i < 150; i++ )
{
/* These small steps are not optimized for good
readability. Will optimize them in C program */
next_ugly_no = Min(next_mulitple_of_2,
next_mulitple_of_3,
next_mulitple_of_5);

ugly[i] = next_ugly_no

if (next_ugly_no == next_mulitple_of_2)
{
i2 = i2 + 1;
next_mulitple_of_2 = ugly[i2]*2;
}
if (next_ugly_no == next_mulitple_of_3)
{
i3 = i3 + 1;
next_mulitple_of_3 = ugly[i3]*3;
}
if (next_ugly_no == next_mulitple_of_5)
{
i5 = i5 + 1;
next_mulitple_of_5 = ugly[i5]*5;
}

}/* end of for loop */


6.return next_ugly_no

Example:
Let us see how it works

initialize
ugly[] = | 1 |
i2 = i3 = i5 = 0;

First iteration
ugly[1] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(2, 3, 5)
= 2
ugly[] = | 1 | 2 |
i2 = 1, i3 = i5 = 0 (i2 got incremented )

2911
Chapter 405. Ugly Numbers

Second iteration
ugly[2] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 3, 5)
= 3
ugly[] = | 1 | 2 | 3 |
i2 = 1, i3 = 1, i5 = 0 (i3 got incremented )

Third iteration
ugly[3] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(4, 6, 5)
= 4
ugly[] = | 1 | 2 | 3 | 4 |
i2 = 2, i3 = 1, i5 = 0 (i2 got incremented )

Fourth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 5)
= 5
ugly[] = | 1 | 2 | 3 | 4 | 5 |
i2 = 2, i3 = 1, i5 = 1 (i5 got incremented )

Fifth iteration
ugly[4] = Min(ugly[i2]*2, ugly[i3]*3, ugly[i5]*5)
= Min(6, 6, 10)
= 6
ugly[] = | 1 | 2 | 3 | 4 | 5 | 6 |
i2 = 3, i3 = 2, i5 = 1 (i2 and i3 got incremented )

Will continue same way till I < 150

C/C++

// C++ program to find n'th Ugly number


# include<bits/stdc++.h>
using namespace std;
  
/* Function to get the nth ugly number*/
unsigned getNthUglyNo(unsigned n)
{
    unsigned ugly[n]; // To store ugly numbers
    unsigned i2 = 0, i3 = 0, i5 = 0;
    unsigned next_multiple_of_2 = 2;
    unsigned next_multiple_of_3 = 3;
    unsigned next_multiple_of_5 = 5;
    unsigned next_ugly_no = 1;
  
    ugly[0] = 1;
    for (int i=1; i<n; i++)

2912
Chapter 405. Ugly Numbers

    {
       next_ugly_no = min(next_multiple_of_2,
                           min(next_multiple_of_3,
                               next_multiple_of_5));
       ugly[i] = next_ugly_no;
       if (next_ugly_no == next_multiple_of_2)
       {
           i2 = i2+1;
           next_multiple_of_2 = ugly[i2]*2;
       }
       if (next_ugly_no == next_multiple_of_3)
       {
           i3 = i3+1;
           next_multiple_of_3 = ugly[i3]*3;
       }
       if (next_ugly_no == next_multiple_of_5)
       {
           i5 = i5+1;
           next_multiple_of_5 = ugly[i5]*5;
       }
    } /*End of for loop (i=1; i<n; i++) */
    return next_ugly_no;
}
  
/* Driver program to test above functions */
int main()
{
    int n = 150;
    cout << getNthUglyNo(n);
    return 0;
}

Java

// Java program to find nth ugly number


import java.lang.Math;
  
class UglyNumber
{
    /* Function to get the nth ugly number*/
    int getNthUglyNo(int n)
    {
        int ugly[] = new int[n];  // To store ugly numbers
        int i2 = 0, i3 = 0, i5 = 0;
        int next_multiple_of_2 = 2;
        int next_multiple_of_3 = 3;
        int next_multiple_of_5 = 5;
        int next_ugly_no = 1;

2913
Chapter 405. Ugly Numbers

          
        ugly[0] = 1;
          
        for(int i = 1; i < n; i++)
        {
            next_ugly_no = Math.min(next_multiple_of_2,
                                  Math.min(next_multiple_of_3,
                                        next_multiple_of_5));
              
            ugly[i] = next_ugly_no;
            if (next_ugly_no == next_multiple_of_2)
            {
               i2 = i2+1;
               next_multiple_of_2 = ugly[i2]*2;
            }
            if (next_ugly_no == next_multiple_of_3)
            {
               i3 = i3+1;
               next_multiple_of_3 = ugly[i3]*3;
            }
            if (next_ugly_no == next_multiple_of_5)
            {
               i5 = i5+1;
               next_multiple_of_5 = ugly[i5]*5;
            }
        } /*End of for loop (i=1; i<n; i++) */
        return next_ugly_no;
    }
  
    /* Driver program to test above functions */
    public static void main(String args[])
    {
        int n = 150;
        UglyNumber obj = new UglyNumber();
        System.out.println(obj.getNthUglyNo(n));
    }
}
  
// This code has been contributed by Amit Khandelwal (Amit Khandelwal 1)

Python

# Python program to find n'th Ugly number


  
# Function to get the nth ugly number
def getNthUglyNo(n):
  
    ugly = [0] * n # To store ugly numbers

2914
Chapter 405. Ugly Numbers

  
    # 1 is the first ugly number
    ugly[0] = 1
  
    # i2, i3, i5 will indicate indices for 2,3,5 respectively
    i2 = i3 =i5 = 0
  
    # set initial multiple value
    next_multiple_of_2 = 2
    next_multiple_of_3 = 3
    next_multiple_of_5 = 5
  
    # start loop to find value from ugly[1] to ugly[n]
    for l in range(1, n):
  
        # choose the min value of all available multiples
        ugly[l] = min(next_multiple_of_2, next_multiple_of_3, next_multiple_of_5)
  
        # increment the value of index accordingly
        if ugly[l] == next_multiple_of_2:
            i2 += 1
            next_multiple_of_2 = ugly[i2] * 2
  
        if ugly[l] == next_multiple_of_3:
            i3 += 1
            next_multiple_of_3 = ugly[i3] * 3
  
        if ugly[l] == next_multiple_of_5: 
            i5 += 1
            next_multiple_of_5 = ugly[i5] * 5
  
    # return ugly[n] value
    return ugly[-1]
  
def main():
  
    n = 150
  
    print getNthUglyNo(n)
  
  
if __name__ == '__main__':
    main()
  
#This code is contributed by Neelam Yadav

C#

2915
Chapter 405. Ugly Numbers

// C# program to count inversions in an array


using System;
using System.Collections.Generic;
  
class GFG {
  
    /* Function to get the nth ugly number*/
    static int getNthUglyNo(int n)
    {
          
        // To store ugly numbers
        int []ugly = new int[n]; 
        int i2 = 0, i3 = 0, i5 = 0;
        int next_multiple_of_2 = 2;
        int next_multiple_of_3 = 3;
        int next_multiple_of_5 = 5;
        int next_ugly_no = 1;
          
        ugly[0] = 1;
          
        for(int i = 1; i < n; i++)
        {
            next_ugly_no = Math.Min(next_multiple_of_2,
                           Math.Min(next_multiple_of_3,
                                  next_multiple_of_5));
              
            ugly[i] = next_ugly_no;
              
            if (next_ugly_no == next_multiple_of_2)
            {
                i2 = i2 + 1;
                next_multiple_of_2 = ugly[i2] * 2;
            }
              
            if (next_ugly_no == next_multiple_of_3)
            {
                i3 = i3 + 1;
                next_multiple_of_3 = ugly[i3] * 3;
            }
            if (next_ugly_no == next_multiple_of_5)
            {
                i5 = i5 + 1;
                next_multiple_of_5 = ugly[i5] * 5;
            }
        } 
          
        return next_ugly_no;
    }

2916
Chapter 405. Ugly Numbers

      
    // Driver code
    public static void Main()
    {
        int n = 150;
        Console.WriteLine(getNthUglyNo(n));
    }
}
  
// This code is contributed by Sam007

PHP

<?php
// PHP program to find 
// n'th Ugly number
  
//  Function to get the
// nth ugly number 
function getNthUglyNo($n)
{
    // To store ugly numbers
    $ugly = array_fill(0, $n, 0);
    $i2 = 0;
    $i3 = 0;
    $i5 = 0;
    $next_multiple_of_2 = 2;
    $next_multiple_of_3 = 3;
    $next_multiple_of_5 = 5;
    $next_ugly_no = 1;
  
    $ugly[0] = 1;
    for ($i = 1; $i < $n; $i++)
    {
    $next_ugly_no = min($next_multiple_of_2,
                    min($next_multiple_of_3,
                        $next_multiple_of_5));
    $ugly[$i] = $next_ugly_no;
    if ($next_ugly_no == 
        $next_multiple_of_2)
    {
        $i2 = $i2 + 1;
        $next_multiple_of_2 = $ugly[$i2] * 2;
    }
    if ($next_ugly_no == 
        $next_multiple_of_3)
    {
        $i3 = $i3 + 1;

2917
Chapter 405. Ugly Numbers

        $next_multiple_of_3 = $ugly[$i3] * 3;
    }
    if ($next_ugly_no == 
        $next_multiple_of_5)
    {
        $i5 = $i5 + 1;
        $next_multiple_of_5 = $ugly[$i5] * 5;
    }
    } /*End of for loop (i=1; i<n; i++) */
    return $next_ugly_no;
}
  
// Driver code
$n = 150;
echo getNthUglyNo($n);
  
// This code is contributed by mits
?>

Output :

5832

Algorithmic Paradigm: Dynamic Programming


Time Complexity: O(n)
Auxiliary Space: O(n)
Super Ugly Number (Number whose prime factors are in given set)
Improved By : Sam007, Mithun Kumar

Source

https://www.geeksforgeeks.org/ugly-numbers/

2918
Chapter 406

Unbounded Knapsack
(Repetition of items allowed)

Unbounded Knapsack (Repetition of items allowed) - GeeksforGeeks


Given a knapsack weight W and a set of n items with certain value vali and weight wti ,
we need to calculate minimum amount that could make up this quantity exactly. This is
different from classical Knapsack problem, here we are allowed to use unlimited number of
instances of an item.
Examples:

Input : W = 100
val[] = {1, 30}
wt[] = {1, 50}
Output : 100
There are many ways to fill knapsack.
1) 2 instances of 50 unit weight item.
2) 100 instances of 1 unit weight item.
3) 1 instance of 50 unit weight item and 50
instances of 1 unit weight items.
We get maximum value with option 2.

Input : W = 8
val[] = {10, 40, 50, 70}
wt[] = {1, 3, 4, 5}
Output : 110
We get maximum value with one unit of
weight 5 and one unit of weight 3.

Its an unbounded knapsack problem as we can use 1 or more instances of any resource. A
simple 1D array, say dp[W+1] can be used such that dp[i] stores the maximum value which

2919
Chapter 406. Unbounded Knapsack (Repetition of items allowed)

can achieved using all items and i capacity of knapsack. Note that we use 1D array here
which is different from classical knapsack where we used 2D array. Here number of items
never changes. We always have all items available.
We can recursively compute dp[] using below formula

dp[i] = 0
dp[i] = max(dp[i], dp[i-wt[j]] + val[j]
where j varies from 0
to n-1 such that:
wt[j] <= i

result = d[W]

Below is the implementation of above idea.


C++

// C++ program to find maximum achievable value


// with a knapsack of weight W and multiple
// instances allowed.
#include<bits/stdc++.h>
using namespace std;
  
// Returns the maximum value with knapsack of
// W capacity
int unboundedKnapsack(int W, int n, int val[], int wt[])
{
    // dp[i] is going to store maximum value
    // with knapsack capacity i.
    int dp[W+1];
    memset(dp, 0, sizeof dp);
  
    int ans = 0;
  
    // Fill dp[] using above recursive formula
    for (int i=0; i<=W; i++)
      for (int j=0; j<n; j++)
         if (wt[j] <= i)
            dp[i] = max(dp[i], dp[i-wt[j]]+val[j]);
  
    return dp[W];
}
  
// Driver program
int main()
{

2920
Chapter 406. Unbounded Knapsack (Repetition of items allowed)

    int W = 100;
    int val[] = {10, 30, 20};
    int wt[] = {5, 10, 15};
    int n = sizeof(val)/sizeof(val[0]);
  
    cout << unboundedKnapsack(W, n, val, wt);
  
    return 0;
}

Java

// Java program to find maximum achievable


// value with a knapsack of weight W and
// multiple instances allowed.
public class UboundedKnapsack {
      
    private static int max(int i, int j) {
            return (i > j) ? i : j;
    }
      
    // Returns the maximum value with knapsack
    // of W capacity
    private static int unboundedKnapsack(int W, int n, 
                                int[] val, int[] wt) {
          
        // dp[i] is going to store maximum value
        // with knapsack capacity i.
        int dp[] = new int[W + 1];
          
        // Fill dp[] using above recursive formula
        for(int i = 0; i <= W; i++){
            for(int j = 0; j < n; j++){
                if(wt[j] <= i){
                    dp[i] = max(dp[i], dp[i - wt[j]] + 
                                val[j]);
                }
            }
        }
        return dp[W];
    }
  
    // Driver program
    public static void main(String[] args) {
        int W = 100;
        int val[] = {10, 30, 20};
        int wt[] = {5, 10, 15};
        int n = val.length;

2921
Chapter 406. Unbounded Knapsack (Repetition of items allowed)

        System.out.println(unboundedKnapsack(W, n, val, wt));


    }
}
// This code is contributed by Aditya Kumar 

Python3

   
# Python3 program to find maximum
# achievable value with a knapsack
# of weight W and multiple instances allowed.
  
# Returns the maximum value 
# with knapsack of W capacity
def unboundedKnapsack(W, n, val, wt):
  
    # dp[i] is going to store maximum 
    # value with knapsack capacity i.
    dp = [0 for i in range(W + 1)]
  
    ans = 0
  
    # Fill dp[] using above recursive formula
    for i in range(W + 1):
        for j in range(n):
            if (wt[j] <= i):
                dp[i] = max(dp[i], dp[i - wt[j]] + val[j])
  
    return dp[W]
  
# Driver program
W = 100
val = [10, 30, 20]
wt = [5, 10, 15]
n = len(val)
  
print(unboundedKnapsack(W, n, val, wt))
  
# This code is contributed by Anant Agarwal.

C#

// C# program to find maximum achievable


// value with a knapsack of weight W and
// multiple instances allowed.
using System;
  

2922
Chapter 406. Unbounded Knapsack (Repetition of items allowed)

class UboundedKnapsack {
      
    private static int max(int i, int j)
    {
            return (i > j) ? i : j;
    }
      
    // Returns the maximum value 
    // with knapsack of W capacity
    private static int unboundedKnapsack(int W, int n, 
                                  int []val, int []wt) 
    {
          
        // dp[i] is going to store maximum value
        // with knapsack capacity i.
        int []dp = new int[W + 1];
          
        // Fill dp[] using above recursive formula
        for(int i = 0; i <= W; i++){
            for(int j = 0; j < n; j++){
                if(wt[j] <= i){
                    dp[i] = Math.Max(dp[i], dp[i - wt[j]] + val[j]);
                }
            }
        }
        return dp[W];
    }
  
    // Driver program
    public static void Main() 
    {
        int W = 100;
        int []val = {10, 30, 20};
        int []wt = {5, 10, 15};
        int n = val.Length;
        Console.WriteLine(unboundedKnapsack(W, n, val, wt));
    }
}
  
// This code is contributed by vt_m.

PHP

<?php
// PHP program to find maximum 
// achievable value with a 
// knapsack of weight W and 
// multiple instances allowed.

2923
Chapter 406. Unbounded Knapsack (Repetition of items allowed)

  
// Returns the maximum value 
// with knapsack of W capacity
function unboundedKnapsack($W, $n, 
                           $val, $wt)
{
    // dp[i] is going to store 
    // maximum value with 
    // knapsack capacity i.
    for($i = 0; $i <= $W; $i++)
        $dp[$i] = 0;
  
    $ans = 0;
      
    // Fill dp[] using above
    // recursive formula
    for ($i = 0; $i <= $W; $i++)
    for ($j = 0; $j < $n; $j++)
        if ($wt[$j] <= $i)
            $dp[$i] = max($dp[$i], 
                          $dp[$i - $wt[$j]] + 
                                   $val[$j]);
  
    return $dp[$W];
}
  
// Driver Code
$W = 100;
$val = array(10, 30, 20);
$wt = array(5, 10, 15);
$n = count($val); //sizeof($val)/sizeof($val[0]);
  
echo unboundedKnapsack($W, $n, 
                       $val, $wt);
  
// This code is contributed
// by shiv_bhakt
?>

Output:

300

Improved By : vt_m, shiv_bhakt, dStudent

2924
Chapter 406. Unbounded Knapsack (Repetition of items allowed)

Source

https://www.geeksforgeeks.org/unbounded-knapsack-repetition-items-allowed/

2925
Chapter 407

Unique paths in a Grid with


Obstacles

Unique paths in a Grid with Obstacles - GeeksforGeeks


Given a grid of size m * n, let us assume you are starting at (1, 1) and your goal is to reach
(m, n). At any instance, if you are on (x, y), you can either go to (x, y + 1) or (x + 1, y).
Now consider if some obstacles are added to the grids. How many unique paths would there
be?
An obstacle and empty space are marked as 1 and 0 respectively in the grid.
Examples:

Input: [[0, 0, 0],


[0, 1, 0],
[0, 0, 0]]
Output : 2
There is only one obstacle in the middle.

We have discussed a problem to count the number of unique paths in a Grid when no
obstacle was present in the grid. But here the situation is quite different. While moving
through the grid, we can get some obstacles which we can not jump and that way to reach
the bottom right corner is blocked.
The most efficient solution to this problem can be achieved using dynamic programming.
Like every dynamic problem concept, we will not recompute the subproblems. A temporary
2D matrix will be constructed and value will be stored using the bottom up approach.

• Create a 2D matrix of same size of the given matrix to store the results.
• Traverse through the created array row wise and start filling the values in it.
• If an obstacle is found, set the value to 0.
• For the first row and column, set the value to 1 if obstacle is not found.

2926
Chapter 407. Unique paths in a Grid with Obstacles

• Set the sum of the right and the upper values if obstacle is not present at that corre-
sponding position in the given matirx
• Return the last value of the created 2d matrix

# Python code to find number of unique paths in a 


# matrix with obstacles.
  
def uniquePathsWithObstacles(A):
    
    # create a 2D-matrix and initializing with value 0
    paths = [[0]*len(A[0]) for i in A]
      
    # initializing the left corner if no obstacle there
    if A[0][0] == 0:
        paths[0][0] = 1
      
    # initializing first column of the 2D matrix
    for i in range(1, len(A)):
        if A[i][0] == 0:  // If not obstacle
            paths[i][0] = paths[i-1][0]
              
    # initializing first row of the 2D matrix
    for j in range(1, len(A[0])):
        if A[0][j] == 0:  // If not obstacle
            paths[0][j] = paths[0][j-1]
              
    for i in range(1, len(A)):
      for j in range(1, len(A[0])):
  
        # If current cell is not obstacle
        if A[i][j] == 0:
          paths[i][j] = paths[i-1][j] + paths[i][j-1]
    
    # returning the corner value of the matrix
    return paths[-1][-1]
  
  
# Driver Code
A = [[0, 0, 0], [0, 1, 0], [0, 0, 0]]
print(uniquePathsWithObstacles(A))

Output:

2927
Chapter 407. Unique paths in a Grid with Obstacles

Source

https://www.geeksforgeeks.org/unique-paths-in-a-grid-with-obstacles/

2928
Chapter 408

Value of continuous floor


function : F(x) = F(floor(x/2))
+x

Value of continuous floor function : F(x) = F(floor(x/2)) + x - GeeksforGeeks


Given an array of positive integers. For every element x of array, we need to find the value
of continuous floor function defined as F(x) = F(floor(x/2)) + x, where F(0) = 0.
Examples :-

Input : arr[] = {6, 8}


Output : 10 15

Explanation : F(6) = 6 + F(3)


= 6 + 3 + F(1)
= 6 + 3 + 1 + F(0)
= 10
Similarly F(8) = 15

Basic Approach : For given value of x, we can calculate F(x) by using simple recursive
function as:

int func(int x)
{
if (x == 0)
return 0;
return (x + func(floor(x/2)));
}

2929
Chapter 408. Value of continuous floor function : F(x) = F(floor(x/2)) + x

In this approach if we have n queries then it will take O(x) for every query element
An Efficient Approach is to use memoization We construct an array which holds the
value of F(x) for each possible value of x. We compute the value if not already computed.
Else we return the value.
C++

// C++ program for finding value 


// of continuous floor function
#include <bits/stdc++.h>
  
#define max 10000
using namespace std;
  
int dp[max];
  
void initDP()
    {
         for (int i = 0; i < max; i++)
             dp[i] = -1;
    }
  
// function to return value of F(n)
int func(int x)
    {
        if (x == 0)
            return 0;
        if (dp[x] == -1)
            dp[x] = x + func(x / 2);
  
        return dp[x];
    }
  
void printFloor(int arr[], int n)
    {
        for (int i = 0; i < n; i++)
            cout << func(arr[i]) << " ";
    }
  
// Driver code
int main()
    {
        // call the initDP() to fill DP array
        initDP();
  
        int arr[] = { 8, 6 };
        int n = sizeof(arr) / sizeof(arr[0]);
  

2930
Chapter 408. Value of continuous floor function : F(x) = F(floor(x/2)) + x

        printFloor(arr, n);
  
        return 0;
    }

Java

// Java program for finding value


// of continuous floor function
class GFG 
{
    static final int max = 10000;
    static int dp[] = new int[max];
      
    static void initDP() 
    {
        for (int i = 0; i < max; i++)
            dp[i] = -1;
    }
      
    // function to return value of F(n)
    static int func(int x) 
    {
        if (x == 0)
            return 0;
        if (dp[x] == -1)
            dp[x] = x + func(x / 2);
      
        return dp[x];
    }
      
    static void printFloor(int arr[], int n) 
    {
        for (int i = 0; i < n; i++)
            System.out.print(func(arr[i]) + " ");
    }
      
    // Driver code
    public static void main(String[] args) 
    {
          
        // call the initDP() to fill DP array
        initDP();
      
        int arr[] = {8, 6};
        int n = arr.length;
      
        printFloor(arr, n);

2931
Chapter 408. Value of continuous floor function : F(x) = F(floor(x/2)) + x

    }
}
  
// This code is contributed by Anant Agarwal.

C#

// C# program for finding value 


// of continuous floor function
using System;
  
class GFG 
{
    static int max = 10000;
    static int []dp = new int[max];
      
    static void initDP() 
    {
        for (int i = 0; i < max; i++)
            dp[i] = -1;
    }
      
    // function to return value of F(n)
    static int func(int x) 
    {
        if (x == 0)
            return 0;
        if (dp[x] == -1)
            dp[x] = x + func(x / 2);
      
        return dp[x];
    }
      
    static void printFloor(int []arr, int n) 
    {
        for (int i = 0; i < n; i++)
            Console.Write(func(arr[i]) + " ");
    }
      
    // Driver code
    public static void Main() 
    {
          
        // call the initDP() to fill DP array
        initDP();
      
        int []arr = {8, 6};
        int n = arr.Length;

2932
Chapter 408. Value of continuous floor function : F(x) = F(floor(x/2)) + x

      
        printFloor(arr, n);
    }
}
  
// This code is contributed by nitin mittal

Output:

15 10

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/value-continuous-floor-function-fx-ffloorx2-x/

2933
Chapter 409

Vertex Cover Problem | Set 2


(Dynamic Programming
Solution for Tree)

Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree) - GeeksforGeeks
A vertex cover of an undirected graph is a subset of its vertices such that for every edge (u,
v) of the graph, either ‘u’ or ‘v’ is in vertex cover. Although the name is Vertex Cover, the
set covers all edges of the given graph.
The problem to find minimum size vertex cover of a graph is NP complete. But it can be
solved in polynomial time for trees. In this post a solution for Binary Tree is discussed. The
same solution can be extended for n-ary trees.
For example, consider the following binary tree. The smallest vertex cover is {20, 50, 30}
and size of the vertex cover is 3.

2934
Chapter 409. Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree)

The idea is to consider following two possibilities for root and recursively for all nodes down
the root.
1) Root is part of vertex cover: In this case root covers all children edges. We recursively
calculate size of vertex covers for left and right subtrees and add 1 to the result (for root).
2) Root is not part of vertex cover: In this case, both children of root must be included
in vertex cover to cover all root to children edges. We recursively calculate size of vertex
covers of all grandchildren and number of children to the result (for two children of root).
Below is C implementation of above idea.

// A naive recursive C implementation for vertex cover problem for a tree


#include <stdio.h>
#include <stdlib.h>
  
// A utility function to find min of two integers
int min(int x, int y) { return (x < y)? x: y; }
  
/* A binary tree node has data, pointer to left child and a pointer to
   right child */
struct node
{
    int data;
    struct node *left, *right;
};
  
// The function returns size of the minimum vertex cover
int vCover(struct node *root)
{
    // The size of minimum vertex cover is zero if tree is empty or there

2935
Chapter 409. Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree)

    // is only one node


    if (root == NULL)
        return 0;
    if (root->left == NULL && root->right == NULL)
        return 0;
  
    // Calculate size of vertex cover when root is part of it
    int size_incl = 1 + vCover(root->left) + vCover(root->right);
  
    // Calculate size of vertex cover when root is not part of it
    int size_excl = 0;
    if (root->left)
      size_excl += 1 + vCover(root->left->left) + vCover(root->left->right);
    if (root->right)
      size_excl += 1 + vCover(root->right->left) + vCover(root->right->right);
  
    // Return the minimum of two sizes
    return min(size_incl, size_excl);
}
  
// A utility function to create a node
struct node* newNode( int data )
{
    struct node* temp = (struct node *) malloc( sizeof(struct node) );
    temp->data = data;
    temp->left = temp->right = NULL;
    return temp;
}
  
// Driver program to test above functions
int main()
{
    // Let us construct the tree given in the above diagram
    struct node *root         = newNode(20);
    root->left                = newNode(8);
    root->left->left          = newNode(4);
    root->left->right         = newNode(12);
    root->left->right->left   = newNode(10);
    root->left->right->right  = newNode(14);
    root->right               = newNode(22);
    root->right->right        = newNode(25);
  
    printf ("Size of the smallest vertex cover is %d ", vCover(root));
  
    return 0;
}

Output:

2936
Chapter 409. Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree)

Size of the smallest vertex cover is 3

Time complexity of the above naive recursive approach is exponential. It should be noted
that the above function computes the same subproblems again and again. For example,
vCover of node with value 50 is evaluated twice as 50 is grandchild of 10 and child of 20.
Since same suproblems are called again, this problem has Overlapping Subprolems property.
So Vertex Cover problem has both properties (see thisand this) of a dynamic programming
problem. Like other typical Dynamic Programming(DP) problems, re-computations of same
subproblems can be avoided by storing the solutions to subproblems and solving problems
in bottom up manner.
Following is C implementation of Dynamic Programming based solution. In the following
solution, an additional field ‘vc’ is added to tree nodes. The initial value of ‘vc’ is set as
0 for all nodes. The recursive function vCover() calculates ‘vc’ for a node only if it is not
already set.

/* Dynamic programming based program for Vertex Cover problem for 


   a Binary Tree */
#include <stdio.h>
#include <stdlib.h>
  
// A utility function to find min of two integers
int min(int x, int y) { return (x < y)? x: y; }
  
/* A binary tree node has data, pointer to left child and a pointer to
   right child */
struct node
{
    int data;
    int vc;
    struct node *left, *right;
};
  
// A memoization based function that returns size of the minimum vertex cover.
int vCover(struct node *root)
{
    // The size of minimum vertex cover is zero if tree is empty or there
    // is only one node
    if (root == NULL)
        return 0;
    if (root->left == NULL && root->right == NULL)
        return 0;
  
    // If vertex cover for this node is already evaluated, then return it
    // to save recomputation of same subproblem again.
    if (root->vc != 0)
        return root->vc;
  

2937
Chapter 409. Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree)

    // Calculate size of vertex cover when root is part of it


    int size_incl = 1 + vCover(root->left) + vCover(root->right);
  
    // Calculate size of vertex cover when root is not part of it
    int size_excl = 0;
    if (root->left)
      size_excl += 1 + vCover(root->left->left) + vCover(root->left->right);
    if (root->right)
      size_excl += 1 + vCover(root->right->left) + vCover(root->right->right);
  
    // Minimum of two values is vertex cover, store it before returning
    root->vc =  min(size_incl, size_excl);
  
    return root->vc;
}
  
// A utility function to create a node
struct node* newNode( int data )
{
    struct node* temp = (struct node *) malloc( sizeof(struct node) );
    temp->data = data;
    temp->left = temp->right = NULL;
    temp->vc = 0; // Set the vertex cover as 0
    return temp;
}
  
// Driver program to test above functions
int main()
{
    // Let us construct the tree given in the above diagram
    struct node *root         = newNode(20);
    root->left                = newNode(8);
    root->left->left          = newNode(4);
    root->left->right         = newNode(12);
    root->left->right->left   = newNode(10);
    root->left->right->right  = newNode(14);
    root->right               = newNode(22);
    root->right->right        = newNode(25);
  
    printf ("Size of the smallest vertex cover is %d ", vCover(root));
  
    return 0;
}

Output:

Size of the smallest vertex cover is 3

2938
Chapter 409. Vertex Cover Problem | Set 2 (Dynamic Programming Solution for Tree)

References:
http://courses.csail.mit.edu/6.006/spring11/lectures/lec21.pdf
Exercise:
Extend the above solution for n-ary trees.
This article is contributed by Udit Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/vertex-cover-problem-set-2-dynamic-programming-solution-tree/

2939
Chapter 410

Water Jug Problem using


Memoization

Water Jug Problem using Memoization - GeeksforGeeks


Given two jugs with the maximum capacity of m and n liters respectively. The jugs don’t
have markings on them which can help us to measure smaller quantities. The task is to
measure d liters of water using these two jugs. Hence our goal is to reach from initial state
(m, n) to final state (0, d) or (d, 0).
Examples:

Input: 4 3 2
Output: (0, 0) –> (4, 0) –> (4, 3) –> (0, 3) –> (3, 0) –> (3, 3) –> (4, 2) –>
(0, 2)
Input: 5 2 4
Output: (0, 0) –> (5, 0) –> (5, 2) –> (0, 2) –> (2, 0) –> (2, 2) –> (4, 0)

Approach: An approach using BFS has been discussed in the previous post. In this post
an approach using memoization and recursion has been discussed. At any point, there can
be a total of six possibilities:

• Empty the first jug completely


• Empty the second jug completely
• Fill the first jug
• Fill the second jug
• Fill the water from the second jug into the first jug until the first jug is full or the
second jug has no water left
• Fill the water from the first jug into the second jug until the second jug is full or the
first jug has no water left

Approach: Using Recursion, visit all the six possible moves one by one until one of them
returns True. Since there can be repetitions of same recursive calls, hence every return value

2940
Chapter 410. Water Jug Problem using Memoization

is stored using memoizationto avoid calling the recursive function again and returning the
stored value.
Below is the implementation of the above approach:

# This function is used to initialize the 


# dictionary elements with a default value.
from collections import defaultdict
  
# jug1 and jug2 contain the value 
# for max capacity in respective jugs 
# and aim is the amount of water to be measured. 
jug1, jug2, aim = 4, 3, 2
  
# Initialize dictionary with 
# default value as false.
visited = defaultdict(lambda: False)
  
# Recursive function which prints the 
# intermediate steps to reach the final 
# solution and return boolean value 
# (True if solution is possible, otherwise False).
# amt1 and amt2 are the amount of water present 
# in both jugs at a certain point of time.
def waterJugSolver(amt1, amt2): 
  
    # Checks for our goal and 
    # returns true if achieved.
    if (amt1 == aim and amt2 == 0) or (amt2 == aim and amt1 == 0):
        print(amt1, amt2)
        return True
      
    # Checks if we have already visited the
    # combination or not. If not, then it proceeds further.
    if visited[(amt1, amt2)] == False:
        print(amt1, amt2)
      
        # Changes the boolean value of
        # the combination as it is visited. 
        visited[(amt1, amt2)] = True
      
        # Check for all the 6 possibilities and 
        # see if a solution is found in any one of them.
        return (waterJugSolver(0, amt2) or
                waterJugSolver(amt1, 0) or
                waterJugSolver(jug1, amt2) or
                waterJugSolver(amt1, jug2) or
                waterJugSolver(amt1 + min(amt2, (jug1-amt1)),
                amt2 - min(amt2, (jug1-amt1))) or

2941
Chapter 410. Water Jug Problem using Memoization

                waterJugSolver(amt1 - min(amt1, (jug2-amt2)),


                amt2 + min(amt1, (jug2-amt2))))
      
    # Return False if the combination is 
    # already visited to avoid repetition otherwise
    # recursion will enter an infinite loop.
    else:
        return False
  
print("Steps: ")
  
# Call the function and pass the
# initial amount of water present in both jugs.
waterJugSolver(0, 0)

Output:

Steps:
0 0
4 0
4 3
0 3
3 0
3 3
4 2
0 2

Time complexity: O(M * N)


Auxiliary Space: O(M * N)

Source

https://www.geeksforgeeks.org/water-jug-problem-using-memoization/

2942
Chapter 411

Ways of transforming one string


to other by removing 0 or more
characters

Ways of transforming one string to other by removing 0 or more characters - GeeksforGeeks


Given two sequences A, B, find out number of unique ways in sequence A, to form a sub-
sequence of A that is identical to the sequence B. Transformation is meant by converting
string A (by removing 0 or more characters) to string B.
Examples:

Input : A = "abcccdf", B = "abccdf"


Output : 3
Explanation : Three ways will be -> "ab.ccdf",
"abc.cdf" & "abcc.df" .
"." is where character is removed.

Input : A = "aabba", B = "ab"


Output : 4
Expalnation : Four ways will be -> "a.b..",
"a..b.", ".ab.." & ".a.b." .
"." is where characters are removed.

Asked in : Google
The idea to solve this problem is using Dynamic Programming. Construct a 2D DP matrix
of m*n size, where m is size of string B and n is size of string A.
dp[i][j] gives the number of ways of transforming string A[0…j] to B[0…i].

• Case 1 : dp[0][j] = 1, since placing B = “” with any substring of A would have only
1 solution which is to delete all characters in A.

2943
Chapter 411. Ways of transforming one string to other by removing 0 or more characters

• Case 2 : when i > 0, dp[i][j] can be derived by two cases:


– Case 2.a : if B[i] != A[j], then the solution would be to ignore the character A[j]
and align substring B[0..i] with A[0..(j-1)]. Therefore, dp[i][j] = dp[i][j-1].
– Case 2.b : if B[i] == A[j], then first we could have the solution in case a), but
also we could match the characters B[i] and A[j] and place the rest of them (i.e.
B[0..(i-1)] and A[0..(j-1)]. As a result, dp[i][j] = dp[i][j-1] + dp[i-1][j-1].

Source

https://www.geeksforgeeks.org/ways-transforming-one-string-removing-0-characters/

2944
Chapter 412

Ways to arrange Balls such that


adjacent balls are of different
types

Ways to arrange Balls such that adjacent balls are of different types - GeeksforGeeks
There are ‘p’ balls of type P, ‘q’ balls of type Q and ‘r’ balls of type R. Using the balls we
want to create a straight line such that no two balls of same type are adjacent.
Examples :

Input : p = 1, q = 1, r = 0
Output : 2
There are only two arrangements PQ and QP

Input : p = 1, q = 1, r = 1
Output : 6
There are only six arrangements PQR, QPR,
QRP, RQP, PRQ and RPQ

Input : p = 2, q = 1, r = 1
Output : 6
There are only six arrangements PQRP, QPRP,
PRQP, RPQP, PRPQ and PQPR

Naive Solution:
The naive solution to this problem is a recursive solution. We recursively call for three cases
1) Last ball to be placed is of type P
2) Last ball to be placed is of type Q
3) Last ball to be placed is of type R

2945
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

Below is the implementation of above idea.

C++

// C++ program to count number of ways to arrange three


// types of balls such that no two balls of same color
// are adjacent to each other
#include<bits/stdc++.h>
using namespace std;
  
// Returns count of arrangements where last placed ball is
// 'last'.  'last' is 0 for 'p', 1 for 'q' and 2 for 'r'
int countWays(int p, int q, int r, int last)
{
    // if number of balls of any color becomes less
    // than 0 the number of ways arrangements is 0.
    if (p<0 || q<0 || r<0)
        return 0;
  
    // If last ball required is of type P and the number
    // of balls of P type is 1 while number of balls of
    // other color is 0 the number of ways is 1.
    if (p==1 && q==0 && r==0 && last==0)
        return 1;
  
    // Same case as above for 'q' and 'r'
    if (p==0 && q==1 && r==0 && last==1)
        return 1;
    if (p==0 && q==0 && r==1 && last==2)
        return 1;
  
    // if last ball required is P and the number of ways is
    // the sum of number of ways to form sequence with 'p-1' P
    // balls, q Q Balls and r R balls ending with Q and R.
    if (last==0)
        return countWays(p-1,q,r,1) + countWays(p-1,q,r,2);
  
    // Same as above case for 'q' and 'r'
    if (last==1)
        return countWays(p,q-1,r,0) + countWays(p,q-1,r,2);
    if (last==2)
        return countWays(p,q,r-1,0) + countWays(p,q,r-1,1);
}
  
// Returns count of required arrangements
int countUtil(int p, int q, int r)
{
   // Three cases arise:

2946
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

   return countWays(p, q, r, 0) +  // Last required balls is type P


          countWays(p, q, r, 1) +  // Last required balls is type Q
          countWays(p, q, r, 2); // Last required balls is type R
}
  
// Driver code to test above
int main()
{
    int p = 1, q = 1, r = 1;
    printf("%d", countUtil(p, q, r));
    return 0;
}

Java

// Java program to count number 


// of ways to arrange three types of
// balls such that no two balls of 
// same color are adjacent to each other
class GFG {
      
    // Returns count of arrangements
    // where last placed ball is
    // 'last'. 'last' is 0 for 'p', 
    // 1 for 'q' and 2 for 'r'
    static int countWays(int p, int q, int r, int last) 
    {
        // if number of balls of any 
        // color becomes less than 0 
        // the number of ways arrangements is 0.
        if (p < 0 || q < 0 || r < 0)
        return 0;
      
        // If last ball required is
        // of type P and the number
        // of balls of P type is 1
        // while number of balls of
        // other color is 0 the number
        // of ways is 1.
        if (p == 1 && q == 0 && r == 0 && last == 0)
            return 1;
      
        // Same case as above for 'q' and 'r'
        if (p == 0 && q == 1 && r == 0 && last == 1)
            return 1;
        if (p == 0 && q == 0 && r == 1 && last == 2)
            return 1;
      

2947
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

        // if last ball required is P


        // and the number of ways is
        // the sum of number of ways 
        // to form sequence with 'p-1' P
        // balls, q Q Balls and r R balls
        // ending with Q and R.
        if (last == 0)
        return countWays(p - 1, q, r, 1) +
               countWays(p - 1, q, r, 2);
      
        // Same as above case for 'q' and 'r'
        if (last == 1)
            return countWays(p, q - 1, r, 0) +
                   countWays(p, q - 1, r, 2);
          
        if (last == 2)
        return countWays(p, q, r - 1, 0) +
               countWays(p, q, r - 1, 1);
      
        return 0;
    }
      
    // Returns count of required arrangements
    static int countUtil(int p, int q, int r) {
        // Three cases arise:
        return countWays(p, q, r, 0) + // Last required balls is type P
               countWays(p, q, r, 1) + // Last required balls is type Q
               countWays(p, q, r, 2);  // Last required balls is type R
    }
      
    // Driver code
    public static void main(String[] args) 
    {
        int p = 1, q = 1, r = 1;
        System.out.print(countUtil(p, q, r));
    }
}
  
// This code is contributed by Anant Agarwal.

C#

// C# program to count number 


// of ways to arrange three types of
// balls such that no two balls of 
// same color are adjacent to each other
using System;
  

2948
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

class GFG {
      
    // Returns count of arrangements
    // where last placed ball is
    // 'last'. 'last' is 0 for 'p', 
    // 1 for 'q' and 2 for 'r'
    static int countWays(int p, int q,
                            int r, int last) 
    {
          
        // if number of balls of any 
        // color becomes less than 0 
        // the number of ways
        // arrangements is 0.
        if (p < 0 || q < 0 || r < 0)
            return 0;
      
        // If last ball required is
        // of type P and the number
        // of balls of P type is 1
        // while number of balls of
        // other color is 0 the number
        // of ways is 1.
        if (p == 1 && q == 0 && r == 0 
                              && last == 0)
            return 1;
      
        // Same case as above for 'q' and 'r'
        if (p == 0 && q == 1 && r == 0 
                               && last == 1)
            return 1;
        if (p == 0 && q == 0 && r == 1 
                               && last == 2)
            return 1;
      
        // if last ball required is P
        // and the number of ways is
        // the sum of number of ways 
        // to form sequence with 'p-1' P
        // balls, q Q Balls and r R balls
        // ending with Q and R.
        if (last == 0)
            return countWays(p - 1, q, r, 1) +
                    countWays(p - 1, q, r, 2);
      
        // Same as above case for 'q' and 'r'
        if (last == 1)
            return countWays(p, q - 1, r, 0) +

2949
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

                countWays(p, q - 1, r, 2);
          
        if (last == 2)
            return countWays(p, q, r - 1, 0) +
                    countWays(p, q, r - 1, 1);
      
        return 0;
    }
      
    // Returns count of required arrangements
    static int countUtil(int p, int q, int r)
    {
          
        // Three cases arise:
        // 1. Last required balls is type P
        // 2. Last required balls is type Q
        // 3. Last required balls is type R
        return countWays(p, q, r, 0) + 
               countWays(p, q, r, 1) + 
               countWays(p, q, r, 2); 
    }
      
    // Driver code
    public static void Main() 
    {
        int p = 1, q = 1, r = 1;
          
        Console.Write(countUtil(p, q, r));
    }
}
  
// This code is contributed by nitin mittal.

PHP

<?php
// PHP program to count number
// of ways to arrange three
// types of balls such that 
// no two balls of same color
// are adjacent to each other
  
// Returns count of arrangements
// where last placed ball is
// 'last'. 'last' is 0 for 'p',
// 1 for 'q' and 2 for 'r'
function countWays($p, $q, 
                   $r, $last)

2950
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

{
      
    // if number of balls of 
    // any color becomes less
    // than 0 the number of 
    // ways arrangements is 0.
    if ($p < 0 || $q 
           < 0 || $r < 0)
        return 0;
  
    // If last ball required is
    // of type P and the number
    // of balls of P type is 1
    // while number of balls of
    // other color is 0 the number
    // of ways is 1.
    if ($p == 1 && $q == 0 && 
        $r == 0 && $last == 0)
        return 1;
  
    // Same case as above 
    // for 'q' and 'r'
    if ($p == 0 && $q == 1 && 
        $r == 0 && $last == 1)
        return 1;
          
    if ($p == 0 && $q == 0 &&
        $r == 1 && $last == 2)
        return 1;
  
    // if last ball required is P 
    // and the number of ways is
    // the sum of number of ways 
    // to form sequence with 'p-1' P
    // balls, q Q Balls and r R 
    // balls ending with Q and R.
    if ($last == 0)
        return countWays($p - 1, $q, $r, 1) + 
               countWays($p - 1, $q, $r, 2);
  
    // Same as above case
    // for 'q' and 'r'
    if ($last == 1)
        return countWays($p, $q - 1, $r, 0) + 
               countWays($p, $q - 1, $r, 2);
    if ($last == 2)
        return countWays($p, $q, $r - 1, 0) + 
               countWays($p, $q, $r - 1, 1);

2951
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

}
  
// Returns count of 
// required arrangements
function countUtil($p, $q, $r)
{
      
    // Three cases arise:
    // Last required balls is type P
    // Last required balls is type Q
    // Last required balls is type R
    return countWays($p, $q, $r, 0) + 
           countWays($p, $q, $r, 1) + 
           countWays($p, $q, $r, 2); 
}
  
    // Driver Code
    $p = 1; 
    $q = 1;
    $r = 1;
    echo(countUtil($p, $q, $r));
      
// This code is contributed by nitin mittal.
?>

Python3

# Python3 program to count 


# number of ways to arrange 
# three types of balls such  
# that no two balls of same 
# color are adjacent to each 
# other
  
# Returns count of arrangements
# where last placed ball is
# 'last'. 'last' is 0 for 'p',
# 1 for 'q' and 2 for 'r'
def countWays(p, q, r, last):
      
    # if number of balls of 
    # any color becomes less
    # than 0 the number of 
    # ways arrangements is 0.
    if (p < 0 or q < 0 or r < 0):
        return 0;
  
    # If last ball required is

2952
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

    # of type P and the number


    # of balls of P type is 1
    # while number of balls of
    # other color is 0 the number
    # of ways is 1.
    if (p == 1 and q == 0 and
        r == 0 and last == 0):
        return 1;
  
    # Same case as above 
    # for 'q' and 'r'
    if (p == 0 and q == 1 and
        r == 0 and last == 1):
        return 1;
          
    if (p == 0 and q == 0 and 
        r == 1 and last == 2):
        return 1;
  
    # if last ball required is P 
    # and the number of ways is
    # the sum of number of ways 
    # to form sequence with 'p-1' P
    # balls, q Q Balls and r R 
    # balls ending with Q and R.
    if (last == 0):
        return (countWays(p - 1, q, r, 1) + 
                countWays(p - 1, q, r, 2));
  
    # Same as above case
    # for 'q' and 'r'
    if (last == 1):
        return (countWays(p, q - 1, r, 0) + 
                countWays(p, q - 1, r, 2));
    if (last == 2):
        return (countWays(p, q, r - 1, 0) + 
                countWays(p, q, r - 1, 1));
  
# Returns count of 
# required arrangements
def countUtil(p, q, r):
      
    # Three cases arise:
    # Last required balls is type P
    # Last required balls is type Q
    # Last required balls is type R
    return (countWays(p, q, r, 0) + 
            countWays(p, q, r, 1) + 

2953
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

            countWays(p, q, r, 2)); 
  
# Driver Code
p = 1; 
q = 1;
r = 1;
print(countUtil(p, q, r));
      
# This code is contributed by mits

Output:

Time Complexity of this solution is exponential.


We can observe that there are many subproblems being solved again and again so the
problem can be solved using Dynamic Programming (DP). We can easily make memoization
solution to this problem.

C++

// C++ program to count number of ways to arrange three


// types of balls such that no two balls of same color
// are adjacent to each other
#include<bits/stdc++.h>
using namespace std;
#define MAX 100
  
// table to store to store results of subproblems
int dp[MAX][MAX][MAX][3];
  
// Returns count of arrangements where last placed ball is
// 'last'.  'last' is 0 for 'p', 1 for 'q' and 2 for 'r'
int countWays(int p, int q, int r, int last)
{
    // if number of balls of any color becomes less
    // than 0 the number of ways arrangements is 0.
    if (p<0 || q<0 || r<0)
        return 0;
  
    // If last ball required is of type P and the number
    // of balls of P type is 1 while number of balls of
    // other color is 0 the number of ways is 1.
    if (p==1 && q==0 && r==0 && last==0)
        return 1;

2954
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

  
    // Same case as above for 'q' and 'r'
    if (p==0 && q==1 && r==0 && last==1)
        return 1;
    if (p==0 && q==0 && r==1 && last==2)
        return 1;
  
    // If this subproblem is already evaluated
    if (dp[p][q][r][last] != -1)
        return dp[p][q][r][last];
  
    // if last ball required is P and the number of ways is
    // the sum of number of ways to form sequence with 'p-1' P
    // balls, q Q Balls and r R balls ending with Q and R.
    if (last==0)
       dp[p][q][r][last] = countWays(p-1,q,r,1) + countWays(p-1,q,r,2);
  
    // Same as above case for 'q' and 'r'
    else if (last==1)
       dp[p][q][r][last] = countWays(p,q-1,r,0) + countWays(p,q-1,r,2);
    else //(last==2)
       dp[p][q][r][last] =  countWays(p,q,r-1,0) + countWays(p,q,r-1,1);
  
    return dp[p][q][r][last];
}
  
// Returns count of required arrangements
int countUtil(int p, int q, int r)
{
   // Initialize 'dp' array
   memset(dp, -1, sizeof(dp));
  
   // Three cases arise:
   return countWays(p, q, r, 0) +  // Last required balls is type P
          countWays(p, q, r, 1) +  // Last required balls is type Q
          countWays(p, q, r, 2); // Last required balls is type R
}
  
// Driver code to test above
int main()
{
    int p = 1, q = 1, r = 1;
    printf("%d", countUtil(p, q, r));
    return 0;
}

Java

2955
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

// Java program to count number


// of ways to arrange three
// types of balls such that no
// two balls of same color
// are adjacent to each other
import java.util.Arrays;
  
class GFG 
{
  
    static final int MAX = 100;
      
    // table to store to store results of subproblems
    static int dp[][][][] = new int[MAX][MAX][MAX][3];
      
    // Returns count of arrangements
    // where last placed ball is
    // 'last'. 'last' is 0 for 'p',
    // 1 for 'q' and 2 for 'r'
    static int countWays(int p, int q, int r, int last)
    {
        // if number of balls of any 
        // color becomes less than 0
        // the number of ways arrangements is 0.
        if (p < 0 || q < 0 || r < 0)
        return 0;
      
        // If last ball required is 
        // of type P and the number
        // of balls of P type is 1 
        // while number of balls of
        // other color is 0 the number 
        // of ways is 1.
        if (p == 1 && q == 0 && r == 0 && last == 0)
            return 1;
      
        // Same case as above for 'q' and 'r'
        if (p == 0 && q == 1 && r == 0 && last == 1)
            return 1;
          
        if (p == 0 && q == 0 && r == 1 && last == 2)
            return 1;
      
        // If this subproblem is already evaluated
        if (dp[p][q][r][last] != -1)
            return dp[p][q][r][last];
      
        // if last ball required is P and 

2956
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

        // the number of ways is the sum


        // of number of ways to form sequence
        // with 'p-1' P balls, q Q balss and
        // r R balls ending with Q and R.
        if (last == 0)
        dp[p][q][r][last] = countWays(p - 1, q, r, 1) + 
                            countWays(p - 1, q, r, 2);
      
        // Same as above case for 'q' and 'r'
        else if (last == 1)
        dp[p][q][r][last] = countWays(p, q - 1, r, 0) + 
                            countWays(p, q - 1, r, 2);
        //(last==2)
        else 
        dp[p][q][r][last] = countWays(p, q, r - 1, 0) + 
                            countWays(p, q, r - 1, 1);
      
        return dp[p][q][r][last];
    }
      
    // Returns count of required arrangements
    static int countUtil(int p, int q, int r)
    {
        // Initialize 'dp' array
        for (int[][][] row : dp)
        {
            for (int[][] innerRow : row) 
            {
                for (int[] innerInnerRow : innerRow)
                {
                    Arrays.fill(innerInnerRow, -1);
                }
            }
        };
      
        // Three cases arise:
        return countWays(p, q, r, 0) + // Last required balls is type P
            countWays(p, q, r, 1) +    // Last required balls is type Q
            countWays(p, q, r, 2);       // Last required balls is type R
    }
  
    // Driver code
    public static void main(String[] args)
    {
        int p = 1, q = 1, r = 1;
        System.out.print(countUtil(p, q, r));
    }
}

2957
Chapter 412. Ways to arrange Balls such that adjacent balls are of different types

  
// This code is contributed by Anant Agarwal.

Output:

Time complexity : O(p*q*r)


Auxiliary Space : O(p*q*r*3)
Improved By : nitin mittal, Mithun Kumar

Source

https://www.geeksforgeeks.org/ways-to-arrange-balls-such-that-adjacent-balls-are-of-different-types/

2958
Chapter 413

Ways to sum to N using array


elements with repetition allowed

Ways to sum to N using array elements with repetition allowed - GeeksforGeeks


Given a set of m distinct positive integers and a value ‘N’. The problem is to count the
total number of ways we can form ‘N’ by doing sum of the array elements. Repetitions and
different arrangements are allowed.
Examples :

Input : arr = {1, 5, 6}, N = 7


Output : 6

Explanation:- The different ways are:


1+1+1+1+1+1+1
1+1+5
1+5+1
5+1+1
1+6
6+1

Input : arr = {12, 3, 1, 9}, N = 14


Output : 150

Approach: The approach is based on the concept of dynamic programming.

countWays(arr, m, N)
Declare and initialize count[N + 1] = {0}
count[0] = 1
for i = 1 to N

2959
Chapter 413. Ways to sum to N using array elements with repetition allowed

for j = 0 to m - 1
if i >= arr[j]
count[i] += count[i - arr[j]]
return count[N]

C++

// C++ implementation to count ways 


// to sum up to a given value N
#include <bits/stdc++.h>
  
using namespace std;
  
// function to count the total 
// number of ways to sum up to 'N'
int countWays(int arr[], int m, int N)
{
    int count[N + 1];
    memset(count, 0, sizeof(count));
      
    // base case
    count[0] = 1;
      
    // count ways for all values up 
    // to 'N' and store the result
    for (int i = 1; i <= N; i++)
        for (int j = 0; j < m; j++)
  
            // if i >= arr[j] then
            // accumulate count for value 'i' as
            // ways to form value 'i-arr[j]'
            if (i >= arr[j])
                count[i] += count[i - arr[j]];
      
    // required number of ways 
    return count[N]; 
      
}
  
// Driver code
int main()
{
    int arr[] = {1, 5, 6};
    int m = sizeof(arr) / sizeof(arr[0]);
    int N = 7;
    cout << "Total number of ways = "
        << countWays(arr, m, N);
    return 0;

2960
Chapter 413. Ways to sum to N using array elements with repetition allowed

Java

// Java implementation to count ways  


// to sum up to a given value N
  
class Gfg
{
    static int arr[] = {1, 5, 6};
      
    // method to count the total number
    // of ways to sum up to 'N'
    static int countWays(int N)
    {
        int count[] = new int[N + 1];
          
        // base case
        count[0] = 1;
          
        // count ways for all values up 
        // to 'N' and store the result
        for (int i = 1; i <= N; i++)
            for (int j = 0; j < arr.length; j++)
      
                // if i >= arr[j] then
                // accumulate count for value 'i' as
                // ways to form value 'i-arr[j]'
                if (i >= arr[j])
                    count[i] += count[i - arr[j]];
          
        // required number of ways 
        return count[N]; 
          
    }
      
    // Driver code
    public static void main(String[] args) 
    {
        int N = 7;
        System.out.println("Total number of ways = "
                                    + countWays(N));
    }
}

Python3

   

2961
Chapter 413. Ways to sum to N using array elements with repetition allowed

# Python3 implementation to count 


# ways to sum up to a given value N
  
# Function to count the total 
# number of ways to sum up to 'N'
def countWays(arr, m, N):
  
    count = [0 for i in range(N + 1)]
      
    # base case
    count[0] = 1
      
    # Count ways for all values up 
    # to 'N' and store the result
    for i in range(1, N + 1):
        for j in range(m):
  
            # if i >= arr[j] then
            # accumulate count for value 'i' as
            # ways to form value 'i-arr[j]'
            if (i >= arr[j]):
                count[i] += count[i - arr[j]]
      
    # required number of ways 
    return count[N]
      
# Driver Code
arr = [1, 5, 6]
m = len(arr)
N = 7
print("Total number of ways = ",
           countWays(arr, m, N))
             
# This code is contributed by Anant Agarwal.

C#

// C# implementation to count ways  


// to sum up to a given value N
using System;
  
class Gfg
{
    static int []arr = {1, 5, 6};
      
    // method to count the total number
    // of ways to sum up to 'N'
    static int countWays(int N)

2962
Chapter 413. Ways to sum to N using array elements with repetition allowed

    {
        int []count = new int[N+1];
          
        // base case
        count[0] = 1;
          
        // count ways for all values up 
        // to 'N' and store the result
        for (int i = 1; i <= N; i++)
            for (int j = 0; j < arr.Length; j++)
      
                // if i >= arr[j] then
                // accumulate count for value 'i' as
                // ways to form value 'i-arr[j]'
                if (i >= arr[j])
                    count[i] += count[i - arr[j]];
          
        // required number of ways 
        return count[N]; 
          
    }
      
    // Driver code
    public static void Main() 
    {
        int N = 7;
        Console.Write("Total number of ways = "
                                    + countWays(N));
    }
}
  
//This code is contributed by nitin mittal.

Output:

Total number of ways = 6

Time Complexity: O(N*m)


Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/ways-sum-n-using-array-elements-repetition-allowed/

2963
Chapter 414

Ways to write n as sum of two


or more positive integers

Ways to write n as sum of two or more positive integers - GeeksforGeeks


For a given number n > 0, find the number of different ways in which n can be written as
a sum of at two or more positive integers.
Examples:

Input : n = 5
Output : 6
Explanation : All possible six ways are :
4 + 1
3 + 2
3 + 1 + 1
2 + 2 + 1
2 + 1 + 1 + 1
1 + 1 + 1 + 1 + 1

Input : 4
Output : 4
Explanation : All possible four ways are :
3 + 1
2 + 2
2 + 1 + 1
1 + 1 + 1 + 1

This problem can be solved in the similar fashion as coin change problem, the difference is
only that in this case we should iterate for 1 to n-1 instead of particular values of coin as in
coin-change problem.
C/C++

2964
Chapter 414. Ways to write n as sum of two or more positive integers

// Program to find the number of ways, n can be


// written as sum of two or more positive integers.
#include <bits/stdc++.h>
using namespace std;
  
// Returns number of ways to write n as sum of
// two or more positive integers
int countWays(int n)
{
    // table[i] will be storing the number of
    // solutions for value i. We need n+1 rows
    // as the table is consturcted in bottom up
    // manner using the base case (n = 0)
    int table[n+1];
  
    // Initialize all table values as 0
    memset(table, 0, sizeof(table));
  
    // Base case (If given value is 0)
    table[0] = 1;
  
    // Pick all integer one by one and update the
    // table[] values after the index greater
    // than or equal to n
    for (int i=1; i<n; i++)
        for (int j=i; j<=n; j++)
            table[j] += table[j-i];
  
    return table[n];
}
  
// Driver program
int main()
{
    int n = 7;
    cout << countWays(n);
    return 0;
}

Java

// Program to find the number of ways, 


// n can be written as sum of two or 
// more positive integers.
import java.util.Arrays;
  
class GFG {
      

2965
Chapter 414. Ways to write n as sum of two or more positive integers

    // Returns number of ways to write


    // n as sum of two or more positive 
    // integers
    static int countWays(int n)
    {
          
        // table[i] will be storing the 
        // number of solutions for value
        // i. We need n+1 rows as the 
        // table is consturcted in bottom
        // up manner using the base case
        // (n = 0)
        int table[] = new int[n + 1];
      
        // Initialize all table values as 0
        Arrays.fill(table, 0);
      
        // Base case (If given value is 0)
        table[0] = 1;
      
        // Pick all integer one by one and
        // update the table[] values after 
        // the index greater than or equal 
        // to n
        for (int i = 1; i < n; i++)
            for (int j = i; j <= n; j++)
                table[j] += table[j - i];
      
        return table[n];
    }
      
    //driver code
    public static void main (String[] args)
    {
        int n = 7;
          
        System.out.print(countWays(n));
    }
}
  
// This code is contributed by Anant Agarwal.

Python

# Program to find the number of ways, n can be


# written as sum of two or more positive integers.
  
# Returns number of ways to write n as sum of

2966
Chapter 414. Ways to write n as sum of two or more positive integers

# two or more positive integers


def CountWays(n):
  
    # table[i] will be storing the number of
    # solutions for value i. We need n+1 rows
    # as the table is consturcted in bottom up
    # manner using the base case (n = 0)
    # Initialize all table values as 0
    table =[0] * (n + 1)
  
    # Base case (If given value is 0)
    # Only 1 way to get 0 (select no integer)
    table[0] = 1
  
    # Pick all integer one by one and update the
    # table[] values after the index greater
    # than or equal to n
    for i in range(1, n ):
  
        for j in range(i , n + 1):
  
            table[j] +=  table[j - i]            
  
    return table[n]
  
# driver program
def main():
  
    n = 7
  
    print CountWays(n)
  
if __name__ == '__main__':
    main()
  
#This code is contributed by Neelam Yadav

C#

// Program to find the number of ways, n can be


// written as sum of two or more positive integers.
using System;
  
class GFG {
      
    // Returns number of ways to write n as sum of
    // two or more positive integers
    static int countWays(int n)

2967
Chapter 414. Ways to write n as sum of two or more positive integers

    {
          
        // table[i] will be storing the number of
        // solutions for value i. We need n+1 rows
        // as the table is consturcted in bottom up
        // manner using the base case (n = 0)
        int []table = new int[n+1];
       
        // Initialize all table values as 0
        for(int i = 0; i < table.Length; i++)
            table[i] = 0;
       
        // Base case (If given value is 0)
        table[0] = 1;
       
        // Pick all integer one by one and update the
        // table[] values after the index greater
        // than or equal to n
        for (int i = 1; i < n; i++)
            for (int j = i; j <= n; j++)
                table[j] += table[j-i];
       
        return table[n];
    }
      
    //driver code
    public static void Main()
    {
        int n = 7;
          
        Console.Write(countWays(n));
    }
}
  
//This code is contributed by Anant Agarwal.

Output:

14

Time complexity O(n2 )

Source

https://www.geeksforgeeks.org/ways-to-write-n-as-sum-of-two-or-more-positive-integers/

2968
Chapter 415

Weighted Job Scheduling

Weighted Job Scheduling - GeeksforGeeks


Given N jobs where every job is represented by following three elements of it.

1. Start Time
2. Finish Time
3. Profit or Value Associated

Find the maximum profit subset of jobs such that no two jobs in the subset overlap.
Example:

Input: Number of Jobs n = 4


Job Details {Start Time, Finish Time, Profit}
Job 1: {1, 2, 50}
Job 2: {3, 5, 20}
Job 3: {6, 19, 100}
Job 4: {2, 100, 200}
Output: The maximum profit is 250.
We can get the maximum profit by scheduling jobs 1 and 4.
Note that there is longer schedules possible Jobs 1, 2 and 3
but the profit with this schedule is 20+50+100 which is less than 250.

A simple version of this problem is discussed herewhere every job has same profit or value.
The Greedy Strategy for activity selection doesn’t work here as a schedule with more jobs
may have smaller profit or value.
The above problem can be solved using following recursive solution.

1) First sort jobs according to finish time.

2969
Chapter 415. Weighted Job Scheduling

2) Now apply following recursive process.


// Here arr[] is array of n jobs
findMaximumProfit(arr[], n)
{
a) if (n == 1) return arr[0];
b) Return the maximum of following two profits.
(i) Maximum profit by excluding current job, i.e.,
findMaximumProfit(arr, n-1)
(ii) Maximum profit by including the current job
}

How to find the profit including current job?


The idea is to find the latest job before the current job (in
sorted array) that doesn't conflict with current job 'arr[n-1]'.
Once we find such a job, we recur for all jobs till that job and
add profit of current job to result.
In the above example, "job 1" is the latest non-conflicting
for "job 4" and "job 2" is the latest non-conflicting for "job 3".

The following is C++ implementation of above naive recursive method.

// C++ program for weighted job scheduling using Naive Recursive Method
#include <iostream>
#include <algorithm>
using namespace std;
  
// A job has start time, finish time and profit.
struct Job
{
    int start, finish, profit;
};
  
// A utility function that is used for sorting events
// according to finish time
bool jobComparataor(Job s1, Job s2)
{
    return (s1.finish < s2.finish);
}
  
// Find the latest job (in sorted array) that doesn't
// conflict with the job[i]. If there is no compatible job,
// then it returns -1.
int latestNonConflict(Job arr[], int i)
{
    for (int j=i-1; j>=0; j--)
    {
        if (arr[j].finish <= arr[i-1].start)

2970
Chapter 415. Weighted Job Scheduling

            return j;
    }
    return -1;
}
  
// A recursive function that returns the maximum possible
// profit from given array of jobs.  The array of jobs must
// be sorted according to finish time.
int findMaxProfitRec(Job arr[], int n)
{
    // Base case
    if (n == 1) return arr[n-1].profit;
  
    // Find profit when current job is inclueded
    int inclProf = arr[n-1].profit;
    int i = latestNonConflict(arr, n);
    if (i != -1)
      inclProf += findMaxProfitRec(arr, i+1);
  
    // Find profit when current job is excluded
    int exclProf = findMaxProfitRec(arr, n-1);
  
    return max(inclProf,  exclProf);
}
  
// The main function that returns the maximum possible
// profit from given array of jobs
int findMaxProfit(Job arr[], int n)
{
    // Sort jobs according to finish time
    sort(arr, arr+n, jobComparataor);
  
    return findMaxProfitRec(arr, n);
}
  
// Driver program
int main()
{
    Job arr[] = {{3, 10, 20}, {1, 2, 50}, {6, 19, 100}, {2, 100, 200}};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "The optimal profit is " << findMaxProfit(arr, n);
    return 0;
}

Output:

The optimal profit is 250

2971
Chapter 415. Weighted Job Scheduling

The above solution may contain many overlapping subproblems. For example if lastNon-
Conflicting() always returns previous job, then findMaxProfitRec(arr, n-1) is called twice
and the time complexity becomes O(n*2n ). As another example when lastNonConflicting()
returns previous to previous job, there are two recursive calls, for n-2 and n-1. In this
example case, recursion becomes same as Fibonacci Numbers.
So this problem has both properties of Dynamic Programming, Optimal Substructureand
Overlapping Subproblems.
Like other Dynamic Programming Problems, we can solve this problem by making a table
that stores solution of subproblems.
Below is C++ implementation based on Dynamic Programming.

// C++ program for weighted job scheduling using Dynamic Programming.


#include <iostream>
#include <algorithm>
using namespace std;
  
// A job has start time, finish time and profit.
struct Job
{
    int start, finish, profit;
};
  
// A utility function that is used for sorting events
// according to finish time
bool jobComparataor(Job s1, Job s2)
{
    return (s1.finish < s2.finish);
}
  
// Find the latest job (in sorted array) that doesn't
// conflict with the job[i]
int latestNonConflict(Job arr[], int i)
{
    for (int j=i-1; j>=0; j--)
    {
        if (arr[j].finish <= arr[i].start)
            return j;
    }
    return -1;
}
  
// The main function that returns the maximum possible
// profit from given array of jobs
int findMaxProfit(Job arr[], int n)
{
    // Sort jobs according to finish time
    sort(arr, arr+n, jobComparataor);
  

2972
Chapter 415. Weighted Job Scheduling

    // Create an array to store solutions of subproblems.  table[i]


    // stores the profit for jobs till arr[i] (including arr[i])
    int *table = new int[n];
    table[0] = arr[0].profit;
  
    // Fill entries in M[] using recursive property
    for (int i=1; i<n; i++)
    {
        // Find profit including the current job
        int inclProf = arr[i].profit;
        int l = latestNonConflict(arr, i);
        if (l != -1)
            inclProf += table[l];
  
        // Store maximum of including and excluding
        table[i] = max(inclProf, table[i-1]);
    }
  
    // Store result and free dynamic memory allocated for table[]
    int result = table[n-1];
    delete[] table;
  
    return result;
}
  
// Driver program
int main()
{
    Job arr[] = {{3, 10, 20}, {1, 2, 50}, {6, 19, 100}, {2, 100, 200}};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "The optimal profit is " << findMaxProfit(arr, n);
    return 0;
}

Output:

The optimal profit is 250

Time Complexity of the above Dynamic Programming Solution is O(n2 ). Note that the
above solution can be optimized to O(nLogn) using Binary Search in latestNonConflict()
instead of linear search. Thanks to Garvit for suggesting this optimization. Please refer
below post for details.
Weighted Job Scheduling in O(n Log n) time
References:
http://courses.cs.washington.edu/courses/cse521/13wi/slides/06dp-sched.pdf

2973
Chapter 415. Weighted Job Scheduling

This article is contributed by Shivam. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/weighted-job-scheduling/

2974
Chapter 416

Weighted Job Scheduling in O(n


Log n) time

Weighted Job Scheduling in O(n Log n) time - GeeksforGeeks


Given N jobs where every job is represented by following three elements of it.

1. Start Time
2. Finish Time
3. Profit or Value Associated

Find the maximum profit subset of jobs such that no two jobs in the subset overlap.
Example:

Input: Number of Jobs n = 4


Job Details {Start Time, Finish Time, Profit}
Job 1: {1, 2, 50}
Job 2: {3, 5, 20}
Job 3: {6, 19, 100}
Job 4: {2, 100, 200}
Output: The maximum profit is 250.
We can get the maximum profit by scheduling jobs 1 and 4.
Note that there is longer schedules possible Jobs 1, 2 and 3
but the profit with this schedule is 20+50+100 which is less than 250.

We strongly recommend to refer below article as a prerequisite for this.


Weighted Job Scheduling
The above problem can be solved using following recursive solution.

2975
Chapter 416. Weighted Job Scheduling in O(n Log n) time

1) First sort jobs according to finish time.


2) Now apply following recursive process.
// Here arr[] is array of n jobs
findMaximumProfit(arr[], n)
{
a) if (n == 1) return arr[0];
b) Return the maximum of following two profits.
(i) Maximum profit by excluding current job, i.e.,
findMaximumProfit(arr, n-1)
(ii) Maximum profit by including the current job
}

How to find the profit including current job?


The idea is to find the latest job before the current job (in
sorted array) that doesn't conflict with current job 'arr[n-1]'.
Once we find such a job, we recur for all jobs till that job and
add profit of current job to result.
In the above example, "job 1" is the latest non-conflicting
for "job 4" and "job 2" is the latest non-conflicting for "job 3".

We have discussed recursive and Dynamic Programming based approaches in the previous
article. The implementations discussed in above post uses linear search to find the previous
non-conflicting job. In this post, Binary Search based solution is discussed. The time
complexity of Binary Search based solution is O(n Log n).
The algorithm is:

1. Sort the jobs by non-decreasing finish times.


2. For each i from 1 to n, determine the maximum value of the schedule from the sub-
sequence of jobs[0..i]. Do this by comparing the inclusion of job[i] to the schedule to
the exclusion of job[i] to the schedule, and then taking the max.

To find the profit with inclusion of job[i]. we need to find the latest job that doesn’t conflict
with job[i]. The idea is to use Binary Search to find the latest non-conflicting job.
C/C++

// C++ program for weighted job scheduling using Dynamic 


// Programming and Binary Search
#include <iostream>
#include <algorithm>
using namespace std;
  
// A job has start time, finish time and profit.
struct Job
{
    int start, finish, profit;

2976
Chapter 416. Weighted Job Scheduling in O(n Log n) time

};
  
// A utility function that is used for sorting events
// according to finish time
bool myfunction(Job s1, Job s2)
{
    return (s1.finish < s2.finish);
}
  
// A Binary Search based function to find the latest job
// (before current job) that doesn't conflict with current
// job.  "index" is index of the current job.  This function
// returns -1 if all jobs before index conflict with it.
// The array jobs[] is sorted in increasing order of finish
// time.
int binarySearch(Job jobs[], int index)
{
    // Initialize 'lo' and 'hi' for Binary Search
    int lo = 0, hi = index - 1;
  
    // Perform binary Search iteratively
    while (lo <= hi)
    {
        int mid = (lo + hi) / 2;
        if (jobs[mid].finish <= jobs[index].start)
        {
            if (jobs[mid + 1].finish <= jobs[index].start)
                lo = mid + 1;
            else
                return mid;
        }
        else
            hi = mid - 1;
    }
  
    return -1;
}
  
// The main function that returns the maximum possible
// profit from given array of jobs
int findMaxProfit(Job arr[], int n)
{
    // Sort jobs according to finish time
    sort(arr, arr+n, myfunction);
  
    // Create an array to store solutions of subproblems.  table[i]
    // stores the profit for jobs till arr[i] (including arr[i])
    int *table = new int[n];

2977
Chapter 416. Weighted Job Scheduling in O(n Log n) time

    table[0] = arr[0].profit;
  
    // Fill entries in table[] using recursive property
    for (int i=1; i<n; i++)
    {
        // Find profit including the current job
        int inclProf = arr[i].profit;
        int l = binarySearch(arr, i);
        if (l != -1)
            inclProf += table[l];
  
        // Store maximum of including and excluding
        table[i] = max(inclProf, table[i-1]);
    }
  
    // Store result and free dynamic memory allocated for table[]
    int result = table[n-1];
    delete[] table;
  
    return result;
}
  
// Driver program
int main()
{
    Job arr[] = {{3, 10, 20}, {1, 2, 50}, {6, 19, 100}, {2, 100, 200}};
    int n = sizeof(arr)/sizeof(arr[0]);
    cout << "Optimal profit is " << findMaxProfit(arr, n);
    return 0;
}

Python

# Python program for weighted job scheduling using Dynamic 


# Programming and Binary Search
  
# Class to represent a job
class Job:
    def __init__(self, start, finish, profit):
        self.start  = start
        self.finish = finish
        self.profit  = profit
  
  
# A Binary Search based function to find the latest job
# (before current job) that doesn't conflict with current
# job.  "index" is index of the current job.  This function
# returns -1 if all jobs before index conflict with it.

2978
Chapter 416. Weighted Job Scheduling in O(n Log n) time

# The array jobs[] is sorted in increasing order of finish


# time.
def binarySearch(job, start_index):
  
    # Initialize 'lo' and 'hi' for Binary Search
    lo = 0
    hi = start_index - 1
  
    # Perform binary Search iteratively
    while lo <= hi:
        mid = (lo + hi) // 2
        if job[mid].finish <= job[start_index].start:
            if job[mid + 1].finish <= job[start_index].start:
                lo = mid + 1
            else:
                return mid
        else:
            hi = mid - 1
    return -1
  
# The main function that returns the maximum possible
# profit from given array of jobs
def schedule(job):
    
    # Sort jobs according to finish time
    job = sorted(job, key = lambda j: j.finish)
  
    # Create an array to store solutions of subproblems.  table[i]
    # stores the profit for jobs till arr[i] (including arr[i])
    n = len(job) 
    table = [0 for _ in range(n)]
  
    table[0] = job[0].profit;
  
    # Fill entries in table[] using recursive property
    for i in range(1, n):
  
        # Find profit including the current job
        inclProf = job[i].profit
        l = binarySearch(job, i)
        if (l != -1):
            inclProf += table[l];
  
        # Store maximum of including and excluding
        table[i] = max(inclProf, table[i - 1])
  
    return table[n-1]
  

2979
Chapter 416. Weighted Job Scheduling in O(n Log n) time

# Driver code to test above function


job = [Job(1, 2, 50), Job(3, 5, 20), 
      Job(6, 19, 100), Job(2, 100, 200)]
print("Optimal profit is"),
print schedule(job)

Java

// Java program for Weighted Job Scheduling in O(nLogn)


// time
import java.util.Arrays;
import java.util.Comparator;
  
// Class to represent a job
class Job
{
    int start, finish, profit;
  
    // Constructor
    Job(int start, int finish, int profit)
    {
        this.start = start;
        this.finish = finish;
        this.profit = profit;
    }
}
  
// Used to sort job according to finish times
class JobComparator implements Comparator<Job>
{
    public int compare(Job a, Job b)
    {
        return a.finish < b.finish ? -1 : a.finish == b.finish ? 0 : 1;
    }
}
  
public class WeightedIntervalScheduling
{
    /* A Binary Search based function to find the latest job
      (before current job) that doesn't conflict with current
      job.  "index" is index of the current job.  This function
      returns -1 if all jobs before index conflict with it.
      The array jobs[] is sorted in increasing order of finish
      time. */
    static public int binarySearch(Job jobs[], int index)
    {
        // Initialize 'lo' and 'hi' for Binary Search
        int lo = 0, hi = index - 1;

2980
Chapter 416. Weighted Job Scheduling in O(n Log n) time

  
        // Perform binary Search iteratively
        while (lo <= hi)
        {
            int mid = (lo + hi) / 2;
            if (jobs[mid].finish <= jobs[index].start)
            {
                if (jobs[mid + 1].finish <= jobs[index].start)
                    lo = mid + 1;
                else
                    return mid;
            }
            else
                hi = mid - 1;
        }
  
        return -1;
    }
  
    // The main function that returns the maximum possible
    // profit from given array of jobs
    static public int schedule(Job jobs[])
    {
        // Sort jobs according to finish time
        Arrays.sort(jobs, new JobComparator());
  
        // Create an array to store solutions of subproblems.
        // table[i] stores the profit for jobs till jobs[i]
        // (including jobs[i])
        int n = jobs.length;
        int table[] = new int[n];
        table[0] = jobs[0].profit;
  
        // Fill entries in M[] using recursive property
        for (int i=1; i<n; i++)
        {
            // Find profit including the current job
            int inclProf = jobs[i].profit;
            int l = binarySearch(jobs, i);
            if (l != -1)
                inclProf += table[l];
  
            // Store maximum of including and excluding
            table[i] = Math.max(inclProf, table[i-1]);
        }
  
        return table[n-1];
    }

2981
Chapter 416. Weighted Job Scheduling in O(n Log n) time

  
    // Driver method to test above
    public static void main(String[] args)
    {
        Job jobs[] = {new Job(1, 2, 50), new Job(3, 5, 20),
                      new Job(6, 19, 100), new Job(2, 100, 200)};
  
        System.out.println("Optimal profit is " + schedule(jobs));
    }
}

Output:

Optimal profit is 250

This article is contributed by Daniel Ray. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above

Source

https://www.geeksforgeeks.org/weighted-job-scheduling-log-n-time/

2982
Chapter 417

Weighted Job Scheduling | Set 2


(Using LIS)

Weighted Job Scheduling | Set 2 (Using LIS) - GeeksforGeeks


Given N jobs where every job is represented by following three elements of it.
1. Start Time
2. Finish Time
3. Profit or Value Associated
Find the maximum profit subset of jobs such that no two jobs in the subset overlap.
Examples:

Input:
Number of Jobs n = 4
Job Details {Start Time, Finish Time, Profit}
Job 1: {1, 2, 50}
Job 2: {3, 5, 20}
Job 3: {6, 19, 100}
Job 4: {2, 100, 200}

Output:
Job 1: {1, 2, 50}
Job 4: {2, 100, 200}

Explaination: We can get the maximum profit by


scheduling jobs 1 and 4 and maximum profit is 250.

In previous post, we have discussed about Weighted Job Scheduling problem. We discussed
a DP solution where we basically includes or excludes current job. In this post, another
interesting DP solution is discussed where we also print the Jobs. This problem is a variation

2983
Chapter 417. Weighted Job Scheduling | Set 2 (Using LIS)

of standard Longest Increasing Subsequence (LIS) problem. We need a slight change in the
Dynamic Programming solution of LIS problem.
We first need to sort jobs according to start time. Let job[0..n-1] be the array of jobs after
sorting. We define vector L such that L[i] is itself is a vector that stores Weighted Job
Scheduling of job[0..i] that ends with job[i]. Therefore for an index i, L[i] can be recursively
written as –

L[0] = {job[0]}
L[i] = {MaxSum(L[j])} + job[i] where j < i and job[j].finish <= job[i].start
= job[i], if there is no such j

For example, consider pairs {3, 10, 20}, {1, 2, 50}, {6, 19, 100}, {2, 100, 200}

After sorting we get,


{1, 2, 50}, {2, 100, 200}, {3, 10, 20}, {6, 19, 100}

Therefore,
L[0]: {1, 2, 50}
L[1]: {1, 2, 50} {2, 100, 200}
L[2]: {1, 2, 50} {3, 10, 20}
L[3]: {1, 2, 50} {6, 19, 100}

We choose the vector with highest profit. In this case, L[1].


Below is C++ implementation of above idea –

// C++ program for weighted job scheduling using LIS


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
  
// A job has start time, finish time and profit.
struct Job
{
    int start, finish, profit;
};
  
// Utility function to calculate sum of all vector
// elements
int findSum(vector<Job> arr)
{
    int sum = 0;
    for (int i = 0; i < arr.size(); i++)
        sum +=  arr[i].profit;

2984
Chapter 417. Weighted Job Scheduling | Set 2 (Using LIS)

    return sum;
}
  
// The main function that finds the maximum possible
// profit from given array of jobs
void findMaxProfit(vector<Job> &arr)
{
    // Sort arr[] by start time.
    sort(arr.begin(), arr.end(), compare);
  
    // L[i] stores stores Weighted Job Scheduling of
    // job[0..i] that ends with job[i]
    vector<vector<Job>> L(arr.size());
  
    // L[0] is equal to arr[0]
    L[0].push_back(arr[0]);
  
    // start from index 1
    for (int i = 1; i < arr.size(); i++)
    {
        // for every j less than i
        for (int j = 0; j < i; j++)
        {
            // L[i] = {MaxSum(L[j])} + arr[i] where j < i
            // and arr[j].finish <= arr[i].start
            if ((arr[j].finish <= arr[i].start) &&
                (findSum(L[j]) > findSum(L[i])))
                L[i] = L[j];
        }
        L[i].push_back(arr[i]);
    }
  
    vector<Job> maxChain;
  
    // find one with max profit
    for (int i = 0; i < L.size(); i++)
        if (findSum(L[i]) > findSum(maxChain))
            maxChain = L[i];
  
    for (int i = 0; i < maxChain.size(); i++)
        cout << "(" <<  maxChain[i].start << ", " <<
             maxChain[i].finish << ", "
             <<  maxChain[i].profit << ") ";
}
  
// comparator function for sort function
int compare(Job x, Job y)
{

2985
Chapter 417. Weighted Job Scheduling | Set 2 (Using LIS)

    return x.start < y.start;


}
  
// Driver Function
int main()
{
    Job a[] = { {3, 10, 20}, {1, 2, 50}, {6, 19, 100},
                {2, 100, 200} };
    int n = sizeof(a) / sizeof(a[0]);
  
    vector<Job> arr(a, a + n);
  
    findMaxProfit(arr);
  
    return 0;
}

Output:

(1, 2, 50) (2, 100, 200)

We can further optimize above DP solution by removing findSum() function. Instead, we


can maintain another vector/array to store sum of maximum profit possible till job i. The
implementation can be seen here.
Time complexity of above Dynamic Programming solution is O(n2 ) where n is the number
of Jobs.
Auxiliary space used by the program is O(n2 ).

Source

https://www.geeksforgeeks.org/weighted-job-scheduling-set-2-using-lis/

2986
Chapter 418

Weird Number

Weird Number - GeeksforGeeks


In number theory, a weird number is a natural number that is abundant but not semiperfect.
In other words, the sum of the proper divisors (divisors including 1 but not itself) of the
number is greater than the number, but no subset of those divisors sums to the number
itself.
Given a number N, the task is to check if the number is weird or not.
Examples:

Input: 40
Output: The number is not weird
1+4+5+10+20=40, hence it is not weird.
Input: 70
Output: The number is Weird
The smallest weird number is 70. Its proper divisors are 1, 2, 5, 7, 10, 14, and
35; these sum to 74, but no subset of these sums to 70.
The number 12, for example, is abundant but not weird, because the proper
divisors of 12 are 1, 2, 3, 4, and 6, which sum to 16; but 2+4+6 = 12. The
first few weird numbers are 70, 836, 4030, 5830, 7192, 7912, 9272, 10430, 10570,
10792, 10990, 11410, 11690, 12110, 12530, 12670, 13370, 13510, ..

Approach: Check if the number is abundant or not. The approach has been discussed here.
Once the checking has been done check if the number is semiperfect or not. The approach
for checking semiperfects numbers has been discussed here.
Below is the implementation of the above approach:

C++

// C++ program to check if the 

2987
Chapter 418. Weird Number

// number is weird or not


#include <bits/stdc++.h>
using namespace std;
  
// code to find all the factors of
// the number excluding the number itself
vector<int> factors(int n)
{
    // vector to store the factors
    vector<int> v;
    v.push_back(1);
  
    // note that this loop runs till sqrt(n)
    for (int i = 2; i <= sqrt(n); i++) {
  
        // if the value of i is a factor
        if (n % i == 0) {
            v.push_back(i);
  
            // condition to check the
            // divisor is not the number itself
            if (n / i != i) {
                v.push_back(n / i);
            }
        }
    }
    // return the vector
    return v;
}
  
// Function to check if the number 
// is abundant or not 
bool checkAbundant(int n)
{
    vector<int> v;
  
    int sum = 0;
  
    // find the divisors using function
    v = factors(n);
  
    // sum all the factors
    for (int i = 0; i < v.size(); i++) {
        sum += v[i];
    }
  
    // check for abundant or not
    if (sum > n)

2988
Chapter 418. Weird Number

        return true;
    else
        return false;
}
  
// Function to check if the
// number is semi-perfecr or not
bool checkSemiPerfect(int n)
{
    vector<int> v;
  
    // find the divisors
    v = factors(n);
  
    // sorting the vector
    sort(v.begin(), v.end());
  
    int r = v.size();
  
    // subset to check if no is semiperfect
    bool subset[r + 1][n + 1];
  
    // initialising 1st column to true
    for (int i = 0; i <= r; i++)
        subset[i][0] = true;
  
    // initialing 1st row except zero position to 0
    for (int i = 1; i <= n; i++)
        subset[0][i] = false;
  
    // loop to find whther the number is semiperfect
    for (int i = 1; i <= r; i++) {
        for (int j = 1; j <= n; j++) {
  
            // calculation to check if the
            // number can be made by summation of diviors
            if (j < v[i - 1])
                subset[i][j] = subset[i - 1][j];
            else {
                subset[i][j] = subset[i - 1][j] || 
                               subset[i - 1][j - v[i - 1]];
            }
        }
    }
  
    // if not possible to make the
    // number by any combination of divisors
    if ((subset[r][n]) == 0)

2989
Chapter 418. Weird Number

        return false;
    else
        return true;
}
  
// Function to check for 
// weird or not 
bool checkweird(int n)
{
    if (checkAbundant(n) == true && 
        checkSemiPerfect(n) == false)
        return true;
    else
        return false;
}
  
// Driver Code
int main()
{
    int n = 70;
  
    if (checkweird(n))
        cout << "Weird Number";
    else
        cout << "Not Weird Number";
    return 0;
}

Java

// Java program to check if  


// the number is weird or not
import java.util.*;
class GFG

// code to find all the 
// factors of the number 
// excluding the number itself
static ArrayList<Integer> factors(int n)
{
    // ArrayList to store
    // the factors
    ArrayList<Integer> v = new ArrayList<Integer>();
    v.add(1);
  
    // note that this loop 
    // runs till sqrt(n)
    for (int i = 2;

2990
Chapter 418. Weird Number

             i <= Math.sqrt(n); i++)


    {
  
        // if the value of 
        // i is a factor
        if (n % i == 0) 
        {
            v.add(i);
  
            // condition to check 
            // the divisor is not 
            // the number itself
            if (n / i != i) 
            {
                v.add(n / i);
            }
        }
    }
      
    // return the ArrayList
    return v;
}
  
// Function to check if the 
// number is abundant or not 
static boolean checkAbundant(int n)
{
    ArrayList<Integer> v;
  
    int sum = 0;
  
    // find the divisors
    // using function
    v = factors(n);
  
    // sum all the factors
    for (int i = 0; i < v.size(); i++) 
    {
        sum += v.get(i);
    }
  
    // check for abundant
    // or not
    if (sum > n)
        return true;
    else
        return false;
}

2991
Chapter 418. Weird Number

  
// Function to check if the
// number is semi-perfecr or not
static boolean checkSemiPerfect(int n)
{
    ArrayList<Integer> v;
  
    // find the divisors
    v = factors(n);
  
    // sorting the ArrayList
    Collections.sort(v);
  
    int r = v.size();
  
    // subset to check if 
    // no is semiperfect
    boolean subset[][] = new boolean[r + 1][n + 1];
  
    // initialising 1st
    // column to true
    for (int i = 0; i <= r; i++)
        subset[i][0] = true;
  
    // initialing 1st row except 
    // zero position to 0
    for (int i = 1; i <= n; i++)
        subset[0][i] = false;
  
    // loop to find whther 
    // the number is semiperfect
    for (int i = 1; i <= r; i++) 
    {
        for (int j = 1; j <= n; j++) 
        {
  
            // calculation to check 
            // if the number can be 
            // made by summation of 
            // diviors
            if (j < v.get(i - 1))
                subset[i][j] = subset[i - 1][j];
            else {
                subset[i][j] = subset[i - 1][j] || 
                               subset[i - 1][j - 
                                v.get(i - 1)];
            }
        }

2992
Chapter 418. Weird Number

    }
  
    // if not possible to make 
    // the number by any 
    // combination of divisors
    if ((subset[r][n]) == false)
        return false;
    else
        return true;
}
  
// Function to check 
// for weird or not 
static boolean checkweird(int n)
{
    if (checkAbundant(n) == true && 
        checkSemiPerfect(n) == false)
        return true;
    else
        return false;
}
  
// Driver Code
public static void main(String args[])
{
    int n = 70;
  
    if (checkweird(n))
        System.out.println("Weird Number");
    else
        System.out.println("Not Weird Number");
}
}
  
// This code is contributed
// by Arnab Kundu

Output:

Weird Number

Time Complexity: O(N * number of factors)


Auxiliary Space: O(N * number of factors)
Improved By : andrew1234

2993
Chapter 418. Weird Number

Source

https://www.geeksforgeeks.org/weird-number/

2994
Chapter 419

WildCard pattern matching


having three symbols ( * , + , ?
)

WildCard pattern matching having three symbols ( * , + , ? ) - GeeksforGeeks


Given a text and a wildcard pattern, implement wildcard pattern matching algorithm that
finds if wildcard pattern is matched with text. The matching should cover the entire text
(not partial text).
The wildcard pattern can include the characters ‘?’, ‘*’ and ‘+’.

‘?’ – matches any single character


‘*’ – Matches any sequence of characters
(including the empty sequence)
'+' – Matches previous single character
of pattern

Examples:

Input :Text = "baaabaaa",


Pattern = “****+ba*****a+", output : true
Pattern = "baaa?ab", output : false
Pattern = "ba*a?", output : true
Pattern = "+a*ab", output : false

Input : Text = "aab"


Pattern = "*+" output : false
Pattern = "*+b" output : true

2995
Chapter 419. WildCard pattern matching having three symbols ( * , + , ? )

Case 1: The character is ‘*’


Here two cases arise: We can ignore ‘*’ character and move to next character in the pattern.
‘*’ character matches with one or more characters in text. Here we will move to next
character in the string.
Case 2: The character is ‘?’ We can ignore current character in text and move to next
character in the pattern and text.
Case 3: The character is ‘+’
Here two cases arise : We match current character of text with the previous character of
pattern. If there is no previous character that mean ‘+’ is the first character of pattern so
we print result as “text do not match”. If the previous character is either ‘+’, ‘?’ or ‘*’ we
replace it with the last character used by them.
Case 4: The character is not a wildcard character
If current character in text matches with current character in pattern, we move to next
character in the pattern and text. If they do not match, wildcard pattern and text do not
match.
The process for “*”, “?” is similar to wildcard pattern Matching for two characters:

Here we use a dp table that will contain


two fields
Struct DP
{
// value is true if match possible
// for current indexes, else false.
bool value;

// Stores the character used


// by the symbol that we used
// later for symbol '+'
char ch;
}

Below c++ implementation of above idea.

// C++ program to implement wildcard


// pattern matching algorithm
#include <bits/stdc++.h>
using namespace std;
  
struct DP {
    bool value;
    char ch;
};
  
// Function that matches input str with

2996
Chapter 419. WildCard pattern matching having three symbols ( * , + , ? )

// given wildcard pattern


bool strmatch(string str, string pattern,
              int n, int m)
{
    // empty pattern can only match with
    // empty string
    if (m == 0)
        return (n == 0);
  
    // If first character of pattern is '+'
    if (pattern[0] == '+')
        return false;
  
    // lookup table for storing results of
    // subproblems
    struct DP lookup[m + 1][n + 1];
  
    // initialize lookup table to false
    for (int i = 0; i <= m; i++)
        for (int j = 0; j <= n; j++) {
            lookup[i][j].value = false; 
            lookup[i][j].ch = ' '; 
        }  
           
    // empty pattern can match with
    // empty string
    lookup[0][0].value = true;
  
    // Only '*' can match with empty string
    for (int j = 1; j <= n; j++)
        if (pattern[j - 1] == '*')
            lookup[j][0].value = 
                   lookup[j - 1][0].value;
  
    // fill the table in bottom-up fashion
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
  
            // Two cases if we see a '*'
            // a) We ignore ‘*’ character and move
            // to next character in the pattern,
            // i.e., ‘*’ indicates an empty sequence.
            // b) '*' character matches with ith
            // character in input
            if (pattern[i - 1] == '*') {
                lookup[i][j].value =
                       lookup[i][j - 1].value || 
                       lookup[i - 1][j].value;

2997
Chapter 419. WildCard pattern matching having three symbols ( * , + , ? )

                lookup[i][j].ch = str[j - 1];


            }
  
            // Current characters are considered as
            // matching in two cases
            // (a) current character of pattern is '?'
            else if (pattern[i - 1] == '?') {
                lookup[i][j].value = 
                          lookup[i - 1][j - 1].value;
                lookup[i][j].ch = str[j - 1];
            }
  
            // (b) characters actually match
            else if (str[j - 1] == pattern[i - 1])
                lookup[i][j].value =
                       lookup[i - 1][j - 1].value;
  
            // Current character match
            else if (pattern[i - 1] == '+')
  
                // case 1: if previous character is 
                // not symbol
                if (pattern[i - 2] != '+' ||
                    pattern[i - 2] != '*' ||
                    pattern[i - 2] != '?')
                    if (pattern[i - 2] == str[j - 1]) {
                        lookup[i][j].value = 
                           lookup[i - 1][j - 1].value;
                        lookup[i][j].ch = str[j - 1];
                    }
  
                    // case 2 : if previous character 
                    // is symbol (+, *, ? ) then we 
                    // compare current text character 
                    // with the character that is used by
                    // the symbol  at that point. we 
                    // access it by lookup[i-1][j-1]
                    else if (str[j-1] == lookup[i-1][j-1].ch) {
                        lookup[i][j].value =
                              lookup[i - 1][j - 1].value;
                        lookup[i][j].ch =
                              lookup[i - 1][j - 1].ch;
                    }
  
                    // If characters don't match
                    else
                        lookup[i][j].value = false;
        }

2998
Chapter 419. WildCard pattern matching having three symbols ( * , + , ? )

    }
  
    return lookup[m][n].value;
}
  
// Driver code
int main()
{
    string str = "baaabaaa";
    string pattern = "*****+ba***+";
  
    if (strmatch(str, pattern, str.length(),
                       pattern.length()))
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
  
    return 0;
}

Output:

Yes

Time Complexity : O(n*m)

Source

https://www.geeksforgeeks.org/wildcard-pattern-matching-three-symbols/

2999
Chapter 420

Wildcard Pattern Matching

Wildcard Pattern Matching - GeeksforGeeks


Given a text and a wildcard pattern, implement wildcard pattern matching algorithm that
finds if wildcard pattern is matched with text. The matching should cover the entire text
(not partial text).
The wildcard pattern can include the characters ‘?’ and ‘*’
‘?’ – matches any single character
‘*’ – Matches any sequence of characters (including the empty sequence)
For example,

Text = "baaabab",
Pattern = “*****ba*****ab", output : true
Pattern = "baaa?ab", output : true
Pattern = "ba*a?", output : true
Pattern = "a*ab", output : false

3000
Chapter 420. Wildcard Pattern Matching

Each occurrence of ‘?’ character in wildcard pattern can be replaced with any other character
and each occurrence of ‘*’ with a sequence of characters such that the wildcard pattern
becomes identical to the input string after replacement.
Let’s consider any character in the pattern.
Case 1: The character is ‘*’
Here two cases arise

1. We can ignore ‘*’ character and move to next character in the Pattern.
2. ‘*’ character matches with one or more characters in Text. Here we will move to next
character in the string.

Case 2: The character is ‘?’


We can ignore current character in Text and move to next character in the Pattern and
Text.
Case 3: The character is not a wildcard character
If current character in Text matches with current character in Pattern, we move to next
character in the Pattern and Text. If they do not match, wildcard pattern and Text do not
match.

3001
Chapter 420. Wildcard Pattern Matching

We can use Dynamic Programming to solve this problem –


Let T[i][j] is true if first i characters in given string matches the first j characters of pattern.
DP Initialization:

// both text and pattern are null


T[0][0] = true;

// pattern is null
T[i][0] = false;

// text is null
T[0][j] = T[0][j - 1] if pattern[j – 1] is '*'

DP relation :

// If current characters match, result is same as


// result for lengths minus one. Characters match
// in two cases:
// a) If pattern character is '?' then it matches
// with any character of text.
// b) If current characters in both match
if ( pattern[j – 1] == ‘?’) ||
(pattern[j – 1] == text[i - 1])
T[i][j] = T[i-1][j-1]

// If we encounter ‘*’, two choices are possible-


// a) We ignore ‘*’ character and move to next
// character in the pattern, i.e., ‘*’
// indicates an empty sequence.
// b) '*' character matches with ith character in
// input
else if (pattern[j – 1] == ‘*’)
T[i][j] = T[i][j-1] || T[i-1][j]

else // if (pattern[j – 1] != text[i - 1])


T[i][j] = false

Below is the implementation of above Dynamic Programming approach.

C++

// C++ program to implement wildcard


// pattern matching algorithm

3002
Chapter 420. Wildcard Pattern Matching

#include <bits/stdc++.h>
using namespace std;
  
// Function that matches input str with
// given wildcard pattern
bool strmatch(char str[], char pattern[],
              int n, int m)
{
    // empty pattern can only match with
    // empty string
    if (m == 0)
        return (n == 0);
  
    // lookup table for storing results of
    // subproblems
    bool lookup[n + 1][m + 1];
  
    // initailze lookup table to false
    memset(lookup, false, sizeof(lookup));
  
    // empty pattern can match with empty string
    lookup[0][0] = true;
  
    // Only '*' can match with empty string
    for (int j = 1; j <= m; j++)
        if (pattern[j - 1] == '*')
            lookup[0][j] = lookup[0][j - 1];
  
    // fill the table in bottom-up fashion
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            // Two cases if we see a '*'
            // a) We ignore ‘*’ character and move
            //    to next  character in the pattern,
            //     i.e., ‘*’ indicates an empty sequence.
            // b) '*' character matches with ith
            //     character in input
            if (pattern[j - 1] == '*')
                lookup[i][j] = lookup[i][j - 1] ||
                               lookup[i - 1][j];
  
            // Current characters are considered as
            // matching in two cases
            // (a) current character of pattern is '?'
            // (b) characters actually match
            else if (pattern[j - 1] == '?' ||

3003
Chapter 420. Wildcard Pattern Matching

                    str[i - 1] == pattern[j - 1])


                lookup[i][j] = lookup[i - 1][j - 1];
  
            // If characters don't match
            else lookup[i][j] = false;
        }
    }
  
    return lookup[n][m];
}
  
int main()
{
    char str[] = "baaabab";
    char pattern[] = "*****ba*****ab";
    // char pattern[] = "ba*****ab";
    // char pattern[] = "ba*ab";
    // char pattern[] = "a*ab";
    // char pattern[] = "a*****ab";
    // char pattern[] = "*a*****ab";
    // char pattern[] = "ba*ab****";
    // char pattern[] = "****";
    // char pattern[] = "*";
    // char pattern[] = "aa?ab";
    // char pattern[] = "b*b";
    // char pattern[] = "a*a";
    // char pattern[] = "baaabab";
    // char pattern[] = "?baaabab";
    // char pattern[] = "*baaaba*";
  
    if (strmatch(str, pattern, strlen(str),
                         strlen(pattern)))
        cout <<    "Yes" << endl;
    else
        cout << "No" << endl;
  
    return 0;
}

Java

// Java program to implement wildcard


// pattern matching algorithm
import java.util.Arrays;
public class GFG{     
       
    // Function that matches input str with
    // given wildcard pattern

3004
Chapter 420. Wildcard Pattern Matching

    static boolean strmatch(String str, String pattern,


                                 int n, int m)
    {
        // empty pattern can only match with
        // empty string
        if (m == 0)
            return (n == 0);
       
        // lookup table for storing results of
        // subproblems
        boolean[][] lookup = new boolean[n + 1][m + 1];
       
        // initailze lookup table to false
        for(int i = 0; i < n + 1; i++)
            Arrays.fill(lookup[i], false);
          
       
        // empty pattern can match with empty string
        lookup[0][0] = true;
       
        // Only '*' can match with empty string
        for (int j = 1; j <= m; j++)
            if (pattern.charAt(j - 1) == '*')
                lookup[0][j] = lookup[0][j - 1];
       
        // fill the table in bottom-up fashion
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                // Two cases if we see a '*'
                // a) We ignore '*'' character and move
                //    to next  character in the pattern,
                //     i.e., '*' indicates an empty sequence.
                // b) '*' character matches with ith
                //     character in input
                if (pattern.charAt(j - 1) == '*')
                    lookup[i][j] = lookup[i][j - 1] ||
                                   lookup[i - 1][j];
       
                // Current characters are considered as
                // matching in two cases
                // (a) current character of pattern is '?'
                // (b) characters actually match
                else if (pattern.charAt(j - 1) == '?' ||
                    str.charAt(i - 1) == pattern.charAt(j - 1))
                    lookup[i][j] = lookup[i - 1][j - 1];
       

3005
Chapter 420. Wildcard Pattern Matching

                // If characters don't match


                else lookup[i][j] = false;
            }
        }
       
        return lookup[n][m];
    }
       
    public static void main(String args[])
    {
        String str = "baaabab";
        String pattern = "*****ba*****ab";
        // String pattern = "ba*****ab";
        // String pattern = "ba*ab";
        // String pattern = "a*ab";
        // String pattern = "a*****ab";
        // String pattern = "*a*****ab";
        // String pattern = "ba*ab****";
        // String pattern = "****";
        // String pattern = "*";
        // String pattern = "aa?ab";
        // String pattern = "b*b";
        // String pattern = "a*a";
        // String pattern = "baaabab";
        // String pattern = "?baaabab";
        // String pattern = "*baaaba*";
       
        if (strmatch(str, pattern, str.length(),
                             pattern.length()))
            System.out.println("Yes");
        else
            System.out.println("No");
       
    }
}
// This code is contributed by Sumit Ghosh

Output :

Yes

Time complexity of above solution is O(m x n). Auxiliary space used is also O(m x n).

Further Improvements:
We can improve space complexity by making use of the fact that we only uses the result
from last row.
One more improvement is yo merge consecutive ‘*’ in the pattern to single ‘*’ as they mean

3006
Chapter 420. Wildcard Pattern Matching

the same thing. For example for pattern “*****ba*****ab”, if we merge consecutive stars,
the resultant string will be “*ba*ab”. So, value of m is reduced from 14 to 6.

Source

https://www.geeksforgeeks.org/wildcard-pattern-matching/

3007
Chapter 421

Word Wrap problem ( Space


optimized solution )

Word Wrap problem ( Space optimized solution ) - GeeksforGeeks


Given a sequence of words, and a limit on the number of characters that can be put in one
line (line width). Put line breaks in the given sequence such that the lines are printed neatly.
Assume that the length of each word is smaller than the line width. When line breaks are
inserted there is a possibility that extra spaces are present in each line. The extra spaces
includes spaces put at the end of every line except the last one.
The problem is to minimize the following total cost.
Total cost = Sum of cost of all lines, where cost of line is = (Number of extra spaces in the
line)^2.
For example, consider the following string and line width M = 15
“Geeks for Geeks presents word wrap problem”
Following is the optimized arrangement of words in 3 lines
Geeks for Geeks
presents word
wrap problem
The total extra spaces in line 1 and line 2 are 0 and 2. Space for line 3 is not considered as
it is not extra space as described above. So optimal value of total cost is 0 + 2*2 = 4.
Examples:

Input format: Input will consists of array of integers where each array element represents length
Output format: Output consists of a series of integers where two consecutive integers represent
starting word and ending word of each line.

Input : arr[] = {3, 2, 2, 5}


Output : 1 1 2 3 4 4
Line number 1: From word no. 1 to 1
Line number 2: From word no. 2 to 3
Line number 3: From word no. 4 to 4

3008
Chapter 421. Word Wrap problem ( Space optimized solution )

Input : arr[] = {3, 2, 2}


Output : 1 1 2 2 3 3
Line number 1: From word no. 1 to 1
Line number 2: From word no. 2 to 2
Line number 3: From word no. 3 to 3

Approach: We have discussed a Dynamic Programming based solution of word wrap prob-
lem. The solution discussed used O(n^2) auxiliary space. The auxiliary space used can be
reduced to O(n). The idea is to use two 1-D arrays dp[] and ans[], where dp[i] represents
minimum cost of the line in which arr[i] is the first word and ans[i] represents index of last
word present in line in which word arr[i] is the first word. Let k represents limit on number
of characters in each line. Suppose for any line l the first word in that line is at index i in
arr[]. The minimum cost of that line is stored in dp[i]. The last word in that line is at index
j in arr[], where j can vary from i to n. Iterate over all values of j and keep track of number
of characters added so far in line l. If number of characters are less than k then find cost of
current line with these number of characters. Compare this cost with minimum cost find so
far for this line in dp[i] and update dp[i] and ans[i] accordingly. Repeat above procedure for
each value of i, 1 <= i <= n. The starting and ending words of each line will be at index i
and index ans[i], where next value of i for line l+1 is ans[i] + 1.
Implementation:

C++

// C++ program for space optimized


// solution of Word Wrap problem.
  
#include <bits/stdc++.h>
using namespace std;
  
// Function to find space optimized
// solution of Word Wrap problem.
void solveWordWrap(int arr[], int n, int k)
{
    int i, j;
  
    // Variable to store number of
    // characters in given line.
    int currlen;
  
    // Variable to store possible
    // minimum cost of line.
    int cost;
  
    // DP table in which dp[i] represents
    // cost of line starting with word
    // arr[i].

3009
Chapter 421. Word Wrap problem ( Space optimized solution )

    int dp[n];
  
    // Array in which ans[i] store index
    // of last word in line starting with
    // word arr[i].
    int ans[n];
  
    // If only one word is present then
    // only one line is required. Cost
    // of last line is zero. Hence cost
    // of this line is zero. Ending point
    // is also n-1 as single word is
    // present.
    dp[n - 1] = 0;
    ans[n - 1] = n - 1;
  
    // Make each word first word of line
    // by iterating over each index in arr.
    for (i = n - 2; i >= 0; i--) {
        currlen = -1;
        dp[i] = INT_MAX;
  
        // Keep on adding words in current
        // line by iterating from starting
        // word upto last word in arr.
        for (j = i; j < n; j++) {
  
            // Update number of characters
            // in current line. arr[j] is
            // number of characters in
            // current word and 1
            // represents space character
            // between two words.
            currlen += (arr[j] + 1);
  
            // If limit of characters
            // is violated then no more
            // words can be added to
            // current line.
            if (currlen > k)
                break;
  
            // If current word that is
            // added to line is last
            // word of arr then current
            // line is last line. Cost of
            // last line is 0. Else cost
            // is square of extra spaces

3010
Chapter 421. Word Wrap problem ( Space optimized solution )

            // plus cost of putting line


            // breaks in rest of words
            // from j+1 to n-1.
            if (j == n - 1)
                cost = 0;
            else
                cost = (k - currlen) * (k - currlen) + dp[j + 1];
  
            // Check if this arrangement gives
            // minimum cost for line starting
            // with word arr[i].
            if (cost < dp[i]) {
                dp[i] = cost;
                ans[i] = j;
            }
        }
    }
  
    // Print starting index and ending index
    // of words present in each line.
    i = 0;
    while (i < n) {
        cout << i + 1 << " " << ans[i] + 1 << " ";
        i = ans[i] + 1;
    }
}
  
// Driver function
int main()
{
    int arr[] = { 3, 2, 2, 5 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int M = 6;
    solveWordWrap(arr, n, M);
    return 0;
}

Java

// Java program for space 


// optimized solution of 
// Word Wrap problem.
import java.io.*;
  
class GFG
{
  
// Function to find space 

3011
Chapter 421. Word Wrap problem ( Space optimized solution )

// optimized solution of
// Word Wrap problem.
static void solveWordWrap(int arr[],
                          int n, int k)
{
    int i, j;
  
    // Variable to store 
    // number of characters 
    // in given line.
    int currlen;
  
    // Variable to store 
    // possible minimum 
    // cost of line.
    int cost;
  
    // DP table in which 
    // dp[i] represents 
    // cost of line starting
    // with word arr[i].
    int dp[] = new int[n];
  
    // Array in which ans[i]
    // store index of last 
    // word in line starting 
    // with word arr[i].
    int ans[] = new int[n];
  
    // If only one word is present 
    // then only one line is required. 
    // Cost of last line is zero. 
    // Hence cost of this line is zero. 
    // Ending point is also n-1 as 
    // single word is present.
    dp[n - 1] = 0;
    ans[n - 1] = n - 1;
  
    // Make each word first 
    // word of line by iterating 
    // over each index in arr.
    for (i = n - 2; i >= 0; i--) 
    {
        currlen = -1;
        dp[i] = Integer.MAX_VALUE;
  
        // Keep on adding words in 
        // current line by iterating 

3012
Chapter 421. Word Wrap problem ( Space optimized solution )

        // from starting word upto 


        // last word in arr.
        for (j = i; j < n; j++) 
        {
  
            // Update number of characters
            // in current line. arr[j] is
            // number of characters in
            // current word and 1
            // represents space character
            // between two words.
            currlen += (arr[j] + 1);
  
            // If limit of characters
            // is violated then no more
            // words can be added to
            // current line.
            if (currlen > k)
                break;
  
            // If current word that is
            // added to line is last
            // word of arr then current
            // line is last line. Cost of
            // last line is 0. Else cost
            // is square of extra spaces
            // plus cost of putting line
            // breaks in rest of words
            // from j+1 to n-1.
            if (j == n - 1)
                cost = 0;
            else
                cost = (k - currlen) * 
                       (k - currlen) +
                            dp[j + 1];
  
            // Check if this arrangement
            // gives minimum cost for
            // line starting with word 
            // arr[i].
            if (cost < dp[i]) 
            {
                dp[i] = cost;
                ans[i] = j;
            }
        }
    }
  

3013
Chapter 421. Word Wrap problem ( Space optimized solution )

    // Print starting index 


    // and ending index of 
    // words present in each line.
    i = 0;
    while (i < n) 
    {
        System.out.print((i + 1) + " " + 
                        (ans[i] + 1) + " ");
        i = ans[i] + 1;
    }
}
  
// Driver Code
public static void main (String[] args) 
{
    int arr[] = {3, 2, 2, 5};
    int n = arr.length;
    int M = 6;
    solveWordWrap(arr, n, M);
}
}
  
// This code is contributed
// by anuj_67.

Output:

1 1 2 3 4 4

Time Complexity: O(n^2)


Auxiliary Space: O(n)
Improved By : vt_m

Source

https://www.geeksforgeeks.org/word-wrap-problem-space-optimized-solution/

3014
Chapter 422

n-th number with digits in {0,


1, 2, 3, 4, 5}

n-th number with digits in {0, 1, 2, 3, 4, 5} - GeeksforGeeks


Given a number n and we have to find n-th number such that it’s digits only consist 0, 1, 2,
3, 4 or 5.
Examples :

Input : n = 6
Output : 5

Input : n = 10
Output : 13

We first store 0, 1, 2, 3, 4, 5 in an array. We can see that next numbers will be 10, 11,
12„13, 14, 15 and after that numbers will be 20, 21, 23, 24, 25 and so on. We can see
the pattern that is repeating again and again. We save the calculated result and use it for
further calculations.
next 6 numbers are-
1*10+0 = 10
1*10+1 = 11
1*10+2 = 12
1*10+3 = 13
1*10+4 = 14
1*10+5 = 15
and after that next 6 numbers will be-
2*10+0 = 20
2*10+1 = 21
2*10+2 = 22

3015
Chapter 422. n-th number with digits in {0, 1, 2, 3, 4, 5}

2*10+3 = 23
2*10+4 = 24
2*10+5 = 25
We use this pattern to find the n-th number. Below is complete algorithm.

1) push 0 to 5 in ans vector


2) for i=0 to n
for j=0 to 6

// this will be the case when first


// digit will be zero
if (ans[i]*10! = 0)
ans.push_back(ans[i]*10 + ans[j])

3) print ans[n-1]

// C++ program to find n-th number with digits


// in {0, 1, 2, 3, 4, 5}
#include <bits/stdc++.h>
using namespace std;
  
// Returns the N-th number with given digits
int findNth(int n)
{
    // vector to store results
    vector<int> ans;
  
    // push first 6 numbers in the answer
    for (int i = 0; i < 6; i++)
        ans.push_back(i);
  
    // calculate further results
    for (int i = 0; i <= n; i++) 
        for (int j = 0; j < 6; j++) 
            if ((ans[i] * 10) != 0)
                ans.push_back(ans[i] * 10 + ans[j]);        
      
    return ans[n - 1];
}
  
// Driver code
int main()
{
    int n = 10;
    cout << findNth(n);
    return 0;
}

3016
Chapter 422. n-th number with digits in {0, 1, 2, 3, 4, 5}

Efficient Method :
Algorithm :
1. First convert number n to base 6.
2. Store the converted value simultaneously in an array.
3. Print that array in reverse order.
Below is the implementation of above algorithm :
C++

// CPP code to find nth number


// with digits 0, 1, 2, 3, 4, 5
#include <bits/stdc++.h>
using namespace std;
  
#define max 100000
  
// function to convert num to base 6
int baseconversion(int arr[], int num, int base)
  
{
    int i = 0, rem, j;
  
    if (num == 0) {
        return 0;
    }
  
    while (num > 0) {
        rem = num % base;
  
        arr[i++] = rem;
  
        num /= base;
    }
  
    return i;
}
  
// Driver code
int main()
{
  
    // initialize an array to 0
    int arr[max] = { 0 };
  
    int n = 10;
  
    // function calling to convert

3017
Chapter 422. n-th number with digits in {0, 1, 2, 3, 4, 5}

    // number n to base 6


    int size = baseconversion(arr, n - 1, 6);
  
    // if size is zero then return zero
    if (size == 0)
  
        cout << size;
  
    for (int i = size - 1; i >= 0; i--) {
  
        cout << arr[i];
    }
  
    return 0;
}
  
// Code is contributed by Anivesh Tiwari.

Java

// Java code to find nth number


// with digits 0, 1, 2, 3, 4, 5
class GFG {
      
    static final int max = 100000;
      
    // function to convert num to base 6
    static int baseconversion(int arr[], 
                          int num, int base)
    {
        int i = 0, rem, j;
      
        if (num == 0) {
            return 0;
        }
      
        while (num > 0) {
              
            rem = num % base;
            arr[i++] = rem;
            num /= base;
        }
      
        return i;
    }
      
    // Driver code
    public static void main (String[] args)

3018
Chapter 422. n-th number with digits in {0, 1, 2, 3, 4, 5}

    {
          
        // initialize an array to 0
        int arr[] = new int[max];
      
        int n = 10;
      
        // function calling to convert
        // number n to base 6
        int size = baseconversion(arr, n - 1, 6);
      
        // if size is zero then return zero
        if (size == 0)
            System.out.print(size);
      
        for (int i = size - 1; i >= 0; i--) {
            System.out.print(arr[i]);
        }
    }
}
  
// This code is contributed by Anant Agarwal.

C#

// C# code to find nth number


// with digits 0, 1, 2, 3, 4, 5
using System;
  
class GFG {
      
    static int max = 100000;
      
    // function to convert num to base 6
    static int baseconversion(int []arr, 
                              int num, int bas)
    {
        int i = 0, rem;
      
        if (num == 0) {
            return 0;
        }
      
        while (num > 0) {
              
            rem = num % bas;
            arr[i++] = rem;
            num /= bas;

3019
Chapter 422. n-th number with digits in {0, 1, 2, 3, 4, 5}

        }
      
        return i;
    }
      
    // Driver code
    public static void Main ()
    {
        // initialize an array to 0
        int []arr = new int[max];
      
        int n = 10;
      
        // function calling to convert
        // number n to base 6
        int size = baseconversion(arr, n - 1, 6);
      
        // if size is zero then return zero
        if (size == 0)
            Console.Write(size);
      
        for (int i = size - 1; i >= 0; i--) {
            Console.Write(arr[i]);
        }
    }
}
  
// This code is contributed by nitin mittal

Output:

13

Improved By : nitin mittal

Source

https://www.geeksforgeeks.org/n-th-number-with-digits-in-0-1-2-3-4-5/

3020

You might also like