Related
As a homework, I have to find the missing number from 0 to n using a divide and conquer (DAC) algorithm.
As an input, I get n-1 numbers from [0, n] and n.
I can easily do this with a quicksort and then just see which number is missing, but that would mean the complexity of my algorithm will be O(n*log n).
I'm wondering if there is any way I can do lower than that.
I was thinking that I might get the sum of the input (somehow) using DAC, and then the number missing will be n - sum. This would be O(n) complexity.
Is there any other way to get a complexity lower than O(n) (without using any space) and also, is my idea a good one? If not, can you give me other ideas for this problem, please?
Thanks.
Edit:
I know I should post another question, but I can post only once every 90 minutes (as I recall) and I want to finish this problem now if possible.
How can I calculate the sum of an array using DAC?
int DAC(int low, int high, int a[], int& s)
{
if (low <= high)
{
int pivot = (low + high)/2;
s += DAC(low, pivot - 1, a, s);
s += DAC(pivot+1, high, a, s);
return a[pivot];
}
}
for this call
cout << DAC(0, n-1, a, s);
Input:
7
1 2 3 4 5 6 7
I get 4 and I don't understand why. I didn't expect it to return only 4.
Edit 2:
I was getting call because I had to cout<<s, not DAC, I'm sorry.
Now I get 52 for the following code, with input: n=7, a=1 2 3 4 5 6 7
#include <iostream>
#include <algorithm>
using namespace std;
void citire(int& n, int a[])
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
}
}
int DAC(int low, int high, int a[], int& s)
{
if (low <= high)
{
int pivot = (low + high)/2;
s += DAC(low, pivot - 1, a, s);
s += DAC(pivot+1, high, a, s);
return a[pivot];
}
}
int main() {
int a[100], n, s = 0;
citire(n, a);
DAC(0, n-1, a, s);
cout << s;
return 0;
}
As sis modified internally, the function DAC doesn't have to return anything.
#include <iostream>
#include <algorithm>
void citire(int& n, int a[])
{
std::cin >> n;
for (int i = 0; i < n; i++)
{
std::cin >> a[i];
}
}
void DAC(int low, int high, int a[], int& s)
{
if (low <= high)
{
int pivot = (low + high)/2;
DAC(low, pivot - 1, a, s);
DAC(pivot+1, high, a, s);
s += a[pivot];
}
}
int main() {
int a[100], n, s = 0;
citire(n, a);
DAC(0, n-1, a, s);
std::cout << s << "\n";
return 0;
}
But std:accumulatewould be much simpler
I have given an array int A[] = {12,10,9,2,11,8,14,3,5};
In this array, 1st 4 elements(from index 0 to index 3) follow max heap condition. But last 5 elements(index 4 to index 8) don't follow max heap condition. So, I have to write a code so that the whole array follow max heap condition.
I have given a function call max_heap_append(A,3,8); and I have to use it in my code to write the program. It is an assignment so I have to follow the instruction.
I have written this code bellow but when I run the program, nothing happens.
#include <stdio.h>
#include <stdlib.h>
void swap(int * a, int * b )
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void heapify( int A[], int q, int i)
{
int largest = i;
int l = 2 * i + 1 ;
int r = 2 * i + 2;
if( l < q && A[l] > A[largest])
{
largest = l;
}
if( r < q && A[r] > A[largest])
{
largest = r;
}
if( largest != i)
{
swap( &A[i] , &A[largest]);
heapify(A, q, largest);
}
}
void max_heap_append(int A[], int p , int q)
{
int i;
for( i = q / 2 -1; i >= 0; i--)
{
heapify( A , q , i);
}
// sort the heap
for( i = q; i>= 0; i--)
{
swap(&A[0] , &A[i]);
heapify(A, i, 0);
}
}
void printA(int A[], int q)
{
int i;
for( i = 0; i <= q; i++)
{
printf("%d", A[i]);
}
printf("%d\n");
}
int main()
{
int A[] = {12,10,9,2,11,8,14,3};
max_heap_append(A,3,8);
printf("Sorted: ");
printA(A, 8);
return 0;
}
Its not followed heapify from 0 to 3 index.. so u need to heapify all. there is some mistake. if your array size is 8 then u can not excess a[8], you can access a[0] to a[7]. so you need to iterate from 0 to 7.
Try with this:
#include <stdio.h>
#include <stdlib.h>
void swap(int * a, int * b )
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void heapify( int A[], int q, int i)
{
int largest = i;
int l = 2 * i + 1 ;
int r = 2 * i + 2;
if( l < q && A[l] > A[largest])
{
largest = l;
}
if( r < q && A[r] > A[largest])
{
largest = r;
}
if( largest != i)
{
swap( &A[i] , &A[largest]);
heapify(A, q, largest);
}
}
void max_heap_append(int A[], int p , int q)
{
int i;
for( i = q-1; i >= 0; i--)
{
heapify( A , q , i);
}
// sort the heap
for( i = q-1; i>= 0; i--)
{
swap(&A[0] , &A[i]);
heapify(A, i, 0);
}
}
void printA(int A[], int q)
{
int i;
for( i = 0; i < q; i++)
{
printf("%d ", A[i]);
}
printf("\n");
}
int main()
{
int A[] = {12,10,9,2,11,8,14,3};
max_heap_append(A,3,8);
printf("Sorted: ");
printA(A, 8);
return 0;
}
You have several problems in your code
printA
One is/can be indicated by the compiler, in printA :
printf("%d\n");
‘%d’ expects a matching ‘int’ argument, but there no no argument
It is easy to guess you just wanted to print a newline, so that line can be replaced by
putchar('\n');
Still in printA you print the numbers without a separator, the result is not usable, for instance do
printf("%d ", A[i]);
When I look at the call of printA in main the parameter n is the number of elements in A, so the end test of the for is invalid because you try to print a value out of the array, the loop must be :
for( i = 0; i < q; i++)
max_heap_append
in the second for the index i can value 0, in that case you swap the first element of the array with itself, that has no sense and the same for the call of heapify with the 2 last arguments valuing 0
When you call that function in main the parameter q receive the number of elements in the array, which is also the first value of i still in that second for and &A[i] is out of the array. You need to replace that line by
for( i = q-1; i> 0; i--)
If I do all these changes :
Compilation and execution :
bruno#bruno-XPS-8300:/tmp$ gcc -g -Wall h.c
bruno#bruno-XPS-8300:/tmp$ ./a.out
Sorted: 2 3 8 9 10 11 12 14
bruno#bruno-XPS-8300:/tmp$
I have a ribbon, its length is n. I want to cut the ribbon in a way that fulfils the following two conditions:
1. After the cutting each ribbon piece should have length a, b or c.
2. After the cutting the number of ribbon pieces should be maximum.
Find the number of maximum pieces after required cutting.
Input is of the form n,a,b,c where n is the original length of ribbon, and a,b,c are the required lengths of the ribbon.
For eg: I/P = 5 5 3 2
O/P = 2
Now, I am able to realize that this should follow a DP solution. A one dimensional DP where dp[n] represents the maximum number of ways for ribbon of length n.
Now, I am not sure if the recurrence relations will be of the form,
dp[n] = dp[n-a] + a;
dp[n] = dp[n-b] + b;
dp[n] = dp[n-c] + c;
Is this correct or there is some other way?
Edit: Implementation according to the first post:
#include <iostream>
#include <cmath>
using namespace std;
int dp[100000];
int maxi (int a,int b,int c);
int main (void)
{
int n,a,b,c;
cin>>n>>a>>b>>c;
for (int i = 0; i <= n; i++)
{
if ( i == 0 )
dp[i] = 0;
else
dp[i] = maxi(dp[i-a],dp[i-b],dp[i-c])+1;
}
cout<<dp[n]<<"\n";
return 0;
}
int maxi (int a,int b,int c)
{
int ret;
if ( a > b )
ret = a;
else
ret = b;
if ( ret < c )
ret = c;
return ret;
}
if n < 0:
dp[n] = -infinity
if n == 0:
dp[n] = 0
if n > 0:
dp[n] = 1 + max(dp[n-a], dp[n-b], dp[n-c])
for (int i = 0; i <= n; i++)
{
if (i == 0)
dp[i] = 0;
else {
int A = (i-a>=0) ? dp[i-a] : -n-1;
int B = (i-b>=0) ? dp[i-b] : -n-1;
int C = (i-c>=0) ? dp[i-c] : -n-1;
dp[i] = maxi(A,B,C)+1;
}
}
There is an interesting game named one person game. It is played on a m*n grid. There is an non-negative integer in each grid cell. You start with a score of 0. You cannot enter a cell with an integer 0 in it. You can start and end the game at any cell you want (of course the number in the cell cannot be 0). At each step you can go up, down, left and right to the adjacent grid cell. The score you can get at last is the sum of the numbers on your path. But you can enter each cell at most once.
The aim of the game is to get your score as high as possible.
Input:
The first line of input is an integer T the number of test cases. The first line of each test case is a single line containing 2 integers m and n which is the number of rows and columns in the grid. Each of next the m lines contains n space-separated integers D indicating the number in the corresponding cell
Output:
For each test case output an integer in a single line which is maximum score you can get at last.
Constraints:
T is less than 7.
D is less than 60001.
m and n are less than 8.
Sample Input:
4
1 1
5911
1 2
10832 0
1 1
0
4 1
0
8955
0
11493
Sample Output:
5911
10832
0
11493
I tried it but my approach is working very slow for a 7x7 grid.I am trying to access every possible path of the grid recursively and comparing the sum of every path.Below is my code
#include<iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
int max(int a,int b,int c, int d)
{
int max = a;
if(b>max)
max = b;
if(c>max)
max = c;
if(d>max)
max = d;
return max;
}
int Visit_Component( int (*A)[8], int Visit[8][8], int m,int n , int row, int col)
{
if ( ( row >= m ) || (col >= n ) || (col < 0) || (row < 0) || A[row][col] == 0 || Visit[row][col] == 1 )
{
return 0;
}
else
{
Visit[row][col] = 1;
int a= 0,b=0,c=0,d=0,result =0;
a = Visit_Component( A, Visit,m,n, row+1, col);
b = Visit_Component( A, Visit,m,n, row, col +1);
c = Visit_Component( A, Visit,m,n, row, col -1);
d = Visit_Component( A, Visit,m,n, row-1, col );
Visit[row][col] = 0;
result = A[row][col] + max(a,b,c,d);
return result;
}
}
int main(){
int T;
scanf("%d",&T);
for(int k =0; k<T;k++)
{
int N ;
int M;
int count = 0;
int maxcount = 0;
scanf("%d %d",&M,&N);
int C[8][8];
int visit[8][8];
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
{
scanf("%d",&C[i][j]);
visit[i][j] = 0;
}
for( int i= 0 ; i< M ; i++ )
{
for( int j =0; j< N ; j++ )
{
count = Visit_Component( C, visit,M,N, i, j);
if(count > maxcount)
{
maxcount = count;
}
}
}
printf("%d\n",maxcount);
}
return 0;
}
Please suggest me how to optimize this approach or a better algorithm.
As Wikipedia article on Travelling salesman problem suggests, there are exact algorithms, solving this task quickly. But it is hard to find any. And they are, most likely, complicated.
As for optimizing OP's approach, there are several possibilities.
It's easier to start with simple micro-optimization: condition Visit[row][col] == 1 is satisfied with highest probability, so it should come first.
Also it is reasonable to optimize branch-and-bound algorithm with dynamic programming to avoid some repeated calculations. Memorizing calculation results in simple hash table for the cases of up to 19 visited cells improves performance by more than 25% (and more may be expected for some improved hash table). Here is the modified code snippet:
#include<iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;
int max(int a,int b,int c, int d)
{
int max = a;
if(b>max)
max = b;
if(c>max)
max = c;
if(d>max)
max = d;
return max;
}
typedef unsigned long long ull;
static const int HS = 10000019;
static const int HL = 20;
struct HT {
ull v;
int r;
int c;
};
HT ht[HS] = {0};
int Visit_Component(
int (*A)[8], ull& Visit, int m,int n , int row, int col, int x)
{
if ( (Visit & (1ull << (8*row+col))) || ( row >= m ) || (col >= n ) ||
(col < 0) || (row < 0) || A[row][col] == 0)
{
return 0;
}
else
{
if (x < HL)
{
HT& h = ht[(Visit+4*row+col)%HS];
if (h.v == Visit && h.r == row && h.c == col)
return 0;
}
Visit |= (1ull << (8*row+col));
int a= 0,b=0,c=0,d=0,result =0;
a = Visit_Component( A, Visit,m,n, row+1, col, x+1);
b = Visit_Component( A, Visit,m,n, row, col +1, x+1);
c = Visit_Component( A, Visit,m,n, row, col -1, x+1);
d = Visit_Component( A, Visit,m,n, row-1, col , x+1);
Visit &= ~(1ull << (8*row+col));
result = A[row][col] + max(a,b,c,d);
if (x < HL)
{
HT& h = ht[(Visit+4*row+col)%HS];
h.v = Visit;
h.r = row;
h.c = col;
}
return result;
}
}
int main(){
int T;
scanf("%d",&T);
for(int k =0; k<T;k++)
{
int N ;
int M;
int count = 0;
int maxcount = 0;
scanf("%d %d",&M,&N);
int C[8][8];
ull visit = 0;
for(int i = 0; i < M; i++)
for(int j = 0; j < N; j++)
{
scanf("%d",&C[i][j]);
}
for( int i= 0 ; i< M ; i++ )
{
for( int j =0; j< N ; j++ )
{
count = Visit_Component( C, visit,M,N, i, j, 0);
if(count > maxcount)
{
maxcount = count;
}
}
}
printf("%d\n",maxcount);
}
return 0;
}
And much more improvements may be done by pre-processing the input matrix. If there are no zeros in the matrix or if there is only one zero in the corner, you may just sum all the values.
If there is only one zero value (not in the corner), at most one non-zero value should be excluded from the sum. If you invent an algorithm, that determines the subset of cells, from which one of the cells must be removed, you can just select the smallest value from this subset.
If there are two or more zero values, use branch-and-bound algorithm: in this case it is about 20 times faster, because each zero value in input matrix means approximately fivefold speed increase.
One optimization that I can think of is to apply Dijkstra's algorithm. This algorithm will give you a minimum (in your case maximum) path for a particular source node to all destination nodes.
In this example, the first step would be to build a graph.
And because you don't know the source node to start at, you will have to apply Dijkstra's algorithm for each node in the grid. The time complexity will be better than your recursion method because for a particular source node, when finding a maximum path Dijkstra's algorithm does not go through all the possible paths.
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int> >A;
vector<vector<bool> >test;
vector<vector<bool> >test1;
int sum_max=0;
int m,n;
vector<vector<bool> > stamp;
void color1(int i,int j,vector<vector<bool> >temp_vector,vector<vector<bool> > st,int summ){
temp_vector[i][j]=false;summ+=A[i][j];st[i][j]=true;
//1.1
if(i+1<m && temp_vector[i+1][j]){
if(test1[i+1][j]){
if(sum_max<(summ)){sum_max=summ;stamp=st;}
}
else{color1(i+1,j,temp_vector,st,summ);}
}
//1.2
if(i+1<m){if(!temp_vector[i+1][j]){ if(sum_max<(summ)){sum_max=summ;}}}
if(i+1>=m){if(sum_max<(summ)){sum_max=summ;}}
//2
if(i-1>=0 && temp_vector[i-1][j]){
if(test1[i-1][j]){
if(sum_max<(summ)){sum_max=summ;}
}
else{ color1(i-1,j,temp_vector,st,summ);}
}
//2.2
if(i-1>=0){if(!temp_vector[i-1][j]){ if(sum_max<(summ)){sum_max=summ;}}}
if(i-1<0){if(sum_max<(summ)){sum_max=summ;}}
//3
if(j+1<n && temp_vector[i][j+1]){
if(test1[i][j+1]){
if(sum_max<(summ)){sum_max=summ;}
}
else{ color1(i,j+1,temp_vector,st,summ);}}
//3.2
if(j+1<n){if(!temp_vector[i][j+1]){ if(sum_max<(summ)){sum_max=summ;}}}
if(j+1>=n){if(sum_max<(summ)){sum_max=summ;}}
//4
if(j-1>=0 && temp_vector[i][j-1]){
if(test1[i][j-1]){
if(sum_max<(summ)){sum_max=summ;}
}
else{ color1(i,j-1,temp_vector,st,summ);}}
//4.2
if(j-1>=0){if(!temp_vector[i][j-1]){ if(sum_max<(summ)){sum_max=summ;}}}
if(j+1<0){if(sum_max<(summ)){sum_max=summ;}}
}
void color(int i,int j){
test[i][j]=false;
if(i+1<m && test[i+1][j]){
color(i+1,j);}
if(i-1>=0 && test[i-1][j]){
color(i-1,j);
}
if(j+1<n && test[i][j+1]){
color(i,j+1);}
if(j-1>=0 && test[i][j-1]){color(i,j-1);}
}
int main(){
int tc;cin>>tc;
for(int i=0;i<tc;i++){
int mp,np;
cin>>mp;
cin>>np;m=mp;n=np;A.resize(m);test.resize(m);test1.resize(m);int sum=0;
vector<bool> ha1(m,1);
vector<bool> ha2(n,1);
for(int i=0;i<m;i++){A[i].resize(n);test[i].resize(n);test1[i].resize(n);
for(int j=0;j<n;j++){
cin>>A[i][j];sum+=A[i][j];
test[i][j]=true;test1[i][j]=false;
if(A[i][j]==0){test[i][j]=false;ha1[i]=false;ha2[j]=false;}
}
}cout<<endl;
for(int i=0;i<m;i++){cout<<" "<<ha1[i];} cout<<endl;
for(int i=0;i<n;i++){cout<<" "<<ha2[i];} cout<<endl;
cout<<"sum "<<sum<<"\n";
int temp_sum=0;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){//if(A[i][j]<=8845){cout<<"\nk "<<A[i][j]<<" "<<(8845-A[i][j]);}
if(test[i][j]){
if((i-1)>=0 && test[i-1][j] && (i+1)<m && test[i+1][j] && (j-1)>=0 && test[i][j-1] && (j+1)<n && test[i][j+1] && test[i-1][j-1] && test[i-1][j+1]&& test[i+1][j-1] && test[i+1][j+1]){
temp_sum+=A[i][j];test1[i][j]=true;}
}
// cout<<test1[i][j]<<" ";
}//cout<<"\n";
}
// /*
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(test1[i][j]){if(!((test1[i-1][j]||test1[i+1][j]) && (test1[i][j-1]||test1[i][j+1]))){
temp_sum-=A[i][j]; test1[i][j]=false;}
}
//
// cout<<test1[i][j]<<" ";
}//
// cout<<"\n";
}
// */
//cout<<"\n temp_sum is "<<temp_sum<<endl;
vector<vector<bool> > st(m,vector<bool>(n,0));st=test1;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(test[i][j] && (!test1[i][j])){
color1(i,j,test,st,0);
}}}
// cout<<"\nsum is "<<(sum_max+temp_sum)<<endl<<endl;
cout<<(sum_max+temp_sum)<<endl;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){cout<<stamp[i][j]<<" ";} cout<<endl;}
// cout<<max<<endl;
A.clear();
test.clear();
test1.clear();
sum_max=0;
}
cout<<endl;system("pause");
return 0;
}
I'm trying to construct an algorithm that runs at O(nb) time with the following input/question:
input: an array A[1..n] of n different integers and an integer b (i am assuming that the numbers in A are sequential, starting at 1 ending at n, i.e. for n=4 A[1,2,3,4].
question: in how many ways can b be written as the sum of elements of the array when elements in A[] can only be used once?
I've kind of hit a wall on this one. I'm looking for some kind of recursive solution, but I don't see how to avoid using repeat numbers. Like, for instance, if we started at 1 and stored all the ways to make one (just 1) then 2 (just 2) then three (3 or 2+1) etc, it shouldn't be hard to see how many ways we can make larger numbers. But if, for instance, we take 5, we will see that it can be broken into 4+1, and 4 can be further broken down into 3+1, so then we would see 2 solutions (4+1, and 3+1+1), but one of those has a repeat of a number. Am I missing something obvious? Thanks so much!
Recursive and dynamic solutions in C:
#include <stddef.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef struct tAddend
{
struct tAddend* pPrev;
uint Value;
} tAddend;
void findRecursiveSolution(uint n, uint maxAddend, tAddend* pPrevAddend)
{
uint i;
for (i = maxAddend; ; i--)
{
if (n == 0)
{
while (pPrevAddend != NULL)
{
printf("+%u", pPrevAddend->Value);
pPrevAddend = pPrevAddend->pPrev;
}
printf("\n");
return;
}
if (n >= i && i > 0)
{
tAddend a;
a.pPrev = pPrevAddend;
a.Value = i;
findRecursiveSolution(n - i, i - 1, &a);
}
if (i <= 1)
{
break;
}
}
}
void printDynamicSolution(uchar** pTable, uint n, uint idx, uint sum, tAddend* pPrevAddend)
{
uchar el = pTable[idx][sum];
assert((el != 0) && (el != 5) && (el != 7));
if (el & 2) // 2,3,6 - other(s)
{
printDynamicSolution(pTable,
n,
idx - 1,
sum,
pPrevAddend);
}
if (el & 4) // self + other(s)
{
tAddend a;
a.pPrev = pPrevAddend;
a.Value = idx + 1;
printDynamicSolution(pTable,
n,
idx - 1,
sum - (idx + 1),
&a);
}
if (el & 1) // self, found a solution
{
tAddend a;
a.pPrev = pPrevAddend;
a.Value = idx + 1;
pPrevAddend = &a;
while (pPrevAddend != NULL)
{
printf("+%u", pPrevAddend->Value);
pPrevAddend = pPrevAddend->pPrev;
}
printf("\n");
}
}
void findDynamicSolution(uint n)
{
uchar** table;
uint i, j;
if (n == 0)
{
return;
}
// Allocate the DP table
table = malloc(sizeof(uchar*) * n);
if (table == NULL)
{
printf("not enough memory\n");
return;
}
for (i = 0; i < n; i++)
{
table[i] = malloc(n + 1);
if (table[i] == NULL)
{
while (i > 0)
{
free(table[--i]);
}
free(table);
printf("not enough memory\n");
return;
}
}
// Fill in the DP table
for (i = 0; i < n; i++)
{
for (j = 0; j <= n; j++)
{
if (i == 0)
{
table[i][j] = (i + 1 == j); // self
}
else
{
table[i][j] = (i + 1 == j) + // self
2 * (table[i - 1][j] != 0) + // other(s)
4 * ((j >= i + 1) && (table[i - 1][j - (i + 1)] != 0)); // self + other(s)
}
}
}
printDynamicSolution(table, n, n - 1, n, NULL);
for (i = 0; i < n; i++)
{
free(table[i]);
}
free(table);
}
int main(int argc, char** argv)
{
uint n;
if (argc != 2 || sscanf(argv[1], "%u", &n) != 1)
{
n = 10;
}
printf("Recursive Solution:\n");
findRecursiveSolution(n, n, NULL);
printf("\nDynamic Solution:\n");
findDynamicSolution(n);
return 0;
}
Output:
for 10:
Recursive Solution:
+10
+1+9
+2+8
+3+7
+1+2+7
+4+6
+1+3+6
+1+4+5
+2+3+5
+1+2+3+4
Dynamic Solution:
+1+2+3+4
+2+3+5
+1+4+5
+1+3+6
+4+6
+1+2+7
+3+7
+2+8
+1+9
+10
See also on ideone.
Let F(x,i) be the number of ways elements of A[1:i] can be summed to get x.
F(x,i+1) = F(x-A[i+1],i) + F(x,i)
That is it!
This is not a dynamic programming solution though. Non-recursive.
Assumption that arr is sorted in your case like [i....j] where a[i] <= a[j]
That's easy enough
void summer(int[] arr, int n , int b)
{
int lowerbound = 0;
int upperbound = n-1;
while (lowerbound < upperbound)
{
if(arr[lowerbound]+arr[upperbound] == b)
{
// print arr[lowerbound] and arr[upperbound]
lowerbound++; upperbound--;
}
else if(arr[lowerbound]+arr[upperbound] < b)
lowerbound++;
else
upperbound--;
}
}
The above program is easily modifiable to a recursive you need to only change the function definition by passing lowerbound and upperbound.
Case for termination is still lowerbound < upperbound
Base case is if arr[lowerbound] +arr[upperbound] == b
Edited based on comments
You will need to use a modified version of integer knapsack problem. The values of [i,j] both need to be modified accordingly. You are having the problem because you are not most probably modifying your i carefully, Increase your i accordingly then their will not be repetition like the one you are having.