Hello codeforces community , problem ZigZag array is for distinct data , I solved this problem . But if data are duplicate(same data occur several times) problem become very complex . There has many corner case :
11
2 4 6 8 9 11 10 8 5 3 1
=>2 8 8 1 ( solution 1, remove 7 numbers)
=>2 11 1 (solution 2, remove 8 numbers)
so ans is 7
10
1 2 3 4 7 8 9 7 6 4
=>1 4 4 (solution 1, remove 7 numbers)
=>1 7 7 4 (solution 2, remove 6 numbers)
=>1 9 4 (solution 3, remove 7 numbers)
so ans is 6
6
1 2 3 4 5 4
=>1 4 4 (solution 1, remove 3 numbers)
=>1 5 4 (solution 2, remove 3 numbers)
so ans is 3
5
1 2 3 2 1
=>1 2 2 1 (solution 1, remove 1 number)
=>1 3 1 (solution 2,remove 2 numbers)
so ans is 1
If 1<=n<=10^5 , How to solve this problem ? and how to implement it efficiently ? I implement it but code become very complex : https://pastebin.com/QrhWgdEj
You are not using DP on this problem, but you can solve simply with using DP in O(n2) (because n ≤ 100). First, the problem is asking "minimum number of deletion", but it is same value to n — "maximum length of zigzag subsequence". Second, let dp[i][0] = "the maximum length of subsequence that ends in i and satisfying (the second element from the last) > (the last element), and dp[i][1] is almost same definition but (the second last) < (the last). And, the DP relation is: dp[i][0] = max(1, maxj < i, a[j] > a[i]{dp[j][1] + 1}), and dp[i][1] = max(1, maxj < i, a[j] < a[i]{dp[j][0] + 1}). Finally the answer is n - max(dp[n - 1][0], dp[n - 1][1]). My code is here (16-line in C++)
This is a main idea, but if the array has same values, you have to add dp[i][2] for equal and change DP relation a little.
EDIT: It's n ≤ 100 (real contest constraints) solution (It's O(n2) and of course if n ≤ 10000 you can solve it). I know you edited the blog and changed the constraints to n ≤ 100000.
Your code complexity is n*(n+1)/2 = O(n^2) . If n is large 10^5 . How to do it more efficiently ?
It can be optimised with two segment trees.
[blank]
It's similar to counting lis(longest increasing sequence) with segment tree.
I think your counting LIS algorithm is "sort p[i] = pair(a[i], i) in increasing order, and calculate like dpp[i].second = min(dp0, dp1, ..., dpp[i].second - 1) + 1. (If I'm wrong, I'm sorry) If so, I think the technique can't use because you have to calculate in decreasing order for dp[i][0], and increasing order for dp[i][1]. But dp[i][0] uses dp[i][1] value, and vice versa. How to calculate it?
Compress numbers in the input so everything is in range [1, n]. Now our dp is dp[x][0,1] = length of sequence with last number x, because we process indexes in increasing order. It can be calculated fast with two segment trees. Is it wrong?
It is still O(n2), but if your approach is correct, it seems that you can solve in O(nlogn) with std::set.
Any proof of your solution is correct?
EDIT: Mr_Emrul, I want to know whether your solution is correct (+proof) if the element of array is not necessarily distinct.
EDIT 2: daihan hacked so this is a wrong solution.
My solution in HR
If you can not see (not public) then I will give you screenshot.
square1001 can you give me a test case? please :) then i will test it
You are not answering my question. Of course I know your code and already tested my few tricky cases and got a correct value. I only want to know why your solution is correct. If you can, please give me a mathematical explanation.
You wanted to know whether my solution is correct or not. You didn't asked my why my code is correct.
square1001, for giving proof to you, I definitely need a test case from you, needn't I?
your code not for duplicate data .
please give me a test case, which give wrong output for my code.
10
1 2 3 4 7 8 9 7 6 4
=>1 4 4 (removed 7 numbers)
=>1 7 7 4 (removed 6 numbers)
=>1 9 4 (removed 7 numbers)
ans should be 6 . Your code gives 7 .
then, i am sorry.
thanks also! :)