-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathquestion20.c
118 lines (96 loc) · 2.5 KB
/
question20.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
Partition problem
Here we need to divide the array into two parts where the difference in the sum of the two parts
is minimum.
If we go by naive approach, we can either include an element or exclude it, like this total combinations
will be 2^n, which needs to be scanned Therefore time complexity is exponential
METHOD
DP: Here for two parts to have equal sum, the net sum of the array needs to be even. Therefore we first
check that.
When its even, we divide it by two and apply the subset sum method. Finding a subset in the array
whose sum is equal to a given value.
Therefore we use a 2d array in that case where columns indicate sum value from 1 to given value.
Rows indicate the values in the array
Each cell means, whether considering elements uptil that row, the column value is possible or not.
Therefore we get the final answer.
Time complexity: O(nk)
Space complexity: O(nk) //where k is the value of the sum.
This method cannnot be applied for large values of k
*/
//Naive approach
// #include <stdio.h>
// #include <stdlib.h>
// int isSubsetSum(int *arr, int size, int sum){
// if(!sum)
// return 1;
// if(!size && sum)
// return 0;
// if(arr[size-1]>sum)
// return isSubsetSum(arr,size-1,sum);
// return isSubsetSum(arr,size-1,sum) || isSubsetSum(arr,size-1,sum-arr[size-1]);
// }
// int findPartition(int *arr,int size){
// int sum = 0;
// int i;
// for(i=0;i<size;i++){
// sum += arr[i];
// }
// if(sum%2 !=0) return 0;
// return isSubsetSum(arr,size,sum/2);
// }
// int main(){
// int arr[] = {3,1,5,9,12};
// int size = sizeof(arr)/sizeof(arr[0]);
// if(findPartition(arr,size)){
// printf("can be divided\n");
// }else{
// printf("cannot be divided\n");
// }
// return 0;
// }
//Better method
#include <stdio.h>
#include <stdlib.h>
int findPartition(int *arr, int size){
int sum = 0;
int i, j;
for(i=0; i<size; i++){
sum += arr[i];
}
if(sum%2 !=0){
return 0;
}
int part[sum/2+1][size+1];
for(i=0;i<=size;i++){
part[i][0] = 1;
}
for(j=1;j<=sum/2;j++){
part[0][j] = 0;
}
for(i=1;i<=size;i++){
for(j=1;j<=sum/2;j++){
if(arr[i-1] > j){
part[i][j] = part[i-1][j];
}else{
part[i][j] = part[i-1][j] || part[i-1][j-arr[i-1]];
}
}
}
for(i=0;i<=size;i++){
for(j=0;j<=sum/2;j++){
printf("%d ", part[i][j]);
}
printf("\n");
}
return part[size][sum/2];
}
int main(){
int arr[] = {3,5};
int size = sizeof(arr)/sizeof(arr[0]);
if(findPartition(arr,size)){
printf("can be divided\n");
}else{
printf("cannot be divided\n");
}
return 0;
}