ACM: The 3n + 1 [duplicate] - hud

This question already has answers here:
Uva's 3n+1 problem
(8 answers)
Project Euler Question 14 (Collatz Problem)
(8 answers)
Closed 9 years ago.
The 3n + 1 problem
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 18416 Accepted Submission(s): 6803
Problem Description
Problems in Computer Science are often classified as belonging to a certain class of problems (e.g., NP, Unsolvable, Recursive). In this problem you will be analyzing a property of an algorithm whose classification is not known for all possible inputs.
Consider the following algorithm:
1. input n
2. print n
3. if n = 1 then STOP
4. if n is odd then n <- 3n + 1
5. else n <- n / 2
6. GOTO 2
Given the input 22, the following sequence of numbers will be printed 22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
It is conjectured that the algorithm above will terminate (when a 1 is printed) for any integral input value. Despite the simplicity of the algorithm, it is unknown whether this conjecture is true. It has been verified, however, for all integers n such that 0 < n < 1,000,000 (and, in fact, for many more numbers than this.)
Given an input n, it is possible to determine the number of numbers printed (including the 1). For a given n this is called the cycle-length of n. In the example above, the cycle length of 22 is 16.
For any two numbers i and j you are to determine the maximum cycle length over all numbers between i and j.
Input
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 1,000,000 and greater than 0.
You should process all pairs of integers and for each pair determine the maximum cycle length over all integers between and including i and j.
You can assume that no opperation overflows a 32-bit integer.
Output
For each pair of input integers i and j you should output i, j, and the maximum cycle length for integers between and including i and j. These three numbers should be separated by at least one space with all three numbers on one line and with one line of output for each line of input. The integers i and j must appear in the output in the same order in which they appeared in the input and should be followed by the maximum cycle length (on the same line).
Sample Input
1 10
100 200
201 210
900 1000
Sample Output
1 10 20
100 200 125
201 210 89
900 1000 174

if you use the plain way.for each case,cal all integer's solution.
so ,you can cal the solution for all between 1 and 1,000,000,than store in an array.
use the ST way to cal a new dp[N][M].
than when there is a query ,you can get the ans with O(1) times;
or you can use the Segment Tree to get the ans.
but i am not sure it won't get TLE...
for(int j=0;j<=log(N);j++)
for(int i=1;i<=N;i++)
dp[i][j]=max(dp[i][j-1]+dp[i+pow(2,j-1)][j-1];

Related

The odd number algorithm

I am practicing on some algorithm problems and I have faced a problem which I can't understand clearly.
The problem is a string with N natural numbers, I need to search in this string for K distinct and disjoint sequences, containing in total a number L of elements, so that there is an odd number of odd numbers among the L elements. I want calculate the largest sum that can be obtained with these L numbers.
Input:
8 3 5 <-- natural numbers N, K and L.
1 2 3 4 5 6 7 8 <--- N natural numbers representing the numbers in the string
Subsequent {2}, {4}, {6,7,8} have an odd number of odd elements (one odd element, 7), their sum is 27 and is the maximum that can be obtained with 5 numbers that meet the required property.
Output:
27 <--- a single number representing the maximum amount by applying the rules.
My question is, how did he obtain that output?

Time limit exceeding for my program in python3

IOI Training Camp 20xx
(INOI 2011)
We are well into the 21st century and school children are taught dynamic programming in class 4. The IOI training camp has degenerated into an endless sequence of tests, with negative marking. At the end of the camp, each student is evaluated based on the sum of the best contiguous segment (i.e., no gaps) of marks in the overall sequence of tests.
Students, however, have not changed much over the years and they have asked for some relaxation in the evaluation procedure. As a concession, the camp coordinators have agreed that students are allowed to drop upto a certain number of tests when calculating their best segment.
For instance, suppose that Lavanya is a student at the training camp and there have been ten tests, in which her marks are as follows.
Test 1 2 3 4 5 6 7 8 9 10
Marks 6 -5 3 -7 6 -1 10 -8 -8 8
In this case, without being allowed to drop any tests, the best segment is tests 5–7, which yields a total of 15 marks. If Lavanya is allowed to drop upto 2 tests in a segment, the best segment is tests 1–7, which yields a total of 24 marks after dropping tests 2 and 4. If she is allowed to drop upto 6 tests in a segment, the best total is obtained by taking the entire list and dropping the 5 negative entries to get a total of 33.
You will be given a sequence of N test marks and a number K. You have to compute the sum of the best segment in the sequence when upto K marks may be dropped from the segment.
Solution hint
For 1 ≤ i ≤ N, 1 ≤ j ≤ K, let Best[i][j] denote the maximum segment ending at position i with at most j marks dropped. Best[i][0] is the classical maximum subsegment or maximum subarray problem. For j ≥ 1; inductively compute Best[i][j] from Best[i][j-1].
Input format
The first line of input contains two integers N and K, where N is the number of tests for which marks will be provided and K is the limit of how many entries may be dropped from a segment.
This is followed by N lines of input each containing a single integer. The marks for test i, i ∈ {1,2,…,N} are provided in line i+1.
Output format
The output is a single number, the maximum marks that can be obtained from a segment in which upto K values are dropped.
Constraints
You may assume that 1 ≤ N ≤ 104 and 0 ≤ K ≤ 102. The marks for each test lie in the range [-104 … 104]. In 40% of the cases you may assume N ≤ 250.
def sumsub(ls,k):
if k==0:
return(sum(ls))
else:
ls.sort()
if len(ls)>=k:
for j in range(0,k):
if(ls[0]<0):
ls.remove(ls[0])
return(sum(ls))
else:
for i in range(len(ls)):
if ls[0]<0:
ls.remove(ls[0])
return(sum(ls))
n,k= map(int,input().split(" "))
l=[]
smax=0
for i in range(n):
m=input()
l.append(int(m))
for i in range(n):
for j in range(n,0,-1):
s=sumsub(l[i:j],k)
if s>smax :
smax=s
print(smax)
i am gettin the proper answer but the time limit is exceeding for some.
it'll be of great help if you can provide a solution for this.
There're four 'for' loops running every time when your defined function executes. That's the big reason for the time limit exceeding in execution.

XOR of numbers = X

I found this problem in a hiring contest(which is over now). Here it is:
You are given two natural numbers N and X. You are required to create an array of N natural numbers such that the bitwise XOR of these numbers is equal to X. The sum of all the natural numbers that are available in the array is as minimum as possible.
If there exist multiple arrays, print the smallest one
Array A< Array B if
A[i] < B[i] for any index i, and A[i]=B[i] for all indices less than i
Sample Input: N=3, X=2
Sample output : 1 1 2
Explanation: We have to print 3 natural numbers having the minimum sum Thus the N-spaced numbers are [1 1 2]
My approach:
If N is odd, I put N-1 ones in the array (so that their xor is zero) and then put X
If N is even, I put N-1 ones again and then put X-1(if X is odd) and X+1(if X is even)
But this algorithm failed for most of the test cases. For example, when N=4 and X=6 my output is
1 1 1 7 but it should be 1 1 2 4
Anyone knows how to make the array sum minimum?
In order to have the minimum sum, you need to make sure that when your target is X, you are not cancelling the bits of X and recreating them again. Because this will increase the sum. For this, you have create the bits of X one by one (ideally) from the end of the array. So, as in your example of N=4 and X=6 we have: (I use ^ to show xor)
X= 7 = 110 (binary) = 2 + 4. Note that 2^4 = 6 as well because these numbers don't share any common bits. So, the output is 1 1 2 4.
So, we start by creating the most significant bits of X from the end of the output array. Then, we also have to handle the corner cases for different values of N. I'm going with a number of different examples to make the idea clear:
``
A) X=14, N=5:
X=1110=8+4+2. So, the array is 1 1 2 4 8.
B) X=14, N=6:
X=8+4+2. The array should be 1 1 1 1 2 12.
C) X=15, N=6:
X=8+4+2+1. The array should be 1 1 1 2 4 8.
D) X=15, N=5:
The array should be 1 1 1 2 12.
E) X=14, N=2:
The array should be 2 12. Because 12 = 4^8
``
So, we go as follows. We compute the number of powers of 2 in X. Let this number be k.
Case 1 - If k <= n (example E): we start by picking the smallest powers from left to right and merge the remaining on the last position in the array.
Case 2 - If k > n (example A, B, C, D): we compute h = n - k. If h is odd we put h = n-k+1. Now, we start by putting h 1's in the beginning of the array. Then, the number of places left is less than k. So, we can follow the idea of Case 1 for the remaining positions. Note that in case 2, instead of having odd number of added 1's we put and even number of 1's and then do some merging at the end. This guarantees that the array is the smallest it can be.
We have to consider that we have to minimize the sum of the array for solution and that is the key point.
First calculate set bits in N suppose if count of setbits are less than or equal to X then divide N in X integers based on set bits like
N = 15, X = 2
setbits in 15 are 4 solution is 1 14
if X = 3 solution is 1 2 12
this minimizes array sum too.
other case if setbits are greater than X
calculate difference = setbits(N) - X
If difference is even then add ones as needed and apply above algorithm all ones will cancel out.
If difference is odd then add ones but now you have take care of that 1 extra one in the answer array.
Check for the corner cases too.

Calculating limits in dynamic programming

I found this question on topcoder:
Your friend Lucas gave you a sequence S of positive integers.
For a while, you two played a simple game with S: Lucas would pick a number, and you had to select some elements of S such that the sum of all numbers you selected is the number chosen by Lucas. For example, if S={2,1,2,7} and Lucas chose the number 11, you would answer that 2+2+7 = 11.
Lucas now wants to trick you by choosing a number X such that there will be no valid answer. For example, if S={2,1,2,7}, it is not possible to select elements of S that sum up to 6.
You are given the int[] S. Find the smallest positive integer X that cannot be obtained as the sum of some (possibly all) elements of S.
Constraints: - S will contain between 1 and 20 elements, inclusive. - Each element of S will be between 1 and 100,000, inclusive.
But in the editorial solution it has been written:
How about finding the smallest impossible sum? Well, we can try the following naive algorithm: First try with x = 1, if this is not a valid sum (found using the methods in the previous section), then we can return x, else we increment x and try again, and again until we find the smallest number that is not a valid sum.
Let's find an upper bound for the number of iterations, the number of values of x we will need to try before we find a result. First of all, the maximum sum possible in this problem is 100000 * 20 (All numbers are the maximum 100000), this means that 100000 * 20 + 1 will not be an impossible value. We can be certain to need at most 2000001 steps.
How good is this upper bound? If we had 100000 in each of the 20 numbers, 1 wouldn't be a possible sum. So we actually need one iteration in that case. If we want 1 to be a possible sum, we should have 1 in the initial elements. Then we need a 2 (Else we would only need 2 iterations), then a 4 (3 can be found by adding 1+2), then 8 (Numbers from 5 to 7 can be found by adding some of the first 3 powers of two), then 16, 32, .... It turns out that with the powers of 2, we can easily make inputs that require many iterations. With the first 17 powers of two, we can cover up to the first 262143 integer numbers. That should be a good estimation for the largest number. (We cannot use 2^18 in the input, smaller than 100000).
Up to 262143 times, we need to query if a number x is in the set of possible sums. We can just use a boolean array here. It appears that even O(log(n)) data structures should be fast enough, however.
I did understand the first paragraph. But after that they have explained something about "How good is this upper bound?...". I couldnt understand that paragraph. How did they deduce to the fact that we need to query 262143 times if a number x is in the set of possible sums?
I am a newbie at dynamic programming and so it would be great if somebody could explain this to me.
Thank you.
The idea is as follows:
If the input sequence contains the first k powers of two: 2^0, 2^1, ... 2^(k-1), then the sum can be any integer between 0 and (2^k) - 1. Since the greatest power of two that can appear in the sequence is 2^17, the greatest sum that you can build from 18 numbers is 2^18 - 1=262,143. If a power of two would be missing, there would be a smaller sum that was not possible to achieve.
However, the statement is missing that there may be 2 more numbers in the sequence (at most 20). From these two numbers, you can repeat the same process. Hence, the maximum number to check is actually (2^18) - 1 + (2^2) - 1.
You may wonder why we use powers of two and not any other powers. The reason is the binary selection that we perform on the numbers in the input sequence. Either we add a number to the sum or we don't. So, if we represent this selection for number ni as a selection variable si (either 0 or 1), then the possible sum is:
s = s0 * n0 + s1 * n1 + s2 * n2 + ...
Now, if we choose the ni to be powers of two ni = 2^i, then:
s = s0 * 2^0 + s1 * 2^1 + s2 * 2^2 + ...
= sum si * 2^i
This is equivalent to the binary representations of numbers (see Positional Notation). By definition, different choices for the selection variables will produce different sums. Hence, the number of possible sums is maximal by choosing powers of two in the input sequence.

Fastest way to find out a number with most divisors

Given a number n how fast can one find the smallest number with most factors and is less than n?
PS:other than the naive approach of finding number of divisors for all numbers upto n.
UPDATE : My observation:
int solve(int primes[],int s,int n)
{
int i=0;
while(s<n)
{
s*=primes[i];
i++;
}
if(s>n)
s/=primes[i-1];
return s;
}
int main()
{
int primes[] = {2,3,5,7,11,13,17,19,23,29,31,37};
int n;
scanf("%d",&n);
int s=1;
while(s*2<n)//checking the possibility of existence of any prime such that s*p<n
{
s=solve(primes,s,n);
}
printf("%d\n",s);
}
The output for this for 100000 is 60060. Is this observation true? Because I don't have any concrete proof of this approach.
What I observed is that suppose take a prime array {2,3,5,7,11} and suppose that the given n is 100. Then observe that keep multiplying distinct primes until that point that you get it >100. That is 2*3*5.Repeat multiplying primes from the array from the first element again.That is 2*3*5*2. This is the number required 60 with 12 factors.Now there is no prime that can be multiplied without exceeding 100. Is this observation true? If its true then with primes upto 37 we can deal with n<=10000000 easily.All the numbers below 100 with most factors are 60, 72, 84, 90 and 96. We get the smallest of these numbers with this approach. All have 12 factors. No number below 100 has more than 12 factors.
I think this problem can be solved by algorithm similar to Hamming Number, indeed your original concept is very similar to Hamming Number as well.
Hamming Number is a problem to generate number x, where x = 2^i * 3*j * 5*k, from small to large in O(N) where N is the number of hamming number to be generated.
Here, I think similar concept can be used but we have to use the set of prime which is below your upper bound instead of {2,3,5}, we just need to also count the maximum # of prime factors when generating the number, and output it after the number generated is larger than N.
For example, here is the list of hamming number(using {2,3,5} for demo purpose) < 100:
1 2 3 4 5 6 8 9 10 12 15 16 18 20 24 25 27 30 32 36 40 45 48 50 54 60 64 72 75 80 81 90 96 100
60 = 2^2 * 3^1 * 5^1, total factors = 3*2*2 = 12 or
96 = 2^5 * 3^1, total factors = 6*2 = 12
So there may be multiple answer but you should be able to capture them while generating hamming number.
One can show that it is logically correct because
The numbers are generated by prime numbers (prime factors)
The numbers are generated in order
Note that in your case, basically you are generating all positive numbers from 1 to your upper bound.
Here is a site with tons of example in different language implementing this algorithm to generate hamming numbers: https://rosettacode.org/wiki/Hamming_numbers
Adapting Sieve of Eratosthenes it is doable in O(n^2) time.
Start with an array of size n i.e divisors.
For each number k less than n increment divisors[k] and all other indexes that are k*i < n
Find index of the larger value in divisors

Resources