Problem Statement:
Codeforces Round #355 (Div. 2) - D. Vanya and Treasure
Summary:
You have a 2D array m x n with values [1..p] on each cell (p <= n*m). Distance between two cells is defined as Manhattan distance. Compute the path with minimum total distance that passes through 1, 2, ..., p in order. [Additionally, the problem always starts from cell (1, 1)].
Showing posts with label Divide and Conquer. Show all posts
Showing posts with label Divide and Conquer. Show all posts
Monday, June 6, 2016
Monday, October 19, 2015
Count the number of set bits
Found something cool today. The problem is simple: Count the number of set bits in a bit representation of an integer. Of course the simplest solution will be to go through the bits one by one and count the number of 1s. The time complexity is O(n), where n is the length of the bit representation. Turns out, we can do better.
Thursday, May 14, 2015
Codeforces 526F - Pudding Monsters
Problem Statement:
526F - Pudding Monsters
Solution:
A self note for a tough problem. The problem is equivalent to finding the number of segments in an array A, with a property that the elements in each valid segment is a permutation of a consecutive sequence of numbers. Furthermore, A itself is a permutation of [1..n].
The first way to solve this problem is by considering a divide and conquer strategy: Let A[1..n] be the sequence of numbers. Let S(i..j) be the number of valid segments in A[i..j]. Then we can find S(i..j) by splitting A[i..j] into 2 parts A[i..m] and A[m+1..j] where m is (i+j)/2. By recursion, assume we know how to compute S(i..m) and S(m+1..j). What is left is to compute the number of segments that crosses A[i..m] and A[m+1..j]. Let L denote A[i..m], while R denote A[m+1..j]. For all such valid segments M[u..v], we have:
526F - Pudding Monsters
Solution:
A self note for a tough problem. The problem is equivalent to finding the number of segments in an array A, with a property that the elements in each valid segment is a permutation of a consecutive sequence of numbers. Furthermore, A itself is a permutation of [1..n].
The first way to solve this problem is by considering a divide and conquer strategy: Let A[1..n] be the sequence of numbers. Let S(i..j) be the number of valid segments in A[i..j]. Then we can find S(i..j) by splitting A[i..j] into 2 parts A[i..m] and A[m+1..j] where m is (i+j)/2. By recursion, assume we know how to compute S(i..m) and S(m+1..j). What is left is to compute the number of segments that crosses A[i..m] and A[m+1..j]. Let L denote A[i..m], while R denote A[m+1..j]. For all such valid segments M[u..v], we have:
Thursday, January 1, 2015
Codeforces Good Bye 2014 Problem F - New Year Shopping
Problem Statement
500F - New Year Shopping
Solution:
A pretty tough problem which solution employs a very clever divide and conquer strategy. Learnt cool stuff :D.
Let's suppose that all the items are already sorted by \(t_i\) in increasing order. We know that item i will be available in the time segment \([t_i,t_i+p-1]\). Suppose that for each time \(T\), we know which are the segments that contain \(T\), i.e. the set of i such that \(T \in [t_i,t_i+p-1]\).
500F - New Year Shopping
Solution:
A pretty tough problem which solution employs a very clever divide and conquer strategy. Learnt cool stuff :D.
Let's suppose that all the items are already sorted by \(t_i\) in increasing order. We know that item i will be available in the time segment \([t_i,t_i+p-1]\). Suppose that for each time \(T\), we know which are the segments that contain \(T\), i.e. the set of i such that \(T \in [t_i,t_i+p-1]\).
Monday, September 8, 2014
a bit of codeforces: Cool Divide and Conquer
Problem Statement:
448C - Painting Fence
Summary:
Given \(N \leq 5000\) sequences of numbers (fences), you can either:
- (paint horizontally) Substract 1 from the sequence consecutively from one end (may start from the first number, or from the next number after any 0s) to the other end (or when another 0 is encountered, whichever is earlier)
- (paint vertically) Set a number to 0
Given this operations, find the minimum number of operation needed to make all number equal to 0
Solution:
The solution to this problem is damn cool and it fits squarely under the divide and conquer paradigm.
Let S(L, R, H) be the minimum number of operations needed to paint the fences from L to R. H is the portion of the height of the fences that have already been painted.
Firstly, we can paint all fence vertically, that means at worst we need R-L+1 number of operations to pain all fences. Otherwise, we can paint the fence horizontally in hope of having a smaller amount of operations. When we paint the fence horizontally, we want to cover as much fences as possible. Furthermore, we want to horizontally paint until we hit the fence with minimum height, since otherwise we will be wasting operation, call this minimum height minH, hence we need minH - H operations. This leads to the formation of separate segments of uncolored fences, which form a smaller subproblem with exactly the same structure. We recursively process each segments and add up the total of each operation together with the operations incurred previously. Finally, we return whichever is smaller, the number of operations incurred when horizontal painting is used, or when only vertical painting is used.
I've written a code for the solution, which run in \(O(N\lg{N})\) time ( since the relationship \(T(N) \leq T(N/2) + O(N) \) holds ).
448C - Painting Fence
Summary:
Given \(N \leq 5000\) sequences of numbers (fences), you can either:
- (paint horizontally) Substract 1 from the sequence consecutively from one end (may start from the first number, or from the next number after any 0s) to the other end (or when another 0 is encountered, whichever is earlier)
- (paint vertically) Set a number to 0
Given this operations, find the minimum number of operation needed to make all number equal to 0
Solution:
The solution to this problem is damn cool and it fits squarely under the divide and conquer paradigm.
Let S(L, R, H) be the minimum number of operations needed to paint the fences from L to R. H is the portion of the height of the fences that have already been painted.
Firstly, we can paint all fence vertically, that means at worst we need R-L+1 number of operations to pain all fences. Otherwise, we can paint the fence horizontally in hope of having a smaller amount of operations. When we paint the fence horizontally, we want to cover as much fences as possible. Furthermore, we want to horizontally paint until we hit the fence with minimum height, since otherwise we will be wasting operation, call this minimum height minH, hence we need minH - H operations. This leads to the formation of separate segments of uncolored fences, which form a smaller subproblem with exactly the same structure. We recursively process each segments and add up the total of each operation together with the operations incurred previously. Finally, we return whichever is smaller, the number of operations incurred when horizontal painting is used, or when only vertical painting is used.
I've written a code for the solution, which run in \(O(N\lg{N})\) time ( since the relationship \(T(N) \leq T(N/2) + O(N) \) holds ).
int minH(int L, int R){ int ret = MAXINT; for(int i=L;i<=R;++i){ ret = min(ret, a[i]); } return ret; } int rec(int L, int R, int H){ int MH = minH(L,R); int ret = MH - H; int prev, state = 0; for(int i=L;i<=R;++i){ if(a[i] > MH && state == 0){ prev = i; state = 1; } else if( a[i] == MH && state == 1){ ret += rec(prev, i-1, MH); state = 0; } } if(state == 1) ret += rec(prev, R, MH); return min(R-L+1, ret); }
Subscribe to:
Posts (Atom)