Suggest an algorithm for finding the sum of all subsets of a set.
For example, if k=3 and the subsets are {1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}
then sum of subsets is {1}+{2}+{3}+{1+2}+{1+3}+{2+3}+{1+2+3}=24
For an input {x1, …, xn}, return 2n-1 (x1 + … + xn), since each term appears in that many sums.
Each element appears the same number of times, which happens to be 2n-1 where n is number of elements. So the answer is: count sum of elements in the set and multiply it by 2n-1
Answer:
Total no. of Subsets are 2^n.
As we don't require an empty set, so total required subsets are 2^n - 1.
Now all we have to do is simply get all possible subsets.
This algorithm will help.
void main()
{
//Total no. of elements in set = n;
//Let's say the Set be denoted as P[n]
//declare a global variable sum and initialize to 0.
for(int i=1;i<=n;i++)
{
int r = nCi;
//here, r = nCi or you can say n combinations i
//it's good to write an extra function named something like "nCi" to evaluate nCi and call it when required.
//define a new two dimensional array of size "r","i", say s[r][i]
for(int k=0;k<r;k++)
{
//define a function to get all combination array for s[r][i] using "i" elements out of total "n"
//This link will help you with best of code for this particular function
//<http://www.geeksforgeeks.org/print-all-possible-combinations-of-r-elements-in-a-given-array-of-size-n/>
//now for every particular s[r][i], do this
for(int j=0;j<i;j++)
{
sum = sum + s[r][j];
}
}
}
//display total output
printf("%d",sum);
}
Related
I have been trying to solve this problem and it works good with small numbers but not the big 10^9 numbers in Hacker Earth
You are given an array of n numbers and q queries. For each query you have to print the floor of the expected value(mean) of the subarray from L to R.
INPUT:
First line contains two integers N and Q denoting number of array elements and number of queries.
Next line contains N space separated integers denoting array elements.
Next Q lines contain two integers L and R(indices of the array).
OUTPUT:
print a single integer denoting the answer.
Constraints:
1<= N ,Q,L,R <= 10^6
1<= Array elements <= 10^9
NOTE
Use Fast I/O
using namespace std;
long int solvepb(int a, int b, long int *arr,int n){
int result, count = 0;
vector<long int>res;
for(int i=0;i<n;i++){
if(i+1 >= a && i+1 <=b){
res.push_back(arr[i]);
count += arr[i];
}
}
result = count / res.size();
return result;
}
int main(){
int n,q;cin>>n>>q;
long int arr[n];
for(int i=0;i<n;i++){
cin>>arr[i];
}
while(q--){
int a,b;
cin>>a>>b;
cout<<solvepb(a,b,arr,n)<<endl;
}
return 0;
}```
So currently, the issue with your algorithm is that each time you are computing the mean over two indices in the array. This means that if the queries are particularly bad, for each of the Q queries, you might iterate through all N elements of the array.
How can one try to reduce this? Notice that because sums are additive, the sum up to an index i is the same as the sum up to an index j plus the sum of the numbers between i and j. Let me rewrite that as an equation -
sum[0:i] = sum[0:j] + sum[j+1:i]
It should be obvious now that by rearranging this equation, you can quickly get the sum between two indices by storing the sum of numbers up to an index. (i.e. sum[j+1:i] = sum[0:i] - sum[0:j]). This means that rather than having O(N*Q), you can have O(N + Q) runtime complexity. The O(N) part of the new complexity is from iterating the array once to get all the sums. The O(Q) part comes from answering the Q queries.
This kind of approach is called prefix sums. There are some optimized data structures like Fenwick trees made specifically for prefix sums that you can read about online or on Wikipedia. But for your question, a simple array should work just fine.
A few comments about your code:
In your for loop in the solvepb function, you are going from 0 to n always, but you didn't need to. You could have specified to go from a to b if you knew a was smaller than b. Otherwise, you go from b to a.
You also do not really use the vector. The vector in the solvepb function stores array elements, but these are never used again. You only seem to use it to find the number of elements from a to b, but you can get that by simply subtracting the difference between the two indices (i.e. b-a+1 if a < b otherwise a-b+1)
Given an unsorted set of integers in the form of array, find minimum subset sum greater than or equal to a const integer x.
eg:- Our set is {4 5 8 10 10} and x=15
so the minimum subset sum closest to x and >=x is {5 10}
I can only think of a naive algorithm which lists all the subsets of set and checks if sum of subset is >=x and minimum or not, but its an exponential algorithm and listing all subsets requires O(2^N). Can I use dynamic programming to solve it in polynomial time?
If the sum of all your numbers is S, and your target number is X, you can rephrase the question like this: can you choose the maximum subset of the numbers that is less than or equal to S-X?
And you've got a special case of the knapsack problem, where weight and value are equal.
Which is bad news, because it means your problem is NP-hard, but on the upside you can just use the dynamic programming solution of the KP (which still isn't polynomial). Or you can try a polynomial approximation of the KP, if that's good enough for you.
I was revising DP. I thought of this question. Then I searched and I get this question but without a proper answer.
So here is the complete code (along with comments ): Hope it is useful.
sample image of table
//exactly same concept as subset-sum(find the minimum difference of subset-sum)
public class Main
{
public static int minSubSetSum(int[] arr,int n,int sum,int x){
boolean[][] t=new boolean[n+1][sum+1];
//initailization if n=0 return false;
for(int i=0;i<sum+1;i++)
t[0][i]=false;
//initialization if sum=0 return true because of empty set (a set can be empty)
for(int i=0;i<n+1;i++)
t[i][0]=true; //here if(n==0 && sum==0 return true) has been also initialized
//now DP top-down
for(int i=1;i<n+1;i++)
for(int j=1;j<sum+1;j++)
{
if(arr[i-1]<=j)
t[i][j]=t[i-1][j-arr[i-1]] || t[i-1][j]; // either include arr[i-1] or not
else
t[i][j]=t[i-1][j]; //not including arr[i-1] so sum is not deducted from j
}
//now as per question we have to take all element as it can be present in set1
//if not in set1 then in set2 ,so always all element will be a member of either set
// so we will look into last row(when i=n) and we have to find min_sum(j)
int min_sum=Integer.MAX_VALUE;
for(int j=x;j<=sum;j++)
if(t[n][j]==true){ //if in last row(n) w.r.t J , if the corresponding value true then
min_sum=j; //then that sum is possible
break;
}
if(min_sum==Integer.MAX_VALUE)
return -1;// because that is not possible
return min_sum;
}
public static void main(String[] args) {
int[] arr=new int[]{4,5,8,10,10};
int x=15;
int n=arr.length;
int sum=0;
for(int i=0;i<n;i++)
sum=sum+arr[i];
System.out.println("Min sum can formed greater than X is");
int min_sum=minSubSetSum(arr,n,sum,x);
System.out.println(min_sum);
}
}
As the problem was N-P complete so with DP time complexity reduces to
T(n)=O(n*sum)
and space complexity =O(n*sum);
As already mentioned, this is NP-complete. Another way of seeing that is, if one can solve this in polynomial time, then subset-sum problem could also be solved in polynomial time (if solution exist then it will be same).
I believe the other answers are incorrect. Your problem is actually a variation of the 0-1 knapsack problem (i.e. without repetitions) which is solvable in polynomial time with dynamic programming. You just need to formulate your criteria as in #biziclop's answer.
How about a greedy approach?
First we sort the list in descending order. Then we recursively pop the first element of the sorted list, subtract its value from x, and repeat until x is 0 or less.
In pseudocode:
sort(array)
current = 0
solution = []
while current < x:
if len(array) < 0:
return -1 //no solution possible
current += array[0]
solution.append(array.pop(0))
return solution
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
Write a function called smallest_sum_sequence() that accepts an array
of signed integers and the number of items in the array as arguments,
and returns the smallest sum of a sequence of numbers in the array. A
sequence is defined as a single item or multiple items that are in
adjacent memory locations.
This is obviously homework, I do not need anyone to write the code for me just an explanation of what they actually are looking for, as it is worded weirdly in my opinion.
I think what they are wanting is:
Given an array and the total items in the array.
Have the user input a sequence of values for the array ( array[7] -> array[9] )
return smallest sum
Then determine the smallest sum? Is that supposed to be the smallest value or the smallest combination of items? The first sounds too easy and the second doesn't make sense even if you have negatives.
Am looking for any sort of enlightenment.
So a sequence is a set of any number of adjacent numbers in an array. In a set like
[A B C D E]
Any individual could be an answer. Or [A B] could be an answer. Or [A B C]. Or [C D E]. Or even [A B C D E]. But, definitely not [A D E] since A is not adjacent to D in the original set. Easy.
Now you have to write code that will compare the sum of the values in every possible adjacent sequence, in any set of numbers (given the size of that set beforehand).
Edited as the prior answer was wrong!
This is how I understand it. Assume you have an array of signed integers, called A, consisting of, say, <3, 4, 5>. So n = 3, the length of the array.
Your sequence is defined to be a single (or multiple) items in adjacent memory locations. So A[0] and A[1] would be a sequence as they are in adjacent memory locations, but A[0] and A[2] wouldn't be.
You call your function: smallest_sum_sequence(A, n) with A and n as above.
So your sequences are:
+ of length 1) <3>, <4>, <5>
+ of length 2) <3,4>, <4,5>
+ of length 3) <3, 4, 5>
Hence your function should return 3 in this case.
You have to sum each int with the next one and find the min of the sum
You can walk like this
int min = INT_MAX;
for (i = 0; i < len; i++) {
sum = array[i];
min = MIN(min, sum);
for (j = i + 1; j < len ; j++ ) {
sum += array[j];
min = MIN(min, sum);
}
}
With an array of signed integers it is possible that a larger sequence produces a smaller sum than a single number or a pair.
To find out you need to produce all possible sequences:
Start with first number alone, then first and second, then first, second and third.
Then start with second number ...
Then the sum of each sequence.
Return smallest sum (and probably the matching sequence)
Let's look closely at the requirements:
Write a function ... smallest_sum_sequence() that accepts (1) an
array of signed integers and (2) the number of items in the array
as arguments, and (3) returns the smallest sum of a sequence of
numbers in the array.
A sequence is defined as a single item or multiple items ... in
adjacent memory locations.
Taking them one at a time, you know you will write a function that accepts an array of type int and then number of items (won't be negative, so size_t is a good type). Since it must return a smallest sum, the return type of the function can be int as well:
int smallest_sum_sequence (int *a, size_t n)
{
...
return ssum;
}
That is the basic framework for your function. The next issue to address is the smallest sum. Since you are told you are accepting an array of signed values, you must presume that the values within the array can be both negative and positive numbers. You are next told the sum of the smallest sequence can be be derived from a single or multiple adjacent values?
What I interpret this to mean is that you must keep 2 running values. (1) the minimum value in the array; and (2) a sum of the smallest sequences.
In the arguments you get the number of elements in the array providing you with an easy means to iterate over the array itself:
int i = 0;
int min = INT_MAX; /* largest possible minimum number */
int ssum = INT_MAX; /* largest possible smallest sum */
for (i = 0; i < n; i++) {
min = a[i] < min ? a[i] : min;
if (i > 0) {
int tssum = 0; /* temporary smallest sum */
/* test adjacent values {
if adjacent: tssum += a[i]; {
if no longer adjacent {
compare tssum < ssum, if so ssum = tssum;
}
}
} */
}
}
In your first iteration over the array, you have found min the minimum single value and ssum the sum of the smallest sequence. Now all that is left is the return:
return min < ssum ? min : ssum;
That is my impression of what the logic asked for. You may have to adjust the logic of the pseudo-code and you need to figure out how to identify a sequence start/end, but this should at least give you an outline of one way to approach it. Good luck.
I have to find the cumulative sum of numbers without using array.Like If n=3 & k=5 then my answer will go like this n
1+2+3+4+5 (sum of k elements)
+ 1+3+6+10+15
+ 1+4+10+20+35
(i.e. n times)
n & k ranging from 1 to 10^9
Here elements from index 2 are cumulative sum from the previous series from index 1 to index x like
second value in second series is 3 which is cumulative sum upto second value in previous series 1+2
third value in second series is 6 which is cumulative sum upto third value in previous series 1+2+3
Similarly third value in third series is 10 which is cumulative sum upto third value in previous series 1+3+6
My approach till know is
//For n==1
for(i=0;i<k;i++)
{
a[i]=i+1;
sum = sum + a[i]%mod;
}
if(n==1)
{
printf("%lld\n",sum%mod);
}
//For n>1
else
{
res = (n-1)*k;
for(w=0;w<res;w++)
{
f = w%k;
if(f==0)
{
a[f] = 1;
sum = sum + a[f]%mod;
}
else
{
a[f] = a[f]+a[f-1];
sum = sum + a[f]%mod;
}
}
printf("%lld\n",sum%mod);
}
Here I have used an array storing the series again and again and finding its cumulative sum but here n*k is going too large.
Please help me out in this by suggesting some optimized approach to do so
Finally I have to find the total sum of all these numbers modulo 1000003 1+2+3+4+5+1+3+6+10+15+1+4+10+20+35 = 120%1000003 = 120
I suggest using recursion since you can't use arrays. If you need a little more getting started, let me know (this sounds a lot like a test question so I don't think I should just spell out the answer).
I can point out one simple observation like whatever be the set of elements, since you have to take out the modulo finally, if that modulo(M) is prime then repeating the cumulative sum n times (where n> M ) you again land to the original set of numbers for M iterations. Then you have to deal with just the remaining n-M iterations.
view: [https://en.wikipedia.org/wiki/Figurate_number ]
#include<stdio.h>
#include<conio.h>
main()
{
int i,j,k,x,y,n=4,a[]={1,2,3,4}; //n is the length of the array
for(i=0;i<n;i++)
{
for(k=0;k<(n-2);k++)
{
for(j=(n-1-k);j>=1;j--)
{
y=a[j];
a[j]=a[j-1];
a[j-1]=y;
for(x=0;x<n;x++)
{
printf("%d",a[x]);
}
printf("\t");
}
}
}
getch();
}
Some additional material (I'm a bit drunk, I will probably have to re-edit this tomorrow, so take it with a grain of salt):
Knuth and Sedgewick both covered permutations aeons ago.
Have a look at: http://www.princeton.edu/~rblee/ELE572Papers/p137-sedgewick.pdf
For n items you have n! permutations, so for 13 items you already have 6 227 020 800 permutations. So creating all permutations for a large set of items will become impossible pretty fast.
There are basically two sets of algorithms to create permutations, ranking/unranking and incremental change methods.
With ranking/unranking you have two methods rank and unrank.
Rank will give you the position of a permutation in the genereration order.
Unrank will give you the permutation that lies at integer m, with 0 >= m <= n! and n the amount of items you want to create permutations for.
This is useful for a variety of cases such as:
Creating a random permutation (you just create a random number from 0 to n! and call unrank(randomNumber)) and get the permutation at position randomNumber.
Creating sequences, getting the next permutation: You have a permutation p and call Rank(p) then Unrank(rank+1).
Incremental change methods:
These basically work through swapping and are more efficient than ranking/unranking:
From wikipedia, unordered generation:
function permutation(k, s) {
for j = 2 to length(s) {
swap s[(k mod j) + 1] with s[j]; // note that our array is indexed starting at 1
k := k / j; // integer division cuts off the remainder
}
return s;
}
Change this:
for(k=0;k<(n-2);k++)
to this:
for(k=0;k<(n-1);k++)
Also, try using more descriptive variable names...
I don't know the point of your program, but you may try to read the implementation of std::next_permutation. Generating all permutations with loops is somewhat tricky and I prefer using recursion.