AMcoder - javascript, python, java, html, php, sql

Դինամիկ ծրագրավորում. կատարյալ գումար բացասական թվերով

Հաշվի առնելով ամբողջ թվերի զանգվածը և գումարը, խնդիրն է՝ տպել տրված զանգվածի բոլոր ենթաբազմությունները՝ տրված գումարին հավասար գումարով:

Example: 
Input : arr[] = {1, 2, 3, 4, 5}
        sum = 10
Output : [4 3 2 1]  
         [5 3 2] 
         [5 4 1]

Input : arr[] = {-1, 2, 3, 4, 5}
        sum = 10
Output : [5 3 2] 
         [5 4 2 -1]

Ես դա արել եմ՝ օգտագործելով դինամիկ ծրագրավորում կեղծ բազմանդամ ժամանակում: Սա ենթաբազմության գումարի խնդրի ընդլայնումն է, որը միայն հոգ է տանում որոշում կայացնելու՝ արդյոք այդպիսի ենթաբազմություն գոյություն ունի, թե ոչ: Ստորև ներկայացված իմ լուծումն աշխատում է ենթաբազմության գումարի խնդրի և՛ դրական, և՛ բացասական թվերի համար: Այնուամենայնիվ, այն ի վիճակի չէ ճիշտ տպել ենթաբազմությունները, եթե զանգվածը պարունակում է բացասական թվեր: Ծրագիրը հետևյալն է.

import java.util.ArrayList;

// sum problem
class GFG {

    static boolean subset[][];

    // Returns true if there is a subset of
    // set[] with sun equal to given sum
    static boolean isSubsetSum(int set[],
                               int n, int sum) {
        // The value of subset[i][j] will be
        // true if there is a subset of
        // set[0..j-1] with sum equal to i
        subset = new boolean[n + 1][sum + 1];

        // Fill the subset table in botton
        // up manner
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= sum; j++) {
                if (j == 0) {
                    subset[i][j] = true;
                } else if (i <= 0 && sum >= 1)
                    subset[i][j] = false;
                else if (set[i - 1] > j)
                    subset[i][j] = subset[i - 1][j];
                else {
                    if (set[i - 1] >= 0)
                        subset[i][j] = subset[i - 1][j] || subset[i - 1][j - set[i - 1]];
                    else
                        subset[i][j] = subset[i - 1][j] || subset[i - 1][j + set[i - 1]];
                }
            }
        }

        // uncomment this code to print table
//        for (int i = 0; i <= sum; i++)
//        {
//        for (int j = 0; j <= n; j++)
//            System.out.println (subset[i][j]);
//        }

        return subset[n][sum];
    }

    /* Driver program to test above function */
    public static void main(String args[]) {
        int set[] = {1, 2, 3, 4, 5};
        int sum = 10;
        int n = set.length;
        if (isSubsetSum(set, n, sum) == true)
            System.out.println("Found a subset"
                    + " with given sum");
        else
            System.out.println("No subset with"
                    + " given sum");
        System.out.println("Done");
        ArrayList<Integer> list = new ArrayList<>();
        printSubsets(set, n, sum, list);
        System.out.println("Finished");
    }

    static void display(ArrayList<Integer> v) {
        System.out.println(v);
    }

    private static void printSubsets(int[] set, int i, int sum, ArrayList<Integer> list) {
        if (i == 0 && sum != 0 && subset[0][sum]) {
            list.add(set[i]);
            display(list);
            list.clear();
            return;
        }

        // If sum becomes 0
        if (i == 0 && sum == 0) {
            display(list);
            list.clear();
            return;
        }

        // If given sum can be achieved after ignoring
        // current element.
        if (subset[i - 1][sum]) {
            // Create a new vector to store path
            ArrayList<Integer> b = new ArrayList<>();
            b.addAll(list);
            printSubsets(set, i - 1, sum, b);
        }

        // If given sum can be achieved after considering
        // current element.

        if (sum >= set[i - 1] && subset[i - 1][sum - set[i - 1]]) {
            list.add(set[i - 1]);
            printSubsets(set, i - 1, sum - set[i - 1], list);
        }

    }   
} 

Ինչպե՞ս կարող է այս կոդը փոփոխվել, որպեսզի աշխատի նաև բացասական թվերի համար:



Պատասխանները:


1

Քանի որ դուք պետք է տպեք ( կամ ստեղծեք ) տվյալ բազմության բոլոր հնարավոր ենթաբազմությունը (պարունակում է ինչպես դրական, այնպես էլ բացասական ամբողջ թվեր), որոնց գումարը հավասար է գումարին , այն, ինչ դուք կարող եք անել, հետևյալն է.

փորձեք բազմության յուրաքանչյուր դիրքը ներկայացնել որպես 0-ի և 1-ի երկուական ներկայացում, որտեղ 1-ը ցույց է տալիս, որ տարրն այդ դիրքում վերցված է, իսկ 0-ը ցույց է տալիս, որ այդ դիրքում գտնվող տարրը հաշվի չի առնվել:

Գտե՛ք բոլոր դիրքերի գումարը, որտեղ կա 1: Եթե այս արժեքների գումարը ճիշտ հավասար է տրված գումարին, ապա տպեք այդ ենթաբազմությունը:

Այսպիսով, ընդհանուր ժամանակային բարդությունը O(2 ^ n) է, որտեղ n-ը տվյալ բազմության երկարությունն է:

Դուք կարող եք դիտել հետևյալ իրականացումը:

import java.util.Arrays;

public class PerfectSum {

public static void printSubsets(int[] set, int n, int sum) {
     int totalSubSets = (1 << n);
     for (int i = 1; i < totalSubSets; ++i) { // loop over all possible subsets
         int curSum = 0;
         for (int j = n - 1; j >= 0; --j) {
             if (((i >> j) & 1) > 0) { // if bit at jth position is 1 take that value
                curSum +=set[j];
             }
         }
         if (curSum == sum) { // valid subset found, then print it
             for (int j = n - 1; j >= 0; --j) { // looping in reverse order to print set in decreasing order
                 if (((i >> j) & 1) > 0) { // if bit at jth position is 1 take that value
                     System.out.print(set[j] + " ");
                 }
             }
             System.out.println("");
         }
     }
}

public static void main(String[] args) {
    int set[] = {-1, 2, 3, 4, 5};
    Arrays.sort(set); // To print in non increasing order
    int sum = 10;
    int n = set.length;
    printSubsets(set, n, sum);
  }
}
19.09.2018
  • Շնորհակալություն լուծման համար: Բայց ես կարծում եմ, որ սա մի տեսակ բիրտ ուժ է, որտեղ մենք կրկնում ենք բոլորի միջով՝ համապատասխան ենթաբազմությունները ստանալու համար: Կա՞ որևէ ձև, որը մենք կարող ենք դա անել՝ օգտագործելով դինամիկ ծրագրավորում (այսինքն՝ կեղծ բազմանդամ ժամանակում): 19.09.2018
  • Քանի որ մենք պետք է տպենք բոլոր հնարավոր ենթաբազմությունները, մենք չենք կարող դա անել O(2 ^ n-ից) պակաս ժամանակում։ շնորհակալություն!! 20.09.2018

  • 2

    Ձեր լուծումները ենթադրում են, որ բոլոր արժեքները դրական են, ուստի դինամիկ ծրագրավորման զանգվածը՝ subset, լցված է j արժեքներով, որոնք դրական են, բայց դուք պետք է հիմա հաշվի առնեք բացասական գումարները:

    Այն, ինչ դուք պետք է անեք, դա է փոխել j-ի հանգույցի սահմանները՝ դինամիկ ծրագրավորման զանգվածը լրացնելու համար

    for (int j = negative_sum; j <= positive_sum; j++)
    

    Որտեղ negative_sum-ը բոլոր բացասական արժեքների գումարն է, իսկ positive_sum-ը բոլոր դրական արժեքների գումարն է:

    Լրացուցիչ մանրամասների համար կարդացեք Վիքիպեդիայի էջը Ենթաբազմության գումարի խնդրի համար այստեղ որտեղ այս քայլը բացատրվում է:

    29.04.2019

    3

    Դուք կարող եք զանգվածի նվազագույն բացասական թիվը հանել ամբողջ բազմությունից՝ զանգվածի թվերը դարձնելով դրական։ Այնուհետև կիրառեք դինամիկ ծրագրավորում:

    26.01.2019
    Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..