Having problems with ctime, and working out function running time - c++

I'm having trouble working out the time for my two maxsubarray functions to run. (right at the bottom of the code)
The output it gives me:
Inputsize: 101 Time using Brute Force:0 Time Using DivandCon: 12
is correct for the second time I use clock() but for the first difference diff1 it just gives me 0 and I'm not sure why?
Edit: Revised Code.
Edit2: Added Output.
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <limits.h>
using namespace std;
int Kedane(int a[], int size)
{
int max_so_far = 0, max_ending_here = 0;
int i;
for(i = 0; i < size; i++)
{
max_ending_here = max_ending_here + a[i];
if(max_ending_here < 0)
max_ending_here = 0;
if(max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
return max_so_far;
}
int BruteForce(int array[],int n)
{
int sum,ret=0;
for(int j=-1;j<=n-2;j++)
{
sum=0;
for(int k=j+1;k<+n-1;k++)
{
sum+=array[k];
if(sum>ret)
{
ret=sum;
}
}
}
return ret;
}
//------------------------------------------------------
// FUNCTION WHICH FINDS MAX OF 2 INTS
int max(int a, int b) { return (a > b)? a : b; }
// FUNCTION WHICH FINDS MAX OF 3 NUMBERS
// CALL MAX FUNCT FOR 2 VARIS TWICE!
int max(int a, int b, int c) { return max(max(a, b), c); }
// WORKS OUT FROM MIDDLE+1->RIGHT THE MAX SUM &
// THE MAX SUM FROM MIDDLE->LEFT + RETURNS SUM OF THESE
int maxCrossingSum(int arr[], int l, int m, int h)
{
int sum = 0; // LEFT OF MID
int LEFTsum = INT_MIN; // INITIALLISES SUM TO LOWEST POSSIBLE INT
for (int i = m; i >= l; i--)
{
sum = sum + arr[i];
if (sum > LEFTsum)
LEFTsum = sum;
}
sum = 0; // RIGHT OF MID
int RIGHTsum = INT_MIN;
for (int i = m+1; i <= h; i++)
{
sum = sum + arr[i];
if (sum > RIGHTsum)
RIGHTsum = sum;
}
// RETURN SUM OF BOTH LEFT AND RIGHT SIDE MAX'S
return LEFTsum + RIGHTsum;
}
// 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
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
int main(void)
{
std::srand (time(NULL));
// CODE TO FILL ARRAY WITH RANDOMS [-50;50]
int size=30000;
int array[size];
for(int i=0;i<=size;i++)
{
array[i]=(std::rand() % 100) -50;
}
// TIMING VARI'S
clock_t t1,t2;
clock_t A,B;
clock_t K1,K2;
volatile int mb, md, qq;
//VARYING ELEMENTS IN THE ARRAY
for(int n=101;n<size;n=n+100)
{
t1=clock();
mb=BruteForce(array,n);
t2=clock();
A=clock();
md=maxSubArraySum(array, 0, n-1) ;
B=clock();
K1=clock();
qq=Kedane(array, n);
K2=clock();
cout<< n << "," << (double)t2-(double)t1 << ","<<(double)B-(double)A << ","<<(double)K2-(double)K1<<endl;
}
return 0;
}
101,0,0,0
201,0,0,0
301,1,0,0
401,0,0,0
501,0,0,0
601,0,0,0
701,0,0,0
801,1,0,0
901,1,0,0
1001,0,0,0
1101,1,0,0
1201,1,0,0
1301,0,0,0
1401,1,0,0
1501,1,0,0
1601,2,0,0
1701,1,0,0
1801,2,0,0
1901,1,1,0
2001,1,0,0
2101,2,0,0
2201,3,0,0
2301,2,0,0
2401,3,0,0
2501,3,0,0
2601,3,0,0
2701,4,0,0
2801,4,0,0
2901,4,0,0
3001,4,0,0
3101,4,0,0
3201,5,0,0
3301,5,0,0
3401,6,0,0
3501,5,0,0
3601,6,0,0
3701,6,0,0
3801,8,0,0
3901,7,0,0
4001,8,0,0
4101,7,0,0
4201,10,1,0
4301,9,0,0
4401,8,0,0
4501,9,0,0
4601,10,0,0
4701,11,0,0
4801,11,0,0
4901,11,0,0
5001,12,0,1
5101,11,1,0
5201,13,0,0
5301,13,0,0
5401,15,0,0
5501,14,0,0
5601,16,0,0
5701,15,0,0
5801,15,1,0
5901,16,0,0
6001,17,0,0
6101,18,0,0
6201,18,0,0
6301,19,0,0
6401,21,0,0
6501,19,0,0
6601,21,1,0
6701,20,0,0
6801,22,0,0
6901,23,0,0
7001,22,0,0
7101,24,0,0
7201,26,0,0
7301,26,0,0
7401,24,1,0
7501,26,0,0
7601,27,0,0
7701,28,0,0
7801,28,0,0
7901,30,0,0
8001,29,0,0
8101,31,0,0
8201,31,1,0
8301,35,0,0
8401,33,0,0
8501,35,0,0
8601,35,1,0
8701,35,0,0
8801,36,1,0
8901,37,0,0
9001,38,0,0
9101,39,0,0
9201,41,1,0
9301,40,0,0
9401,41,0,0
9501,42,0,0
9601,45,0,0
9701,45,0,0
9801,44,0,0
9901,47,0,0
10001,47,0,0
10101,48,0,0
10201,50,0,0
10301,51,0,0
10401,50,0,0
10501,51,0,0
10601,53,0,0
10701,55,0,0
10801,54,0,0
10901,56,0,0
11001,57,0,0
11101,56,0,0
11201,60,0,0
11301,60,0,0
11401,61,1,0
11501,61,1,0
11601,63,0,0
11701,62,1,0
11801,66,1,0
11901,65,0,0
12001,68,1,0
12101,68,0,0
12201,70,0,0
12301,71,0,0
12401,72,0,0
12501,73,1,0
12601,73,1,0
12701,76,0,0
12801,77,0,0
12901,78,1,0
13001,79,1,0
13101,80,0,0
13201,83,0,0
13301,82,0,0
13401,86,0,0
13501,85,1,0
13601,86,0,0
13701,89,0,0
13801,90,0,1
13901,90,0,0
14001,91,0,0
14101,97,0,0
14201,93,0,0
14301,96,0,0
14401,99,0,0
14501,100,0,0
14601,101,0,0
14701,101,0,0
14801,103,1,0
14901,104,0,0
15001,107,0,0
15101,108,0,0
15201,109,0,0
15301,109,0,0
15401,114,0,0
15501,114,0,0
15601,115,0,0
15701,116,0,0
15801,119,0,0
15901,118,0,0
16001,124,0,0
16101,123,1,0
16201,123,1,0
16301,125,0,0
16401,127,1,0
16501,128,1,0
16601,131,0,0
16701,132,0,0
16801,134,0,0
16901,134,1,0
17001,135,1,0
17101,139,0,0
17201,139,0,0
17301,140,1,0
17401,143,0,0
17501,145,0,0
17601,147,0,0
17701,147,0,0
17801,150,1,0
17901,152,1,0
18001,153,0,0
18101,155,0,0
18201,157,0,0
18301,157,1,0
18401,160,0,0
18501,160,1,0
18601,163,1,0
18701,165,0,0
18801,169,0,0
18901,171,0,1
19001,170,1,0
19101,173,1,0
19201,178,0,0
19301,175,1,0
19401,176,1,0
19501,180,0,0
19601,180,1,0
19701,182,1,0
19801,184,0,0
19901,187,1,0
20001,188,1,0
20101,191,0,0
20201,192,1,0
20301,193,1,0
20401,195,0,0
20501,199,0,0
20601,200,0,0
20701,201,0,0
20801,209,1,0
20901,210,0,0
21001,206,0,0
21101,210,0,0
21201,210,0,0
21301,213,0,0
21401,215,1,0
21501,217,1,0
21601,218,1,0
21701,221,1,0
21801,222,1,0
21901,226,1,0
22001,225,1,0
22101,229,0,0
22201,232,0,0
22301,233,1,0
22401,234,1,0
22501,237,1,0
22601,238,0,1
22701,243,0,0
22801,242,1,0
22901,246,1,0
23001,246,0,0
23101,250,1,0
23201,250,1,0
23301,254,1,0
23401,254,0,0
23501,259,0,1
23601,260,1,0
23701,263,1,0
23801,268,0,0
23901,266,1,0
24001,271,0,0
24101,272,1,0
24201,274,1,0
24301,280,0,1
24401,279,0,0
24501,281,0,0
24601,285,0,0
24701,288,0,0
24801,289,0,0
24901,293,0,0
25001,295,1,0
25101,299,1,0
25201,299,1,0
25301,302,0,0
25401,305,1,0
25501,307,0,0
25601,310,1,0
25701,315,0,0
25801,312,1,0
25901,315,0,0
26001,320,1,0
26101,320,0,0
26201,322,0,0
26301,327,1,0
26401,329,0,0
26501,332,1,0
26601,339,1,0
26701,334,1,0
26801,337,0,0
26901,340,0,0
27001,341,1,0
27101,342,1,0
27201,347,0,0
27301,348,1,0
27401,351,1,0
27501,353,0,0
27601,356,1,0
27701,360,0,1
27801,361,1,0
27901,362,1,0
28001,366,1,0
28101,370,0,1
28201,372,0,0
28301,375,1,0
28401,377,1,0
28501,380,0,0
28601,384,1,0
28701,384,0,0
28801,388,1,0
28901,391,1,0
29001,392,1,0
29101,399,1,0
29201,399,0,0
29301,404,1,0
29401,405,0,0
29501,409,1,0
29601,412,2,0
29701,412,1,0
29801,422,1,0
29901,419,1,0

The return values from BruteForce and maxSubArraySum are never used, and this gives the compiler a lot of lattitude when it comes to optimizing them.
On my machine for example, using clang -O3 reduces the call to BruteForce to a vector copy and nothing else.
One method for forcing the evaluation of these functions is to write their results to volatile variables:
volatile int mb, md;
// ...
mb = BruteForce(array, n);
// ...
md = maxSubArraySum(array, 0, n-1);
As the variables are volatile, the value given by the right-hand side of the assignments must be stored, despite the absence of any other side-effects, which prevents the compiler from optimising the computation away.

Related

Minimum Excluded Value of subarray

mex here refers to the minimum excluded value of an array.
I have and array with about 300000 elements. Then I have 50000 pairs of a and b (1<=a<300000 b<=300000) and computer need to tell me the MEX of array in range from a to b.
Example:
int a[10]={0,1,2,3,0,4,5,4,8,6};
a=3;
b=8;
We start from a[2] end and at a[7] , and MEX will be 1
I made a funtion, but it takes 30 seconds for one pair which is not what I need.
int Mex=0;
vector<int> a;
// fill vector
while (find(a.begin(),a.end(), Mex )!= a.end())
{
Mex++;
}
cout << Mex;
So the quextion is: how to make fast MEX function with C++, so that computer can do 50000 various MEX operations for 300000 elements in 5 seconds? Memory limit is 900MB.
Here I am sorting the range, then trying to figure out mex.
int mex(std::vector<int>& num_list, int start, int end) {
std::vector<int> range_list(num_list.begin() + start, num_list.begin() + end);
std::sort(range_list.begin(), range_list.end());
int mex_val = 0;
for (auto&el : range_list) {
int diff = el - mex_val;
if (diff > 1) {
break;
}
mex_val++;
}
return mex_val;
}
int main()
{
std::vector<int>data = {0,1,2,3,0,4,5,4,8,6};
cout<<mex(data, 3, 8)<<"\n";
return 0;
}
Run some tests and see if this works for you.
Worst case:O((b-a)²)
Best case: O(b-a)
#include <iostream>
//Calculate mex starting at myArray[a-1] and ending at myArray[b-1]
int mex(int* myArray, int a, int b){
int mex = 0; //Lowest positive natural number
int position = a-1; //To keep track of where you are in the array
while(position != b){
if(mex == myArray[position]){
mex++;
position = a-1;
}
else
position++;
}
return mex;
}
int main(){
int myArray[10]={0,1,2,3,0,4,5,4,8,6};
int a = 3;
int b = 8;
std::cout << mex(myArray, a, b);
return 0;
}

C++ combination function always resulting 0

can anybody tell me why my Combination function is always resulting 0 ?
I also tried to make it calculate the combination without the use of the permutation function but the factorial and still the result is 0;
#include <iostream>
#include <cmath>
using namespace std;
int factorial(int& n)
{
if (n <= 1)
{
return 1;
}
else
{
n = n-1;
return (n+1) * factorial(n);
}
}
int permutation(int& a, int& b)
{
int x = a-b;
return factorial(a) / factorial(x);
}
int Combination(int& a, int& b)
{
return permutation(a,b) / factorial(b);
}
int main()
{
int f, s;
cin >> f >> s;
cout << permutation(f,s) << endl;
cout << Combination(f,s);
return 0;
}
Your immediate problem is that that you pass a modifiable reference to your function. This means that you have Undefined Behaviour here:
return (n+1) * factorial(n);
// ^^^ ^^^
because factorial(n) modifies n, and is indeterminately sequenced with (n+1). A similar problem exists in Combination(), where b is modified twice in the same expression:
return permutation(a,b) / factorial(b);
// ^^^ ^^^
You will get correct results if you pass n, a and b by value, like this:
int factorial(int n)
Now, factorial() gets its own copy of n, and doesn't affect the n+1 you're multiplying it with.
While we're here, I should point out some other flaws in the code.
Avoid using namespace std; - it has traps for the unwary (and even for the wary!).
You can write factorial() without modifying n once you pass by value (rather than by reference):
int factorial(const int n)
{
if (n <= 1) {
return 1;
} else {
return n * factorial(n-1);
}
}
Consider using iterative code to compute factorial.
We should probably be using unsigned int, since the operations are meaningless for negative numbers. You might consider unsigned long or unsigned long long for greater range.
Computing one factorial and dividing by another is not only inefficient, it also risks unnecessary overflow (when a is as low as 13, with 32-bit int). Instead, we can multiply just down to the other number:
unsigned int permutation(const unsigned int a, const unsigned int b)
{
if (a < b) return 0;
unsigned int permutations = 1;
for (unsigned int i = a; i > a-b; --i) {
permutations *= i;
}
return permutations;
}
This works with much higher a, when b is small.
We didn't need the <cmath> header for anything.
Suggested fixed code:
unsigned int factorial(const unsigned int n)
{
unsigned int result = 1;
for (unsigned int i = 2; i <= n; ++i) {
result *= i;
}
return result;
}
unsigned int permutation(const unsigned int a, const unsigned int b)
{
if (a < b) return 0;
unsigned int result = 1;
for (unsigned int i = a; i > a-b; --i) {
result *= i;
}
return result;
}
unsigned int combination(const unsigned int a, const unsigned int b)
{
// C(a, b) == C(a, a - b), but it's faster to compute with small b
if (b > a - b) {
return combination(a, a - b);
}
return permutation(a,b) / factorial(b);
}
You dont calculate with the pointer value you calculate withe the pointer address.

median of two sorted arrays of different size

i was solving this problem from geeks for geeks http://www.geeksforgeeks.org/median-of-two-sorted-arrays-of-different-sizes/ but when i implemented the same code ,then for input
A[] = {1,2,3}
B[] = {3,6,9,12}
it is giving wrong output as 6 but it should be 3 ,someone please tell me the problem with my code?
//code
#include<iostream>
#include<cmath>
using namespace std;
float single_median(int arr[],int size)//method to find median in an arr
{
if(size == 0)
return -1;
else if(size%2==0)
return (arr[size/2] + arr[size/2 -1])/2.0;
else
return arr[size/2];
}
float medianOf2(int a,int b)//median of two numbers
{
return ((a+b)/2.0);
}
int medianOf3(int a,int b,int c)//median of 3 numbers
{
int maximum = max(a,max(b,c));
int minimum = min(a,min(b,c));
return ((a+b+c) - maximum - minimum);
}
int medianOf4(int a, int b,int c,int d)//median of 4 numbers
{
int maximum = max(a,max(b,max(c,d)));
int minimum = min(a,min(b,min(c,d)));
return ((a+b+c+d) - maximum - minimum);
}
int find_median(int A[],int m,int B[],int n)
{
if(m<n)//here we will keep in mind that A is larger than B else we swap
return find_median(B,n,A,m);
if(n==0)//if smaller array has no element just find the median of larger array
return single_median(A,m);
if(n==1)//if smaller array has one element
{
if(m==1)
return (A[0]+B[0])/2.0;//if both has one element just return the average
else if(m&1)//when larger array has odd elements
return medianOf2(medianOf3(B[0],A[m/2 - 1],A[m/2 + 1]),A[m/2]);
else//for e
return medianOf3(B[0],A[m/2],A[m/2 -1]);
}
if(n==2)
{
if(m==2)
return medianOf4(A[0],B[0],A[1],B[1]);
else if(m&1)
return medianOf3(max(B[0],A[m/2 -1]),min(B[1],A[m/2 +1]),A[m/2]);
else
return medianOf4(max(B[0],A[m/2 -2]),min(B[1],A[m/2 +1]),A[m/2],A[m/2 -1]);
}
int mid_m = (m-1)/2;
int mid_n = (n-1)/2;
if(A[mid_m]<B[mid_n])
find_median(A + mid_m,m/2 +1 ,B,n - mid_n);
else
find_median(A,n/2 +1, B + mid_n, n/2 + 1);
}
int main()
{
int B[] = {1,2,3};
int A[] = {3,6,9,12};
cout<<find_median(A,4,B,3);
return 0;
}
You simply forgot to divide the result by 2.0 in the medianOf4 function before returning the result as so:
int medianOf4(int a, int b,int c,int d)//median of 4 numbers
{
int maximum = max(a,max(b,max(c,d)));
int minimum = min(a,min(b,min(c,d)));
return ((a+b+c+d) - maximum - minimum) / 2.0; # <-- forgot to add "/ 2.0"
}
Hope this helps!
public class Solution {
public double FindMedianSortedArrays(int[] nums1, int[] nums2) {
if(nums1== null || nums1.Length<1)
return result(nums2);
else if(nums2== null || nums2.Length<1)
return result(nums1);
int[] merged = new int[nums1.Length + nums2.Length];
int num1Ind=0;
int num2Ind=0;
int currInd = 0;
while(num1Ind<nums1.Length && num2Ind<nums2.Length){
if(nums1[num1Ind]< nums2[num2Ind])
merged[currInd++]=nums1[num1Ind++];
else
merged[currInd++]=nums2[num2Ind++];
}
if(num2Ind<nums2.Length)
for(int i=num2Ind; i<nums2.Length; i++)
merged[currInd++]=nums2[i];
else if(num1Ind<nums1.Length)
for(int i=num1Ind; i<nums1.Length; i++)
merged[currInd++]=nums1[i];
return result(merged);
}
private double result(int[] merged){
if(merged.Length==1)
return merged[0];
if((merged.Length)%2 !=0)
return (double)merged[merged.Length/2];
return (double)(merged[merged.Length/2-1] + merged[merged.Length/2])/2;
}
}

Printing (Factorial of 2^n)/(2^n -1)mod m in C++

How can we store and print factorial(2^n) / (2^n -1))mod1000000009 in C++.Here n can be as large as 20. When I try to print this using the following code, it shows segmentation fault for n=20
#include
#include
using namespace std;
long int factorial(int n)
{
if(n<=1){return 1;}
else
return (n%1000000009)*(factorial(n-1))%1000000009;
}
int main()
{
int K;
long long int numofmatches=0;
long long int denominator=0;
long long int factor=0;
long long int times=0;
long long int players=0;
cin>>K;
if(K==1)
{
cout<<2<<endl<<2<<endl;
return 0;
}
else
{
denominator=pow(2,K);
cout<<"Denominator="<<denominator<<endl;
numofmatches=factorial(denominator)%1000000009;
denominator-=1;
cout<<"numberofmatches="<<numofmatches<<endl;
cout<<"Denominator="<<denominator<<endl;
factor=numofmatches/denominator;
cout<<"Factor="<<factor<<endl;
while(times<=denominator)
{
cout<<(times*factor)<<endl;
++times;
}
}
return 0;
}
First of all, note that (2^n)! / (2^n-1) is equal to (2^n-2)! x 2^n.
Now, (2^20-2)! by itself is already an extremely large number to calculate.
What you can do instead, is to modulo the intermediate result with 1000000009 after every multiplication:
#define MAX ((1<<20)-2)
unsigned long long res = 1;
for (unsigned int i=1; i<=MAX; i++)
res = (res*i)%1000000009;
res = (res*(MAX+2))%1000000009;
If you want to iterate all values of n between 1 and 20, then you can use:
#define MAX_N 20
unsigned int arr[MAX_N+1] = {0};
void Func()
{
unsigned int i = 1;
unsigned long long res = 1;
for (int n=1; n<=MAX_N; n++)
{
unsigned int max = (1<<n)-2;
for (; i<=max; i++)
res = (res*i)%1000000009;
arr[n] = (unsigned int)((res*(max+2))%1000000009);
}
}
BTW, for any n larger than 29 the result will simply be 0, as (2^30-2) is larger than 1000000009.
So (2^30-2)! is divisible by 1000000009, and therefore, (2^30-2)! mod 1000000009 equals 0.

Knapsack algorithm for two bags

I've found thread which provides pseudo-code for knapsack algorithm with 2 knapsacks.
I've tried implement it in C++, but it doesn't work as suppose. Here's code:
#include <cstdio>
#define MAX_W1 501
#define MAX_W2 501
int maximum(int a, int b, int c) {
int max = a>b?a:b;
return c>max?c:max;
}
int knapsack[MAX_W1][MAX_W2] = {0};
int main() {
int n, s1, s2, gain, weight; // items, sack1, sack2, gain, cost
scanf("%d %d %d", &n, &s1, &s2);
// filing knapsack
for (int i = 0; i < n; i++) {
scanf("%d %d", &gain, &weight);
for (int w1 = s1; w1 >= weight; w1--) {
for (int w2 = s2; w2 >= weight; w2--) {
knapsack[w1][w2] = maximum(
knapsack[w1][w2], // we have best option
knapsack[w1 - weight][w2] + gain, // put into sack one
knapsack[w1][w2 - weight] + gain // put into sack two
);
}
}
}
int result = 0;
// searching for result
for (int i = 0; i <= s1; i++) {
for (int j = 0; j <= s2; j++) {
if (knapsack[i][j] > result) {
result = knapsack[i][j];
}
}
}
printf("%d\n", result);
return 0;
}
For instance for following input:
5 4 3
6 2
3 2
4 1
2 1
1 1
I have output:
13
Obviously it's wrong because I can take all items (1,2 into first bag and rest to second bag) and sum is 16.
I would be grateful for any explanation where I get pseudo-code wrong.
I made little update since, some people have problem with understanding the input format:
First line contains 3 numbers as follows number of items, capacity of sack one, capacity of sack two
Later on there are n lines where each contains 2 numbers: gain, cost of i-th item.
Assume that sacks cannot be larger than 500.
The algorithm you're using appears incorrect, because it will only consider cases where the object happens to fit in both sacks. I made the following changes to your code and it operates correctly now:
#include <algorithm>
using std::max;
int max3(int a, int b, int c) {
return max(a, max(b, c));
}
and
for (int w1 = s1; w1 >= 0; w1--) {
for (int w2 = s2; w2 >= 0; w2--) {
if (w1 >= weight && w2 >= weight) // either sack has room
{
knapsack[w1][w2] = max3(
knapsack[w1][w2], // we have best option
knapsack[w1 - weight][w2] + gain, // put into sack one
knapsack[w1][w2 - weight] + gain // put into sack two
);
}
else if (w1 >= weight) // only sack one has room
{
knapsack[w1][w2] = max(
knapsack[w1][w2], // we have best option
knapsack[w1 - weight][w2] + gain // put into sack one
);
}
else if (w2 >= weight) // only sack two has room
{
knapsack[w1][w2] = max(
knapsack[w1][w2], // we have best option
knapsack[w1][w2 - weight] + gain // put into sack two
);
}
}
}
Here is modification to code to make it work:-
#include <cstdio>
#define MAX_W1 501
#define MAX_W2 501
int maximum(int a, int b, int c) {
int max = a>b?a:b;
return c>max?c:max;
}
int knapsack[MAX_W1][MAX_W2] = {0};
int main() {
int n, s1, s2, gain, weight; // items, sack1, sack2, gain, cost
scanf("%d %d %d", &n, &s1, &s2);
// filing knapsack
for (int i = 0; i < n; i++) {
scanf("%d %d", &gain, &weight);
// need to fill up all the table cannot stop if one sack is full because item might fit in other
for (int w1 = s1; w1 >= 0; w1--) {
for (int w2 = s2; w2 >= 0; w2--) {
int val1=0,val2=0;
if(weight<=w1)
val1 = knapsack[w1 - weight][w2] + gain;
if(weight<=w2)
val2 = knapsack[w1][w2 - weight] + gain;
knapsack[w1][w2] = maximum(
knapsack[w1][w2], // we have best option
val1, // put into sack one
val2 // put into sack two
);
}
}
}
// No need to search for max value it always be Knapsack[s1][s2]
printf("%d\n", knapsack[s1][s2]);
return 0;
}