Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Recently, I was trying to solve this dynamic programing problem, but somehow not getting the approach to solve it.
The editorial to the problem seems very confusing too and i would understand how to think properly to approach this problem.
Thanks.
The problem
F. Yet Another Minimization Problem: Time limit per test: 2 seconds |
Memory limit per test: 256 megabytes |
Input: standard input |
Output: standard output
You are given an array of n integers a1... an. The cost of a subsegment is the number of unordered pairs of distinct indices within the subsegment that contain equal elements. Split the given array into k non-intersecting non-empty subsegments so that the sum of their costs is minimum possible. Each element should be present in exactly one subsegment.
Input
The first line contains two integers n and k (2 ≤ n ≤ 105, 2 ≤ k ≤ min (n, 20)) - the length of the array and the number of segments you need to split the array into.
The next line contains n integers a1, a2, ..., an (1 ≤ ai ≤ n) - the elements of the array.
Output
Print single integer: the minimum possible total cost of resulting subsegments.
Example 1
input
7 3
1 1 3 3 3 2 1
output
1
Example 2
input
10 2
1 2 1 2 1 2 1 2 1 2
output
8
Example 3
input
13 3
1 2 2 2 1 2 1 1 1 2 2 1 1
output
9
Note:
In the first example it's optimal to split the sequence into the following three subsegments: [1], [1, 3], [3, 3, 2, 1]. The costs are 0, 0 and 1, thus the answer is 1.
In the second example it's optimal to split the sequence in two equal halves. The cost for each half is 4.
In the third example it's optimal to split the sequence in the following way: [1, 2, 2, 2, 1], [2, 1, 1, 1, 2], [2, 1, 1]. The costs are 4, 4, 1.
Understanding the problem
You just need to count the number of pairs in the serie of numbers (line 2) divised by k (line 1, second number)
From the example 2:
10 2
1 2 1 2 1 2 1 2 1 2
[numbers length] [divider]
[serie of numbers]
Take a look about the serie of numbers:
1 2 1 2 1 2 1 2 1 2
You need to divide by 2 the serie as an minimum total cost by pairs
[1,2,1,2,1] [2,1,2,1,2]
Then count the numbers of pairs for each number:
[1,2,1,2,1]
1 => [2,1,2,1] = 2 pairs
2 => [1,2,1] = 1 pair
1 => [2,1] = 1 pair
2 => [1] = 0
1 => [] = 0
Sum = 4 pairs
[2,1,2,1,2]
2 => [1,2,1,2] = 2 pairs
1 => [2,1,2] = 1 pairs
2 => [1,2] = 1 pairs
1 => [2] = 0
2 => [] = 0
Sum = 4 pairs
Total = 8
How to find the best segment cost (Finally wrong..)
This method is totally experimental and seems to be correct (but could be totally wrong too ... for now i tested some series and it worked)
I took an other example:
10 3
7 7 2 4 6 9 7 4 1 1
Subsegment 1: I count the number of pairs in all the serie, then i sum each paired value by her key in the array (starting to 0), divide this result by the number of pairs, then round (ceil?) at the closest integrer to find the position (which starting to 1).
Subsegment 2 and 3: I do exactly the same but i excluded the first sub segment.
Total: [7,7,2,4,6,9] [7,4,1] [1] = 1 + 0 + 0 = 1
Testing
I did a little script to generate random values relative to the problem:
var n = document.getElementById('n')
var k = document.getElementById('k')
var s = document.getElementById('s')
var btn = document.getElementById('btn')
// apply random values
function random() {
n.value = Math.ceil(Math.random() * (Math.random()*20)+2)
k.value = Math.ceil(Math.random() * (n.value/3)+1)
var serie = []
for(var i = 0; i<n.value; i++){
serie.push(Math.ceil(Math.random() * (n.value-1)))
}
s.value = serie.join(' ')
}
window.onload = function() { random() }
btn.onclick = function() { random() }
<input id="n" size="2" value="14">
<input id="k" size="2" value="3">
<input id="s" size="40">
<button id="btn">Random</button>
Hope it will help.
Related
The problem is to find the prefix sum of array of length N by repeating the process M times. e.g.
Example N=3
M=4
array = 1 2 3
output = 1 6 21
Explanation:
Step 1 prefix Sum = 1 3 6
Step 2 prefix sum = 1 4 10
Step 3 prefix sum = 1 5 15
Step 4(M) prefix sum = 1 6 21
Example 2:
N=5
M=3
array = 1 2 3 4 5
output = 1 5 15 35 70
I was not able to solve the problem and kept getting lime limit exceeded. I used dynamic programming to solve it in O(NM) time. I looked around and found the following general mathematical solution but I still not able to solve it because my math isn't that great to understand it. Can someone solve it in a better time complexity?
https://math.stackexchange.com/questions/234304/sum-of-the-sum-of-the-sum-of-the-first-n-natural-numbers
Hint: 3, 4, 5 and 6, 10, 15 are sections of diagonals on Pascal's Triangle.
JavaScript code:
function f(n, m) {
const result = [1];
for (let i = 1; i < n; i++)
result.push(result[i-1] * (m + i + 1) / i);
return result;
}
console.log(JSON.stringify(f(3, 4)));
console.log(JSON.stringify(f(5, 3)));
I am given a number from 1 to N , and there are M relationship given in the form a and b where we can connect number a and b.
We have to form the valid array , A array is said to be valid if for any two consecutive indexes A[i] and A[i+1] is one of the M relationship
We have to construct a valid Array of Size N, it's always possible to construct that.
Solution: Make A Bipartite Graph of the following , but there is a loophole on this,
let N=6
M=6
1 2
2 3
1 3
4 5
5 6
3 4
So Bipartite Matching gives this:
Match[1]=2
Match[2]=3
Match[3]=1 // Here it form a Loop
Match[4]=5
Match[5]=6
So how to i print a valid Array of size N , since N can be very large so many loops can be formed ? Is there any other solution ?
Another Example:
let N=6
M=6
1 3
3 5
2 5
5 1
4 2
6 4
It's will form a loop 1->3->5->1
1 3 5 2 4 6
A matrix of size nxn needs to be constructed with the desired properties.
n is even. (given as input to the algorithm)
Matrix should contain integers from 0 to n-1
Main diagonal should contain only zeroes and matrix should be symmetric.
All numbers in each row should be different.
For various n , any one of the possible output is required.
input
2
output
0 1
1 0
input
4
output
0 1 3 2
1 0 2 3
3 2 0 1
2 3 1 0
Now the only idea that comes to my mind is to brute-force build combinations recursively and prune.
How can this be done in a iterative way perhaps efficiently?
IMO, You can handle your answer by an algorithm to handle this:
If 8x8 result is:
0 1 2 3 4 5 6 7
1 0 3 2 5 4 7 6
2 3 0 1 6 7 4 5
3 2 1 0 7 6 5 4
4 5 6 7 0 1 2 3
5 4 7 6 1 0 3 2
6 7 4 5 2 3 0 1
7 6 5 4 3 2 1 0
You have actually a matrix of two 4x4 matrices in below pattern:
m0 => 0 1 2 3 m1 => 4 5 6 7 pattern => m0 m1
1 0 3 2 5 4 7 6 m1 m0
2 3 0 1 6 7 4 5
3 2 1 0 7 6 5 4
And also each 4x4 is a matrix of two 2x2 matrices with a relation to a power of 2:
m0 => 0 1 m1 => 2 3 pattern => m0 m1
1 0 3 2 m1 m0
In other explanation I should say you have a 2x2 matrix of 0 and 1 then you expand it to a 4x4 matrix by replacing each cell with a new 2x2 matrix:
0 => 0+2*0 1+2*0 1=> 0+2*1 1+2*1
1+2*0 0+2*0 1+2*1 0+2*1
result => 0 1 2 3
1 0 3 2
2 3 0 1
3 2 1 0
Now expand it again:
0,1=> as above 2=> 0+2*2 1+2*2 3=> 0+2*3 1+2*3
1+2*2 0+2*2 1+2*3 0+2*3
I can calculate value of each cell by this C# sample code:
// i: row, j: column, n: matrix dimension
var v = 0;
var m = 2;
do
{
var p = m/2;
v = v*2 + (i%(n/p) < n/m == j%(n/p) < n/m ? 0 : 1);
m *= 2;
} while (m <= n);
We know each row must contain each number. Likewise, each row contains each number.
Let us take CS convention of indices starting from 0.
First, consider how to place the 1's in the matrix. Choose a random number k0, from 1 to n-1. Place the 1 in row 0 at position (0,k0). In row 1, if k0 = 1 in which case there is already a one placed. Otherwise, there are n-2 free positions and place the 1 at position (1,k1). Continue in this way until all the 1 are placed. In the final row there is exactly one free position.
Next, repeat with the 2 which have to fit in the remaining places.
Now the problem is that we might not be able to actually complete the square. We may find there are some constraints which make it impossible to fill in the last digits. The problem is that checking a partially filled latin square is NP-complete.(wikipedia) This basically means pretty compute intensive and there no know short-cut algorithm. So I think the best you can do is generate squares and test if they work or not.
If you only want one particular square for each n then there might be simpler ways of generating them.
The link Ted Hopp gave in his comment Latin Squares. Simple Construction does provide a method for generating a square starting with the addition of integers mod n.
I might be wrong, but if you just look for printing a symmetric table - a special case of latin squares isomorphic to the symmetric difference operation table over a powerset({0,1,..,n}) mapped to a ring {0,1,2,..,2^n-1}.
One can also produce such a table, using XOR(i,j) where i and j are n*n table indexes.
For example:
def latin_powerset(n):
for i in range(n):
for j in range(n):
yield (i, j, i^j)
Printing tuples coming from previously defined special-case generator of symmetric latin squares declared above:
def print_latin_square(sq, n=None):
cells = [c for c in sq]
if n is None:
# find the length of the square side
n = 1; n2 = len(cells)
while n2 != n*n:
n += 1
rows = list()
for i in range(n):
rows.append(" ".join("{0}".format(cells[i*n + j][2]) for j in range(n)))
print("\n".join(rows))
square = latin_powerset(8)
print(print_latin_square(square))
outputs:
0 1 2 3 4 5 6 7
1 0 3 2 5 4 7 6
2 3 0 1 6 7 4 5
3 2 1 0 7 6 5 4
4 5 6 7 0 1 2 3
5 4 7 6 1 0 3 2
6 7 4 5 2 3 0 1
7 6 5 4 3 2 1 0
See also
This covers more generic cases of latin squares, rather than that super symmetrical case with the trivial code above:
https://www.cut-the-knot.org/arithmetic/latin2.shtml (also pointed in the comments above for symmetric latin square construction)
https://doc.sagemath.org/html/en/reference/combinat/sage/combinat/matrices/latin.html
I have a vector that includes a value for every possible combination of two numbers out of a bigger group of n numbers (from 0 to (n-1)), excluding combinations where both numbers are the same.
For instance, if n = 4, combinations will be the ones shown in columns number1 and number2.
number1 number2 vector-index value
0 1 0 3
0 2 1 98
0 3 2 0
1 0 3 44
1 2 4 6
1 3 5 3
2 0 6 2
2 1 7 43
2 3 8 23
3 0 9 11
3 1 10 54
3 2 11 7
There are always n*(n-1) combinations and therefore that is the number of elements in the vector (12 elements in the example above).
Problem
In order to access the values in the vector I need a expression that allows me to figure out the corresponding index number for every combination.
If combinations where number1=number2 were included, the index number could be figured our using:
index = number1*(n-1)+number2
This question is related but includes also combinations where number1=number2.
Is there any expression to calculate the index in this case?
First, notice that all the pairs can be grouped into blocks of size (n-1), where n is the number of different indices. This means that given a pair (i, j), the index of the block containing it will be i(n-1). Within that block the indices are laid out sequentially, skipping over index i. If j < i, then we just look j steps past the start of the block. Otherwise, we look j-1 steps past it. Overall this gives the formula
int index = i * (n - 1) + (j < i? j : j - 1);
Note that the only difference is when number2 is greater than number1, when this happens a value from number2 sequence was skipped, so you will need to decrease the count, something like this:
index = number1 * (n - 1) + number2 - (number2 > number1 ? 1 : 0)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
How do I check if a number is sum of multiples of 3 and 5 given that the number could be as big as 100,000 . I need an optimized way to break a number into two parts such that the two parts are multiple of 3 and 5 only and the part which is multiple of 3 is greater than the part which is multiple of 5 and if that kind of splitting is not possible then I need to reject that number .
Eg:
1 => cant be split so rejected ,
35 => 30 + 5 ,
65 => 60 + 5 (Though 30 + 35 could be a split but since part which is multiple of 3 has to be greater than the part which is multiple of 5),
11 => 6+5
Every (integer) number modulo 3 yields 0, 1 or 2.
So let's examine all cases (n > 3 must yield for obvious reasons):
n % 3 == 0. Easy: We just take 0 == 0 * 5 and n / 3 as splitting.
n % 3 == 2. Easy again: One number will be 5 and the other (n-5) / 3. When subtracting 5 from n, we will create a second number (n-5), which falls under the first case.
n % 3 == 1. Same as in case 2, but this time we substract 10 == 2*5.
A small problem is the property that the multiple of 3 has to be larger than the one of 5. For this to hold true, n has to be at least 22. ( 22 == 2 * 5 + 3 * 4).
So all numbers smaller than 22 with the property n % 3 == 1 have to be rejected: 4, 7, 10, 13, 16 and 19. (As long as the factor for the multiples have to be non-negative).
If you mean to find a way to split a number to two parts, where the first part is a multiple of 3 and the second is a multiple of 5, with the extra requirement that the first (multiple of 3) part is greater than than the second (multiple of 5) part, then it's rather trivial:
Every number from 20 and above can be split that way.
Proof: For given number N, exactly one of the three numbers, N, N-5, N-10 will be a multiple of 3 (consider modulo 3 arithmetic.) So, one of these three splits satisfy the requirements:
N 0
N-5 5
N-10 10
and since N >= 20, the 1st part is greater (or equal) than the 2nd.
Off the top of my head --
Make Q = N / 3, integer division, rounding down. Make R the remainder.
If R = 0 you're done.
If R == 2, decrement Q.
Else R must be 1, subtract 2 from Q.
Your answer is Q * 3 and N - (Q * 3). Check that all results are positive and that the 3s multiple > 5s multiple restriction is satisfied.
(Note that this is essentially the same as Sirko's answer, but I felt it worthwhile to think it through separately, so I didn't attempt to analyze his first.)
max divisor of 3 and 5 is 1.
so when N = 3, or N >= 5, it can be sum of multiple of 3 and 5.
Just use this code:-
Enjoy :)
$num = 0; // Large Number
$arr = array();
if(isset($_POST['number']) $num = $_POST['number'];
// Assuming you post the number to be checked.
$j=0;
for($i=0;$i<$num;$i++)
{
if(($num-$i)%3==0 || ($num-$i)%5==0) { $arr[j] = $num - $i; $j++; }
}
//This creates an array of all possible numbers.
$keepLooping = true;
while($keepLooping)
{
$rand = array_rand($arr,2);
if(($rand[0] + $rand[1]) == $num)
{
//Do whatever you like with them. :)
}
}
I haven't tested it though but just for your idea. Instead of the for loop to select the possibilities, you can choose some other way whichever suits you.