এটি বাছাই করতে অ্যারের থেকে এন্ট্রিগুলি সরান এবং উপাদানের যোগফলকে সর্বাধিক করে তোলে


13

এই চ্যালেঞ্জটি একটি ভর্তি পরীক্ষা থেকে শুরু করে একটি বদ্ধ নম্বর সাইবার সুরক্ষা কোর্স পর্যন্ত to যাইহোক এটি সাইবার সুরক্ষার সাথে করার দরকার নেই, এটি কেবলমাত্র শিক্ষার্থীদের যৌক্তিক এবং কোডিং দক্ষতা পরীক্ষা করার জন্য।

কার্য

একটি প্রোগ্রাম লিখুন যা অ্যারের থেকে এন্ট্রিগুলিকে সরিয়ে দেয় যাতে বাকী মানগুলি কঠোরভাবে হ্রাসমান ক্রমে সাজানো হয় এবং অন্যান্য সম্ভাব্য হ্রাস ক্রমগুলির মধ্যে তাদের যোগফলটি সর্বাধিক হয়।

ইনপুট এবং আউটপুট

ইনপুটটি পূর্ণসংখ্যার মানগুলির একটি অ্যারে হবে যা একে অপরের চেয়ে কঠোরভাবে বৃহত্তর0 এবং সমস্ত পৃথক । আপনি ফাইল, কমান্ড লাইন বা স্টিডিন থেকে ইনপুট পড়বেন কিনা তা চয়ন করতে পারেন।

আউটপুট হ'ল ইনপুটটির একটি উত্থিত-বাছাই করা সাবহারি হবে, যার যোগফল অন্য সম্ভাব্য উতরাই-বাছাই করা সাবহারির চেয়ে বেশি ray

দ্রষ্টব্য: [5, 4, 3, 2] এটির নিকটবর্তী এবং [5, 4, 1, 3, 2]এমনকি না হলেও এটির একটি সাবহারে । কেবলমাত্র পপ করা হয়েছিল।431

ব্রুটেফোর্স সমাধান

অবশ্যই সবচেয়ে সহজ সমাধানটি প্রদত্ত অ্যারের সমস্ত সম্ভাব্য সংমিশ্রণের মধ্যে পুনরাবৃত্তি হবে এবং পাইথনের সর্বাধিক যোগফলের সাথে বাছাই করা সন্ধান করবে :

import itertools

def best_sum_desc_subarray(ary):
    best_sum_so_far = 0
    best_subarray_so_far = []
    for k in range(1, len(ary)):
        for comb in itertools.combinations(ary, k):
            if sum(comb) > best_sum_so_far and all(comb[j] > comb[j+1] for j in range(len(comb)-1)):
                best_subarray_so_far = list(comb)
                best_sum_so_far = sum(comb)
    return best_subarray_so_far

দুর্ভাগ্যবশত, চেক যদি অ্যারের অনুসারে বাছাই করা হয়, এবং এটি এর উপাদানের সমষ্টি গণক থেকে হয় এবং এই অপারেশন থেকে সম্পন্ন করা হবে বার জন্য থেকে থেকে , মধ্যে asymptotic সময় জটিলতা হতে হবে

চ্যালেঞ্জ

আপনার লক্ষ্য উপরের ব্রুটফোর্সের চেয়ে আরও ভাল সময়ের জটিলতা অর্জন করা। ক্ষুদ্রতম অ্যাসিম্পটিক সময় জটিলতার সাথে সমাধানটি চ্যালেঞ্জের বিজয়ী। যদি দুটি সমাধানের একই অ্যাসিপটোটিক সময়ের জটিলতা থাকে তবে বিজয়ীর মধ্যে ক্ষুদ্রতম অ্যাসিপটোটিক স্থানিক জটিলতা রয়েছে।

দ্রষ্টব্য: আপনি পড়তে, লিখতে এবং পারমাণবিক তুলনায় এমনকি বৃহত সংখ্যায় বিবেচনা করতে পারেন ।

দ্রষ্টব্য: যদি দুটি বা আরও বেশি সমাধান থাকে তবে সেগুলির মধ্যে দুটিই ফিরে আসে।

পরীক্ষার মামলা

Input:  [200, 100, 400]
Output: [400]

Input:  [4, 3, 2, 1, 5]
Output: [4, 3, 2, 1]

Input:  [50, 40, 30, 20, 10]
Output: [50, 40, 30, 20, 10]

Input:  [389, 207, 155, 300, 299, 170, 158, 65]
Output: [389, 300, 299, 170, 158, 65]

Input:  [19, 20, 2, 18, 13, 14, 8, 9, 4, 6, 16, 1, 15, 12, 3, 7, 17, 5, 10, 11]
Output: [20, 18, 16, 15, 12, 7, 5]

Input:  [14, 12, 24, 21, 6, 10, 19, 1, 5, 8, 17, 7, 9, 15, 23, 20, 25, 11, 13, 4, 3, 22, 18, 2, 16]
Output: [24, 21, 19, 17, 15, 13, 4, 3, 2]

Input:  [25, 15, 3, 6, 24, 30, 23, 7, 1, 10, 16, 29, 12, 13, 22, 8, 17, 14, 20, 11, 9, 18, 28, 21, 26, 27, 4, 2, 19, 5]
Output: [25, 24, 23, 22, 17, 14, 11, 9, 4, 2]

সম্পর্কিত। (দুটি অ্যালগরিদম আসলে সমান কিনা তা আমি এখনই যাচাই করতে পারছি না, তবে আমি মনে করি সেগুলি হতে পারে))
মার্টিন এন্ডার

মন্তব্যগুলি বর্ধিত আলোচনার জন্য নয়; এই কথোপকথন চ্যাটে সরানো হয়েছে ।
মার্টিন ইন্ডার

উত্তর:


3

পার্ল

এটি সময়ে ও (এন ^ 2) এবং স্পেসে ও (এন) হওয়া উচিত

STDIN- এ এক লাইনে স্থান দ্বারা পৃথক সংখ্যাগুলি দিন

#!/usr/bin/perl -a
use strict;
use warnings;

# use Data::Dumper;
use constant {
    INFINITY => 9**9**9,
    DEBUG    => 0,
};

# Recover sequence from the 'how' linked list
sub how {
    my @z;
    for (my $h = shift->{how}; $h; $h = $h->[1]) {
        push @z, $h->[0];
    }
    pop @z;
    return join " ", reverse @z;
}

use constant MINIMUM => {
    how  => [-INFINITY, [INFINITY]],
    sum  => -INFINITY,
    next => undef,
};

# Candidates is a linked list of subsequences under consideration
# A given final element will only appear once in the list of candidates
# in combination with the best sum that can be achieved with that final element
# The list of candidates is reverse sorted by final element
my $candidates = {
    # 'how' will represent the sequence that adds up to the given sum as a
    # reversed lisp style list.
    # so e.g. "1, 5, 8" will be represented as [8, [5, [1, INFINITY]]]
    # So the final element will be at the front of 'how'
    how  => [INFINITY],
    # The highest sum that can be reached with any subsequence with the same
    # final element
    sum  => 0,
    # 'next' points to the next candidate
    next => MINIMUM,   # Dummy terminator to simplify program logic
};

for my $num (@F) {
    # Among the candidates on which an extension with $num is valid
    # find the highest sum
    my $max_sum = MINIMUM;
    my $c = \$candidates;
    while ($num < $$c->{how}[0]) {
        if ($$c->{sum} > $max_sum->{sum}) {
            $max_sum = $$c;
            $c = \$$c->{next};
        } else {
            # Remove pointless candidate
            $$c = $$c->{next};
        }
    }

    my $new_sum = $max_sum->{sum} + $num;
    if ($$c->{how}[0] != $num) {
        # Insert a new candidate with a never before seen end element
        # Due to the unique element rule this branch will always be taken
        $$c = { next => $$c };
    } elsif ($new_sum <= $$c->{sum}) {
        # An already known end element but the sum is no improvement
        next;
    }
    $$c->{sum} = $new_sum;
    $$c->{how} = [$num, $max_sum->{how}];
    # print(Dumper($candidates));
    if (DEBUG) {
        print "Adding $num\n";
        for (my $c = $candidates; $c; $c = $c->{next}) {
            printf "sum(%s) = %s\n", how($c), $c->{sum};
        }
        print "------\n";
    }
}

# Find the sequence with the highest sum among the candidates
my $max_sum = MINIMUM;
for (my $c = $candidates; $c; $c = $c->{next}) {
    $max_sum = $c if $c->{sum} > $max_sum->{sum};
}

# And finally print the result
print how($max_sum), "\n";

3

হাস্কেল , সময়, স্পেস( এন )O(nlogn)O(n)

{-# LANGUAGE MultiParamTypeClasses #-}

import qualified Data.FingerTree as F

data S = S
  { sSum :: Int
  , sArr :: [Int]
  } deriving (Show)

instance Monoid S where
  mempty = S 0 []
  mappend _ s = s

instance F.Measured S S where
  measure = id

bestSubarrays :: [Int] -> F.FingerTree S S
bestSubarrays [] = F.empty
bestSubarrays (x:xs) = left F.>< sNew F.<| right'
  where
    (left, right) = F.split (\s -> sArr s > [x]) (bestSubarrays xs)
    sLeft = F.measure left
    sNew = S (x + sSum sLeft) (x : sArr sLeft)
    right' = F.dropUntil (\s -> sSum s > sSum sNew) right

bestSubarray :: [Int] -> [Int]
bestSubarray = sArr . F.measure . bestSubarrays

কিভাবে এটা কাজ করে

bestSubarrays xssub xsবৃহত্তম সমষ্টি, সবচেয়ে ছোট প্রথম উপাদান the এর দক্ষ সীমান্তে এর সাবারিগুলির ক্রম হ'ল যোগফল বৃদ্ধি করে এবং প্রথম উপাদানকে বাড়িয়ে বাম থেকে ডানে আদেশ করা হয়।

থেকে যেতে bestSubarrays xsকরার bestSubarrays (x:xs), আমরা

  1. অনুক্রমটি প্রথম উপাদানগুলির চেয়ে কম x, এবং একটি ডান দিকের চেয়ে কম প্রথম উপাদানগুলির সাথে বাম দিকে বিভক্ত করুন x,
  2. xবাম পাশের ডানদিকের সাববারিকে প্রিপেন্ড করে একটি নতুন সাবহারে সন্ধান করুন,
  3. ডান দিক থেকে সাববারির উপসর্গটি নতুন সাববারির চেয়ে ছোট অঙ্কের সাথে ফেলে দিন,
  4. বাম পাশ, নতুন সুবারে এবং ডান পাশের বাকী অংশটি সংযুক্ত করুন।

O(logn)


1

এই উত্তরটি টন হসপেলের একটিতে প্রসারিত।

পুনরুক্তিটি ব্যবহার করে ডায়নামিক প্রোগ্রামিংয়ের মাধ্যমে সমস্যাটি সমাধান করা যেতে পারে

T(i)=ai+max[{0}{T(j)|0j<iaiaj}]

যেখানে ইনপুট ক্রম এবং কোন কমে উপ-ক্রম সর্বাধিক সাধনযোগ্য সমষ্টি সূচক দিয়ে শেষ । আসল সমাধানটি পরে নিম্নলিখিত জং কোডের মতো ব্যবহার করে আবার ব্যবহার করা যেতে পারে ।টি ( i ) i টি(ai)T(i)iT

fn solve(arr: &[usize]) -> Vec<usize> {
    let mut tbl = Vec::new();
    // Compute table with maximum sums of any valid sequence ending
    // with a given index i.
    for i in 0..arr.len() {
        let max = (0..i)
            .filter(|&j| arr[j] >= arr[i])
            .map(|j| tbl[j])
            .max()
            .unwrap_or(0);
        tbl.push(max + arr[i]);
    }
    // Reconstruct an optimal sequence.
    let mut sum = tbl.iter().max().unwrap_or(&0).clone();
    let mut limit = 0;
    let mut result = Vec::new();

    for i in (0..arr.len()).rev() {
        if tbl[i] == sum && arr[i] >= limit {
            limit = arr[i];
            sum -= arr[i];
            result.push(arr[i]);
        }
    }
    assert_eq!(sum, 0);
    result.reverse();
    result
}

fn read_input() -> Vec<usize> {
    use std::io::{Read, stdin};
    let mut s = String::new();
    stdin().read_to_string(&mut s).unwrap();
    s.split(|c: char| !c.is_numeric())
        .filter(|&s| !s.is_empty())
        .map(|s| s.parse().unwrap())
        .collect()
}

fn main() {
    println!("{:?}", solve(&read_input()));
}

এটি অনলাইন চেষ্টা করুন!

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.