Quantcast
Channel: CodeChef Discuss - latest questions
Viewing all 39796 articles
Browse latest View live

CHEFSIGN - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Dmytro Berezin
Primary Tester:Misha Chorniy
Editorialist:Hussain Kara Fallah

DIFFICULTY:

Cakewalk

PREREQUISITES:

None

PROBLEM:

Given a sequence of N arithmetic signs ( = , + , - ) between N+1 unknown integers. You are allowed to fix these integers using numbers in the range [1,P] such that the expression is true when you read it from left to right. (Numbers don't violate the signs). You are asked to calculate minimum possible P such you can construct a valid expression.

EXPLANATION:

First of all, it's clear that we can drop all '=' signs and pretend that they never existed, because each number which follows an '=' sign would be identical to the number preceding this sign. So these signs aren't affecting our answer at all. After discarding all '=' signs our answer would be :

P = max(maximum number of consecutive '<' signs, maximum number of consecutive '>' signs) + 1

Let's process our expression from left to right, If we are facing X (X ≤ P-1) consecutive '<' signs, our starting number would be P-X, and we increment our last number by 1 after each sign,so the number after the last sign would be exactly P (which will be followed by '>' sign). Our last number will be followed by Y consecutive '>' signs, so we assign the next number to Y (Y < P) and we decrement the last number by 1 by each '>' sign we process. The number after the last sign would be 1. (In case our expression starts with '>' the situation would just be reversed). After that we would have another block of Z consecutive '<' signs, so we assign the next number to P-Z (P-Z ≥ 1) so the number after the last sign would be P and we continue....

Following this approach, the last number after a block of consecutive '<' signs would be P (the maximal value), and the last number after a block of consecutive '>' signs would be 1 (the minimal value). So according to our bold assumption below we can assign values using numbers in the range [1,P] without violating the signs.

Let's take an example:

<<<=>=>=>>><<>>>><<<<<>><<>>

After removing = signs our sequence would be

<<< >>>>> << >>>> << >>>>>

(Blocks are separated by spaces for clarity)

here P = max(3 , 5 , 2 , 4 , 5 , 2 , 2 , 2) + 1 = 6

Our sequence would be

3< 4 < 5 < 6> 5 > 4 > 3 > 2 > 1< 5< 6> 4> 3 > 2 > 1< 5< 6 > 5 > 4 > 3 > 2 > 1

AUTHOR'S AND TESTER'S SOLUTIONS:

TESTER's solution: Will be found here
EDITORIALIST's solution: Will be found here


nzec error in python

$
0
0

t,s=map(float, raw_input().split()) if s%5==0 : if t> s+0.5 : t-=s+0.5 print('%.2f' % t) else : print ('low balance') else : print ('%.2f' % t)

CHN08 - Editorial

$
0
0

PROBLEM LINK:

Contest

Author:???
Tester:Kevin Atienza, Jingbo Shang
Editorialist:Kevin Atienza

PREREQUISITES:

Modulo, recurrences, pattern matching

PROBLEM:

A function $f$ on integers is defined:

  • $f(1) = A$, $f(2) = B$.
  • For all integers $x \ge 2$, $f(x) = f(x-1) + f(x+1)$.

Find $f(N) \bmod (10^9 + 7)$.

QUICK EXPLANATION:

$f$ is periodic with period $6$, so $f(N)$ is equal to $f(N \bmod 6)$. (Just define $f(0) = A-B$.)

EXPLANATION:

At first glance, this problem seems to require standard techniques in solving general linear recurrences. While those techniques will work, they are quite overkill for this problem. Simple pattern spotting will do :) (This solution is much faster to code and very easy to find, so you'll probably be able to get AC earlier with it. The few minutes you save is sometimes significant.)

The key is to simply compute the first few terms. As an example, let's say $A = 11$ and $B = 9$. Since $f(x+1) = f(x) - f(x-1)$ (a rearrangement of the above), we have:

  • $f(\,\,3) = f(\,\,2) - f(\,\,1) = -2$
  • $f(\,\,4) = f(\,\,3) - f(\,\,2) = -11$
  • $f(\,\,5) = f(\,\,4) - f(\,\,3) = -9$
  • $f(\,\,6) = f(\,\,5) - f(\,\,4) = 2$
  • $f(\,\,7) = f(\,\,6) - f(\,\,5) = 11$
  • $f(\,\,8) = f(\,\,7) - f(\,\,6) = 9$
  • $f(\,\,9) = f(\,\,8) - f(\,\,7) = -2$
  • $f(10) = f(\,\,9) - f(\,\,8) = -11$
  • $f(11) = f(10) - f(\,\,9) = -9$
  • $f(12) = f(11) - f(10) = 2$
  • ...

At this point, you might notice that the sequence repeats every $6$ terms. Once you notice this, you might think to try to prove it rigorously before coding it. Though proving it is simple, you don't have to do it; you just pray to the god of pattern matching and hope that this pattern will go on forever (or you trust your instinct). Though this doesn't always work, with experience and intuition, you'll eventually learn which of the unproven statements / observations you make may actually be true.

Note: Don't forget to ensure that $f(N) \bmod (10^9 + 7)$ is positive! Also, $f(N)$ can be $< -(10^9 + 7)$, so adding $(10^9 + 7)$ just once isn't enough to make $f(N)$ positive.

Proving it

But as just mentioned, proving it is simple. Let's first generalize the observation above, by actually using variables $A$ and $B$:

  • $f(3) = f(2) - f(1) = B - A$
  • $f(4) = f(3) - f(2) = -A$
  • $f(5) = f(4) - f(3) = -B$
  • $f(6) = f(5) - f(4) = A - B$
  • $f(7) = f(6) - f(5) = A$
  • $f(8) = f(7) - f(6) = B$
  • $f(9) = f(8) - f(7) = B - A$
  • $f(10) = f(9) - f(8) = -A$
  • $f(11) = f(10) - f(9) = -B$
  • $f(12) = f(11) - f(10) = A - B$
  • ...

Let's now prove that this pattern will go on forever:

Claim: For $n \ge 1$, $f(n) = f(n+6)$.

Proof:

Clearly, this is true for $n = 1$ and $n = 2$ (because $f(1) = f(7) = A$ and $f(2) = f(8) = B$). Now, assume $n > 2$. Assume by induction that it is true for all $1 \le n' < n$. So it must be true for $n-2$ and $n-1$. Then:

$$\begin{align*} f(n)&= f(n-1) - f(n-2) \\\&= f((n-1)+6) - f((n-2)+6) \\\&= f(n+5) - f(n+4) \\\&= f(n+6) \end{align*}$$

This proves the claim.

End of proof

The general idea is that because each term $f(n)$ depends only on the previous two terms $(f(n-2), f(n-1))$, once two consecutive terms repeat, the whole function will repeat forever. In our case, since $(A,B)$ repeated, we're sure that the following sequence will just repeat previous terms after that.

This also works even if $f(n)$ is not a linear recurrence! If $f(n) = g(f(n-2), f(n-1))$ for some function $g$, then regardless of the nature of $g$, as long as you find a repeat of the pair $(f(n-2),f(n-1))$, the function $f$ will repeat after that point. This also works if $f$ was a recurrence that depended on more than two previous terms, say $k \ge 2$, though this time you'll need to keep track of a $k$-tuple of values instead of a pair.

More properties

Let's analyze $f$ more deeply. Using generating functions, we can actually find a neat formula for $f$. (though it doesn't necessarily yield any algorithmic improvements, it is interesting nonetheless.) It will also explain why every three terms almost repeats, except that you have to flip the sign first. To make things cleaner, in the following we'll write $f_n$ as a synonym of $f(n)$. We'll also define $f(0) = A - B$, so the recurrence still holds.

Let $F(x) = f_0 + f_1x + f_2x^2 + f_3x^3 + \ldots$. Then:

$$\begin{array}{rrrrrrr} F(x) = & f_0 &+ f_1x &+ f_2x^2 &+ f_3x^3 &+ f_4x^4 &+ \ldots \\\ xF(x) = & & f_0x &+ f_1x^2 &+ f_2x^3 &+ f_3x^4 &+ \ldots \\\ x^2F(x) = & & & f_0x^2 &+ f_1x^3 &+ f_2x^4 &+ \ldots \\\ \end{array}$$

Now, consider $F(x) - xF(x) + x^2F(x)$, by adding like terms together. Since $f_n = f_{n-1} - f_{n-2}$, almost all terms will cancel out. The only nonzero terms are the constant and linear term. Thus, we have:
$$\begin{align*} F(x) - xF(x) + x^2F(x) &= f_0 + f_1x \\\ (1 - x + x^2)F(x) &= f_0 + f_1x \\\ F(x) &= \frac{f_0 + f_1x}{1 - x + x^2} \\\ F(x) &= \frac{A-B + Ax}{1 - x + x^2} \end{align*}$$

Now, let's try to factorize $1 - x + x^2$. It has two roots: $\dfrac{1 \pm \sqrt{3}i}{2}$. Let us use the symbol $\psi$ and $\bar{\psi}$ for $\dfrac{1 + \sqrt{3}i}{2}$ and $\dfrac{1 - \sqrt{3}i}{2}$, respectively ($\bar{x}$ denotes complex conjugation). Thus, $1 - x + x^2$ must be equal to $(x - \psi)(x - \bar{\psi})$. But since $\psi\bar{\psi} = 1$, we get:

$$\begin{align*} 1 - x + x^2&= (x - \psi)(x - \bar{\psi}) \\\&= \psi\bar{\psi}(x - \psi)(x - \bar{\psi}) \\\&= (\bar{\psi}x - \bar{\psi}\psi)(\psi x - \psi\bar{\psi}) \\\&= (\bar{\psi}x - 1)(\psi x - 1) \\\&= (1 - \psi x)(1 - \bar{\psi}x) \end{align*}$$

Note that $\psi$ and $\bar{\psi}$ are both primitive $6$th roots of unity, so $\psi^6 = \bar{\psi}^6 = 1$. (verify)

Back to $F(x)$, we get:

$$\begin{align*} F(x) &= \frac{A-B + Ax}{1 - x + x^2} \\\ F(x) &= \frac{A-B + Ax}{(1 - \psi x)(1 - \bar{\psi}x)} \end{align*}$$ At this point, let's use the method of partial fractions, to obtain $$F(x) = \frac{C}{1 - \psi x} + \frac{D}{1 - \bar{\psi}x}$$ where $C$ and $D$ are constants that we don't know yet. This form is very useful to us because of the equality: $$\frac{1}{1 - rx} = 1 + rx + r^2x^2 + r^3x^3 + \ldots$$ which means that the coefficient of $x^n$ in $F(x)$ is just $C\psi^n + D\bar{\psi}^n$, giving us a formula for $f(n)$. Right away, this tells us that $f(n)$ is periodic with period $6$, because $\psi$ and $\bar{\psi}$ are both primitive $6$th roots of unity. It also explains why $f(n) = -f(n+3)$: It's because $\psi^3 = \bar{\psi}^3 = -1$.

To compute $C$ and $D$, simply add the two fractions together and equate coefficients: $$\begin{align*} F(x) &= \frac{C}{1 - \psi x} + \frac{D}{1 - \bar{\psi}x} \\\ F(x) &= \frac{(C + D) - (C\bar{\psi} + D\psi)x}{(1 - \psi x)(1 - \bar{\psi}x)} \end{align*}$$ Thus, we get $C + D = A - B$ and $C\bar{\psi} + D\psi = A$. By solving this system, we get $$D = -\frac{A(\psi-2)+B(\psi+1)}{3}$$ $$C = -\frac{A(\bar{\psi}-2)+B(\bar{\psi}+1)}{3}$$

This gives us the following formula for $f(n)$:
$$f(n) = -\frac{1}{3}\left[\left(A(\psi-2)+B(\psi+1)\right)\psi^n + \left(A(\bar{\psi}-2)+B(\bar{\psi}+1)\right)\bar{\psi}^n\right]$$

In general, for any periodic sequence $g(n)$ with period $k$, $g$ always has some formula that looks like:
$$g(n) = a_0 + a_1\omega_k^n + a_2\omega_k^{2n} + a_3\omega_k^{3n} + \ldots + a_{k-1}\omega_k^{(k-1)n}$$ where $\omega_k$ is a primitive $k$th root of unity (so $\{1, \omega_k, \omega_k^2, \ldots, \omega_k^{k-1}\}$ is the complete set of $k$th roots of unity).

Time Complexity:

$O(1)$

AUTHOR'S AND TESTER'S SOLUTIONS:

[setter][333]
[tester][444]
[editorialist][555]

[333]: The link is provided by admins after the contest ends and the solutions are uploaded on the CodeChef Server. [444]: The link is provided by admins after the contest ends and the solutions are uploaded on the CodeChef Server. [555]: The link is provided by admins after the contest ends and the solutions are uploaded on the CodeChef Server.

What is the bothering factor in these 2 submissions?

$
0
0

Hi, I tried submitting a solution for the Calculator problem from the recently concluded July Challenge. The first submission fetched me a partial result whereas the second submission fetched full points. The only change I did was that I added long long to the third argument of the function findans. Can someone explain the intricacy behind this please?

HELP@ Pishty and Tree ( SIGABRT )

Codechef Rating Predictor

$
0
0

Hello everyone!

alt text

Codechef Rating Predictor

The delay in previous month rating changes + inspiration from CF Predictor and for the practice of a web-application, i tried to write a script that can predict rating changes from ongoing live contests @ Codechef.

While the actual delays in rating changes s/would be fixed, this script can help in predicting rating changes as new submissions are made, so hopefully it can be useful for Long contests :).

The script is written in nodejs and is based on open rating formulas available at this link. The code for the project can be accessed here

Website is currently hosted on Openshift free servers and has few restrictions on use. Therefore the server might be slow or not responding during the period rating changes are calculated. Currently, ratings are expected to be updated every 15 minutes

I also tested rating changes on few past contests and the predictions were accurate within an error of 2 for almost everyone except the first rank (I have no idea why first rank predictions are wrong in some contests using current formulas)

Please note that project is still in beta stage and also actual changes might differ more due to changes in ranklist after plagiarism detection

Your feedback/suggestions would be appreciated

JUNE17 Links:

All: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/JUNE17/all/

Long: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/JUNE17/long/

Few stats on JUNE17 Predictions. I matched ratings (All) of first 6391 users and the results were as follows:

Difference - No of users

  • 0 - 5868
  • 1 - 275
  • 2 - 125
  • 3 - 68
  • >= 4 - 55

There were around 40 users having difference > 50. Turns out some usernames appears to be missing in the ranklist when sorted by rank and hence they were showing as last in the prediction list.

I ran the code again after fixing the above bug and results are better now (Maximum difference is 8)

  • 0 - 5900
  • 1 - 485
  • >= 2 - 6

COOK83 Links:

All: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/COOK83/all/

Short: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/COOK83/short/

The ratings are expected to update every 5 minute

Few stats, 4811/4820 predictions (for both all and cook-off predictions) were right. Rest have diff < 3 with the exception of rating prediction of first rank in cook off. Also, as @vikasj554 pointed out, few users got rating changed after initial update. (I still need to figure out why this happened). But even after this 4794/4820 predictions were accurate.

LTIME49 Links:

All: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/LTIME49/all/

Lunchtime : http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/LTIME49/ltime/

The ratings are again expected to update every 5 minute

JULY17 Links:

All: http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/JULY17/all/

Long : http://codechef-rating-predictor.7e14.starter-us-west-2.openshiftapps.com/contest/JULY17/long/

Update frequency: 10 mins

IPCTRAIN getting TLE for 100 marks plz help (my Code is written in java)?

$
0
0

here below is my code which working for 40 marks but not for 100 marks.. i know my program time complexity is near to 10^10 for worst case for 100 marks, but i dont know how to reduce time for my code, what to do further, after looking at editorial, i havn't understood anything plz help me

   /*
     * To change this license header, choose License Headers in Project Properties.
     * To change this template file, choose Tools | Templates
     * and open the template in the editor.
 */
package codechef;

import java.util.Comparator;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;

/**
 *
 * @author Hemant Dhanuka
 */
public class IPCTRAIN1for100Marks {

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        //        FastReader s = new FastReader();
        int totalCases = s.nextInt();
        for (int i = 0; i < totalCases; i++) {

            int NoOfTrainers = s.nextInt();
            int Days = s.nextInt();
            boolean DaysAvailablity[] = new boolean[Days];

            //       LinkedList<Node> l=new LinkedList<>();
            //           PriorityQueue pq=new PriorityQueue(new MyComparator());
            TreeSet pq = new TreeSet(new MyComparator());

            for (int j = 0; j < NoOfTrainers; j++) {
                int arrivalDay = s.nextInt();
                int totalLecutures = s.nextInt();
                int Sadness = s.nextInt();
                Node jiskoAddkarnaH = new Node(arrivalDay, totalLecutures, Sadness);

                pq.add(jiskoAddkarnaH);

            }
            //  System.out.println(pq);
            Iterator finalItr = pq.iterator();
            long MinimumSadness = 0;
            while (finalItr.hasNext()) {
                Node Trainee = (Node) finalItr.next();
                //System.out.println(Trainee.Sadness);
                for (int j = Trainee.arrivalDay; j <= Days && Trainee.totalLecutures > 0; j++) {
                    if (!DaysAvailablity[j - 1]) {
                        Trainee.totalLecutures--;
                        DaysAvailablity[j - 1] = true;

                    }
                }
                MinimumSadness += ((long) Trainee.totalLecutures) * Trainee.Sadness;

            }

            System.out.println(MinimumSadness);
        }
    }
}

class MyComparator implements Comparator<Object> {

    @Override
    public int compare(Object o1, Object o2) {
        if (((Node) o1).Sadness < ((Node) o2).Sadness) {
            return 1;
        } else if (((Node) o1).Sadness == ((Node) o2).Sadness) {
            if (((Node) o1).arrivalDay >= ((Node) o2).arrivalDay) {
                return 1;
            }

        }
        return -1;
    }

}

class Node {

    int arrivalDay;
    int totalLecutures;
    int Sadness;

    Node(int d, int t, int s) {
        this.arrivalDay = d;
        this.totalLecutures = t;
        this.Sadness = s;
    }
}

help me out


chef and sign sequence

CHECK THIS CODE SIMPLE CODE

$
0
0

/ Written by:Kishan Chaudhary Name of project:/

include <stdio.h>

int main(void) {

int num; int result;

printf("Enter integer/t"); scanf("%d",num);

result=num/10;

printf("Result is: %d",result);

return 0; }

Unable to find bug in SRVRS simple solution

$
0
0

Hi everyone!

My solution for July challenge problem SRVRS gets "Wrong Answer" even with very simple approach - link. It generates all possible answers (vector o) and prints them from last server to first and from first CPU to last. Also I added some asserts trying to find the bug; the asserts check that all answers are different, server id and CPU id are correct, the result contains exactly Q responses. Moreover, if one line is commented, solution gets "Correct Answer" (link). The commented line in function "place" actually does not affect the answer, since it operates with variable which isn't used here (I used it for more complicated solution). Also the correctness of operation is checked too and local variable "ans" (which is returned by the function) is marked as "const".

Besides, the author of the problem said (via "Comments" section) that this code gets "Runtime Error" at "testing page" (Codechef online IDE?)

Usually such things are the result of undefined behaviour caused by some incorrect operation, but still can't find it. So, can anyone please help with the following?

  1. What is wrong with the "Wrong Answer" solution?
  2. How the commented line changed it go "Correct Answer"?
  3. Is it actually WA or RE? What result should be displayed for interactive problems in case of RE?

Any ideas?

Recently started coding - Some good resources

$
0
0

I have been looking forward to some good learning resources. Although , I have found a few books but I prefer audiobooks rather than video lectures and pdfs.

If anyone can help me with that , I would be glad.

Thanks :)

Dekebuza

MCHEF - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Sunny Aggarwal
Tester:Mugurel Ionut Andreica
Editorialist:Lalit Kundu

DIFFICULTY:

Easy-Medium

PREREQUISITES:

dynamic programming, data structures

PROBLEM:

Given an array of $N$ elements consisting of both negative and positive elements and $M$ operations. Each operation is of type $L$, $R$ and $K$ which implies that you can remove any one element within range $L$ to $R$(both include) by paying $K$ cost (each operation can be used multiple times).

You have a fixed budget $C$. You have to maximize the total sum of the array such that the expenditure in maximizing sum of elements does not exceed your budget $C$.

Here, $N, M \le 10^5$ and $C \le 200$.

QUICK EXPLANATION:

First for each element find the minimum cost required to remove it. And then using DP similar to 0-1 Knapsack Problem calculate the maximum possible sum.

For finding minimum cost to remove each element:

  • For subtask 1, you can brute force i.e. for each operation traverse over all indices it effects and update the value in an array.

  • For solving subtask 2, you have to either use STL sets or you can use segment trees.

EXPLANATION:

================
The most basic observation here is that each operation allows to remove single element only. So, let's say you want to remove $A_i$, you can remove it in many ways. Let's define by set $S_i$ the set of operations which can remove $A_i$. So $S_i = \{\textrm{oper}_j : L_j \le i \le R_j\}$. Now you can intuitively/greedily say that for removing $A_i$ you would always choose the operation from set $S_i$ whose cost is minimum.

Now, let's say for all $i$, we have found the minimum cost to remove $A_i$. How we actually do this I will explain later. So our problem now is basically:

You have an array $A$ of size $N$.. For each element $A_i$ there is cost of removal $R_i$. Remove some elements from $A_i$ to maximize the sum of remaining elements and also total cost of removal shouldn't exceed $C$. This is quite similar to 0-1 Knapsack Problem which can be solved via Dynamic Programming(DP).

So, first step in writing/formalizing any DP problem is to decide some states which defines a sub problem of the problem we are trying to solve. You can do some hit and trial before you reach the correct states. Next step is to break the current problem into smaller sub problems which can help in defining the recursive relation between the DP states. Last step is to decide the base case.

So, here we define $\textrm{solve}\hspace{1mm}(i,\hspace{1mm}j)$ as the answer if our budget is $j$ and our array is formed by the first $i$ elements ie. $A_1, A_2, ..., A_i$. So our answer will be $\textrm{solve}\hspace{1mm}(N,\hspace{1mm}C)$.

Now let's try to form recursive relations. You want to reduce your current problem i.e. $\textrm{solve}\hspace{1mm}(i,\hspace{1mm}j)$ into smaller sub problems. How can we do that? To reduce current problem in smaller parts, we have to perform some action, which here is to decide whether to remove $A_i$ or not.

Let's consider case 1, where we will remove $A_i$. This is only possible if $j \ge R_i$. Now, $\textrm{solve}\hspace{1mm}(i,\hspace{1mm}j)$ = $\textrm{solve}\hspace{1mm}(i-1,\hspace{1mm}j - R_i)$. Note that we have lost $R_i$ cost on removing $A_i$ and our array is now reduced to first $i - 1$ elements. Also, in the sum of remaining elements $A_i$ couldn't contribute anything. (A thought: Will we ever remove $A_i$ if it's positive, considering removing elements incurs cost?).

Now, case 2, let's not remove $A_i$. Now, $\textrm{solve}\hspace{1mm}(i,\hspace{1mm}j)$ $=$ $A_i$ + $\textrm{solve}\hspace{1mm}(i-1,\hspace{1mm}C)$. Now, $A_i$ is not removed and contributes to the sum of remaining elements. Also, our budget remains same and our array size is now reduced by $1$.

So, our recurrence is ready which is basically:
$\textrm{solve}\hspace{1mm}(i,\hspace{1mm}j)$ = $\textrm{max}(\hspace{1mm}\textrm{solve}\hspace{1mm}(i-1,\hspace{1mm}j - R_i), \hspace{1mm} A_i + \textrm{solve}\hspace{1mm}(i-1,\hspace{1mm}j))$.

Let's see what are the base cases. The only base case is that if $i==0$ i.e. there is no array left, the only maximum sum possible is $0$.

DP Implementation:

This is the last step of completing your DP problem. The best and the easiest way of writing DP is recursively with memoisation. There is no major difference in run time of recurisve and iterative DP.

Now, what is memoisation? It basically is method where you don't calculate things you've already calculated. So you maintain a $\textrm{flag}$ array which is same type of your DP array and intialised to $\textrm{false}$. Once you have calculated a certain subproblem, you mark it true in the $\textrm{flag}$ array. If you ever reach again a state, which has already been calculated, you return the value currently stored in DP array. Things will get clear from the following implementation:

    flag[N][C]  #initialised to false
    DP[N][C]    #array which stores actual answers
    A[N]        #array A
    R[N]        #cost array

    solve(i, j):
        #base case
        if i<=0:
            return dp[i][j]=0   #first sets dp[i][j] to 0 and returns it

        if flag[i][j] == true:  #this dp has already been calculated
            return dp[i][j]

        #case 2: don't remove A[i]
        ret = A[i] + solve(i - 1, j)

        #case 1: remove A[i] if possible
        #tak ret to be the maximum of both cases
        if(j >= R[i])
            ret = max(ret, solve(i - 1, j - R[i]))

        #mark flag[i][j] true since we have calculated this DP
        flag[i][j] = true

        return dp[i][j] = ret

Complexity of DP:

Let's set what is the complexity of such a recursive implementation. Since each possible state is visited once, the complexity of DP is number of states multiplied with transition cost. Transition cost is the complexity required from transfrom from one state to another state.

Here, our total number of states is $\textrm{N * C}$ and transition cost is constant time. So, total complexity is $\textrm{O(N * C)}$.

Calculating minimum cost for removing each element

Now, about the part which we skipped earlier about calculating minimum cost of removing of $A_i$.

First you initialize all indices of a $MIN$ array to infinity and then for each operation you traverse through all indices which it covers and update the minimum value at each index. Here complexity is $\textrm{O(M*N)}$, where $M$ is number of operations and $N$ is size of array $A$. This is enough to pass Subtask 1.

For solving Subtask 2, interesting observation is that an index $i$ is affected by operations whose left end is before $i$ and right end is after $i$. Suppose we have a data structure where we can insert/delete elements and find minimum value currently stored in this data structure in sub linear time. Let's say this structure is $S$.
So, let's maintain two vector arrays $L$ and $R$(means you can store a list of values at each index) and for each operation $j$ insert at index $L_j$ and $R_j$ the cost of this particular operation ie. $K_j$. Now, when we traverse arrays $L$ and $R$ from left to right, say we are index $i$, for indices $\ge i$, values stored in list $L[i]$ are going to effect them, so we add to our structure the values stored at $L[i]$ and the values stored in $R[i]$ are not going to affect indices $\ge i$, so we remove all values stored at $R[i]$. What could be this data structure $S$. If we use STL set, we can insert/delete a object only once, but this is not what we require. There might be two operations with same cost. So instead of storing values, we can store a pair of value and the indices of operations. In this way all operations will be unique and the beginning element of set will always give the minimum value operation.

If you don't feel enough clarity, see this pseudo code and try to visualize what is happening.

    struct oper{
        int l, r, k;
    };

    oper operarray[M];      //array of operations
    int MIN[N];             //MIN[i] stores minimum cost for removing A[i]
    vector<int> L[N], R[N];
    //arrays as defined in above paragraph
    //except now they store indices of operations instead of their cost

    set < pair < int, int > > iset;
    //first element of pair stores value of operation cost
    //second stores the index of operation

    for i = 1 to M:
        left = operarray[i].l
        right = operarray[i].r

        L[left].push_back(i)
        R[right].push_back(i)

    for i = 1 to N:

        //add all operations beginning at i
        for j = 0 to L[i].size() - 1:
            operindex = L[i][j]     //index of operation beginning here
            cost  = operarray[operindex].k

            //insert in set
            iset.insert(make_pair(cost, operindex))

        MIN[i] = iset.begin()->first;   //first element of the set

        //remove all operations ending at i
        for j = 0 to R[i].size() - 1:
            operindex = R[i][j]     //index of operation beginning here
            cost  = operarray[operindex].k

            //erase from set
            iset.erase(make_pair(cost, operindex))

Set is a STL data structure that inserts and deletes elements in $O(\textrm{log (size of set)})$. And since it keeps all elements in sorted order, we can find minimum element in constant time.

So total complexity of finding the $\textrm{MIN}$ array is $\textrm{O(N log M)}$. You can also find $\textrm{MIN}$ array using segment trees where the complexity will be $\textrm{O((M + N) log N)}$, if we use lazy propagation and make updates.

COMPLEXITY:

Final complexity after including complexity of DP is $\textrm{O(N log M + N C)}$.

AUTHOR'S, TESTER'S SOLUTIONS:

setter
tester

Problems to Practice:

Problems based on DP

Problems based on STL

CHEFROUT - Editorial

$
0
0

Problem Link

Practice

Contest

Author:Praveen Dhinwa

Tester:Pawel Kacprzak and Misha Chorniy

Editorialist:Bhuvnesh Jain

Difficulty

CAKEWALK

Prerequisites

Looping techniques

Problem

You are given an array consisting of 'C', 'E' and 'S' denoting cooking, eating and sleeping respectively. You need to tell whether the array is correct i.e. has 'C', 'E' and 'S' in correct order or not.

Explanation

Solution 1

The problem can be solved as stated in the question itself. All we need to find is whether is the activities recorded by Chef's dog are in the order Cooking, Eating and Sleeping or not. So, we can group the equal elements together. This can be done easily using a "for" loop as follows:

vector<char> u; for i in 0 to s.length()-1: j = i while(j < s.length() && s[i]==s[j]): j += 1 u.push_back(s[i]); i = j-1

Now, if size(u) > 3, then answer is definitely "no". Otherwise, check if it follows the sequence. i.e.

if size(u) == 3, u[0] = 'C', u[1] = 'E', u[2] = 'S' if size(u) == 2, u[0] = 'C', u[1] = 'S' or u[0] = 'C', u[1] = 'E' or u[0] = 'E', u[1] = 'S' if size(u) == 1, trivally true

The above will suffice for 100 points as the complexity of the above code is $O(n)$. It may initially seem that the complexity of the above code is $O(n^2)$. To see why the above doesn't hold, let us analyze the complexity in a different manner. We see how many time each position will be visited. Each position will be visited once, either by the variable $i$ or $j$. Since there are $n$ locations in total, the complexity becomes $O(n)$.

Solution 2

The question can be solved using information about the state only. Let us denote the states 'C', 'E', 'S' by 0, 1, 2 respectively. Then the solution is "yes" if and only if, $state[i] <= state[i+1]$ for $0 <= i < s.length()-1$. The editorialist has used this idea and the implementation can be seen in his solution.

Solution 3

This solution is similar to the second one except that instead of maintaining the state, we just check if the given string corresponding to the required regular expression or not. This is also a builtin function in most languages as well.

For example, the C++ code would be

cout << (regex_match(s, regex("^CES*$")) ? "yes" : "no") << endl;

The java code code be found in the answer below.

Time Complexity

$O(n)$ per test case

Solution Links

Setter's solution

Tester's solution

Editorialist solution

airlines management system


two coins problem in july 2017 long contest

Point in polygon problem

$
0
0

Given a point and a set of sides which make up a convex polygon, output true if the point is inside of the polygon, otherwise output false.

I understand that this problem is basic but I struggle to find a solution for it. After trying to solve it myself I looked up some solutions but they don't work either if I understand the problem correctly. For example, the solution posted on geeks for geeks doesn't work for the following case:

Coordinates of the point which needs to be checked: (-2,0) Sides of the polygon (one line corresponds to one side by connecting the two given points on that line):

(-4 -1), (-5 0)
(-1 1), (0 4)
(-5 0), (-5 1)
(-5 1), (-1 1)
(5 0), (3 -4)
(3 -4), (2 -5)
(0 4), (4 4)
(-2 -1), (-4 -1)
(4 4), (5 0)
(2 -5), (-2 -1)

The point is inside of the polygon but the geeks for geeks solution (and many others) claim that the point is outside.

Am I missing something or is the geeks for geeks solution wrong?

SRVRS - Editorial (Unofficial) & Discussion

$
0
0

PROBLEM LINK:

PracticeContest

Author:Alexandru Valeanu
Editorialist:Tiny Wong

DIFFICULTY:

CHALLENGE.

PREREQUISITES:

Greedy,k-d tree.

PROBLEM:

Given $n$ points $(x_i, y_i)$ with a collection of CPUs of processing time $p_{ij}$. You are asked to answer $q$ queries ONLINE. Each query contains a point $(x, y)$, and you should associate it with an unused CPU, and the cost is $\sqrt{(x-x_i)^2+(y-y_i)^2}+p_{ij}$. Once a CPU of processing time $p_{ij}$ is associated, it cannot be used until $p_{ij}$ seconds passes.

QUICK EXPLANATION:

There is a good enough greedy method, which is that we choose the minimal cost CPU that is unused currently.

EXPLANATION:

In order to follow the greedy method declared in QUICK EXPLANATION, we can just use a k-d tree to find the nearest point.

More precisely, the CPUs are considered to be a 3-dimensional point $(x_i, y_i, p_{ij})$ with the meanings corresponding to the above, while each query point can be regarded as $(x, y, 0)$. The distance between two points is defined by $$ \operatorname{dis}((x_1, y_1, z_1), (x_2, y_2, z_2)) = \sqrt{(x_1-x_2)^2+(y_1-y_2)^2}+|z_1-z_2|. $$

Just following the simple idea can make you become a top coder of this problem.

EDITORIALIST'S SOLUTION:

EDITORIALIST's solution is here

CALC - Editorial

$
0
0

PROBLEM LINK:

Practice
Contest

Author:Hasan Jaddouh
Primary Tester:Misha Chorniy
Editorialist:Hussain Kara Fallah

DIFFICULTY:

Easy

PREREQUISITES:

Simple Math

PROBLEM:

We have a calculator with 2 screens and 2 buttons. Each screen shows number zero initially. Pressing the first button increments the number on the first screen by 1, and each press of this button consumes 1 unit of energy. Pressing the second button increases the number on the second screen by the number appearing on the first screen. Each click of this button consumes B units of energy. Given B,N what's the maximum possible number that may show on the second screen without consuming more than N units of energy?

EXPLANATION:

First of all, it's obvious that it's not optimal to press the first button after pressing the second. We must press the first button for number of times, after that we should spend the remaining energy on pressing the second button.

Let's define a function f(x) where f(x) represents the maximum number displayed on the second screen if we pressed the second button exactly x times.

$f(x) = (N-x*B) * x$

$f(x) = -x^2 * B + Nx$

We can notice that the graph of this function is a parabola. Our best answer would be $f(k) = h$

where the point (k,h) is the vertex of the parabola. It's well known that

$k = \frac{-b}{2a} $

for any parabola following the form $f(x) = ax^2 + bx + c$

So here : $k = \frac{N}{2*B}$

We can also deduce that from the derivative and find the local extrema of the function.

Since we can press the second button only integer number of presses so we must try, $k1 = \lfloor \frac{N}{2*B}\rfloor$ AND $k2 = \lceil \frac{N}{2*B}\rceil$ and pick the better choice.

Ternary search is another possible solution for this problem.

AUTHOR'S AND TESTER'S SOLUTIONS:

AUTHOR's solution: Will be found here
TESTER's solution: Will be found here
EDITORIALIST's solution: Will be found here

Run Error and TLE in PSHTTR (Help Needed)

Viewing all 39796 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>