Maximum subset which has no sum of two divisible by K

后端 未结 5 850
栀梦
栀梦 2021-02-14 16:49

I am given the set {1, 2, 3, ... ,N}. I have to find the maximum size of a subset of the given set so that the sum of any 2 numbers from the subset is not divisible by a given n

相关标签:
5条回答
  • 2021-02-14 17:14
    n,k=(raw_input().split(' '))
    n=int(n)
    k=int(k)
    l=[0 for x in range(k)]
    d=[int(x) for x in raw_input().split(' ')]
    flag=0
    for x in d:
       l[x%k]=l[x%k]+1
    
    sum=0
    
    if l[0]!=0:
        sum+=1 
    if (k%2==0):
        sum+=1
    
    
    if k==1:
        print 1
    elif k==2:
        print 2 
    else:       
        i=1
        j=k-1
        while i<j:
            sum=sum+(l[i] if l[i]>=l[j] else l[j])
            i=i+1
            j=j-1
         print sum
    
    0 讨论(0)
  • 2021-02-14 17:15

    formula is

    |N/K| * |(K-1)/2| + ost 
    
    ost =
    if n<k:
      ost =0
    else if n%k ==0 :
      ost =1    
    else if n%k < |(K-1)/2| :
      ost = n%k
    else:
      ost = |(K-1)/2|
    

    where |a/b| for example |9/2| = 4 |7/2| = 3

    example n = 30 , k =7 ;

    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

    1 2 3 |4| 5 6 7. - is first line . 8 9 10 |11| 12 13 14 - second line if we getting first 3 number in each line we may get size of this subset. also we may adding one number from ( 7 14 28)

    getting first 3 number (1 2 3) is a number |(k-1)/2| . a number of this line is |n/k| . if there is not residue we may add one number (for example last number). if residue < |(k-1)/2| we get all number in last line else getting |(K-1)/2|.

    thanks for exception case. ost = 0 if k>n

    0 讨论(0)
  • 2021-02-14 17:15

    This is explanation to ABRAR TYAGI and amin k's solution.

    The approach to this solution is:

    • Create an array L with K buckets and group all the elements from the input array D into the K buckets. Each bucket L[i] contains D's elements such that ( element % K ) = i.
    • All the elements that are individually divisible by K are in L[0]. So only one of these elements (if any) can belong in our final (maximal) subset. Sum of any two of these elements is divisible by K.
    • If we add an element from L[i] to an element in L[K-i] then the sum is divisible by K. Hence we can add elements from only one of these buckets to our final set. We pick the largest bucket.

    Code: d is the array containing the initial set of numbers of size n. The goal of this code is to find the count of the largest subset of d such that the sum of no two integers is divisible by 2.

    l is an array that will contain k integers. The idea is to reduce each (element) in array d to (element % k) and save the frequency of their occurrences in array l.

    For example, l[1] contains the frequency of all elements % k = 1

    We know that 1 + (k-1) % k = 0 so either l[1] or l[k-1] have to be discarded to meet the criteria that sum of no two numbers % k should be 0.

    But as we need the largest subset of d, we choose the larger of l[1] and l[k-1]

    We loop through array l such that for (i=1; i<=k/2 && i < k-i; i++) and do the above step.

    There are two outliers. The sum of any two numbers in the l[0] group % k = 0. So add 1 if l[0] is non-zero.

    if k is even, the loop does not handle i=k/2, and using the same logic as above increment the count by one.

    0 讨论(0)
  • 2021-02-14 17:23

    first calculate all of the set elements mod k.and solve simple problem: find the maximum size of a subset of the given set so that the sum of any 2 numbers from the subset is not equal by a given number K. i divide this set to two sets (i and k-i) that you can not choose set(i) and set(k-i) Simultaneously.

    int myset[]
    int modclass[k]
    
    for(int i=0; i< size of myset ;i++)
    {
        modclass[(myset[i] mod k)] ++;
    }
    

    choose

    for(int i=0; i< k/2 ;i++)
    { 
        if (modclass[i] > modclass[k-i])
        {
            choose all of the set elements that the element mod k equal i
        }
        else
        {
            choose all of the set elements that the element mod k equal k-i
        }
    }
    

    finally you can add one element from that the element mod k equal 0 or k/2.

    this solution with an algorithm of complexity O(K).

    you can improve this idea with dynamic array:

    for(int i=0; i< size of myset ;i++)
    {
        x= myset[i] mod k;
        set=false;
        for(int j=0; j< size of newset ;j++)
        {
            if(newset[j][1]==x or newset[j][2]==x)
            {
                if (x < k/2)
                {
                    newset[j][1]++;
                    set=true;
                }
                else
                {
                    newset[j][2]++;
                    set=true;
                }
            }
        }
        if(set==false)
        {
            if (x < k/2)
            {
                newset.add(1,0);
            }
            else
            {
                newset.add(0,1);
            }
        }
    }
    

    now you can choose with an algorithm of complexity O(myset.count).and your algorithm is more than O(myset.count) because you need O(myset.count) for read your set. complexity of this solution is O(myset.count^2),that you can choose algorithm depended your input.with compare between O(myset.count^2) and o(k). and for better solution you can sort myset based on mod k.

    0 讨论(0)
  • 2021-02-14 17:23

    I'm assuming that the set of numbers is always 1 through N for some N.

    Consider the first N-(N mod K) numbers. The form floor(N/K) sequences of K consecutive numbers, with reductions mod K from 0 through K-1. For each group, floor(K/2) have to be dropped for having a reduction mod K that is the negation mod K of another subset of floor(K/2). You can keep ceiling(K/2) from each set of K consecutive numbers.

    Now consider the remaining N mod K numbers. They have reductions mod K starting at 1. I have not worked out the exact limits, but if N mod K is less than about K/2 you will be able to keep all of them. If not, you will be able to keep about the first ceiling(K/2) of them.

    ==========================================================================

    I believe the concept here is correct, but I have not yet worked out all the details.

    ==========================================================================

    Here is my analysis of the problem and answer. In what follows |x| is floor(x). This solution is similar to the one in @Constantine's answer, but differs in a few cases.

    Consider the first K*|N/K| elements. They consist of |N/K| repeats of the reductions modulo K.

    In general, we can include |N/K| elements that are k modulo K subject to the following limits:

    If (k+k)%K is zero, we can include only one element that is k modulo K. That is the case for k=0 and k=(K/2)%K, which can only happen for even K.

    That means we get |N/K| * |(K-1)/2| elements from the repeats.

    We need to correct for the omitted elements. If N >= K we need to add 1 for the 0 mod K elements. If K is even and N>=K/2 we also need to add 1 for the (K/2)%K elements.

    Finally, if M(N)!=0 we need to add a partial or complete copy of the repeat elements, min(N%K,|(K-1)/2|).

    The final formula is:

    |N/K| * |(K-1)/2| +
    (N>=K ? 1 : 0) +
    ((N>=K/2 && (K%2)==0) ? 1 : 0) +
    min(N%K,|(K-1)/2|)
    

    This differs from @Constantine's version in some cases involving even K. For example, consider N=4, K=6. The correct answer is 3, the size of the set {1, 2, 3}. @Constantine's formula gives |(6-1)/2| = |5/2| = 2. The formula above gets 0 for each of the first two lines, 1 from the third line, and 2 from the final line, giving the correct answer.

    0 讨论(0)
提交回复
热议问题