implement DP for a recursive function - c++

I have the following recursive function:
typedef unsigned long long ull;
ull calc(ull b, ull e)
{
if (!b) return e;
if (!e) return b;
return calc(b - 1, e - 1) + calc(b - 1, e) - calc(b, e - 1);
}
I want to implement it with dynamic programming (i.e. using storage). I have tried to use a map<pair<ull, ull>, ull> but it is too slow also. I couldn't implement it using arrays O(1) too.
I want to find a solution so that this function solves quickly for large b, es.

Make a table b/e and fill it cell by cell. This is DP with space and time complexity O(MaxB*MaxE).
Space complexity may be reduced with Ante's proposal in comment - store only two needed rows or columns.
0 1 2 3 4 5
1 0 3 . . .
2 . . . . .
3 . . . . .
4 . . . . .

If a bottom up representation is what you want then this would do fine.
Fill up the table as MBo has shown
This can be done as:
for e from 0 to n:
DP[0][e] = e
for b from 0 to n:
DP[b][0] = b
for i from 1 to n:
for j from 1 to n:
DP[i][j] = DP[i-1][j-1] + DP[i-1][j] - DP[i][j-1]
now your answer for any b,e is simply DP[b][e]

You might want to take a look at this recent blog posting on general purpose automatic memoization. The author discusses various data structures, such std::map, std::unordered_map etc. Warning: uses template-heavy code.

You can implement in O(n^2) (assuming n as max number of values for b and e ) by using a 2 dimensional array. Each current value for i,j would depend on the value at i-1,j and i-1,j-1 and i,j-1. Make sure you handle cases for i=0, j=0.

Related

Removing Cyclotomic Factors from a Polynomial - Pari

I want to take some polynomial f and remove all of it's cyclotomic factors, and then look at the resulting polynomial (say g). I'm aware of polcyclofactors and the current code I have tried is:
c(f)=polcyclofactors(f)
p(f)=prod(i=1,#c(f),c(f)[i])
g(f)=f/p(f)
The issue I have is that polcyclofactors doesn't take into account multiplicity of the cyclotomic factors. For example:
f=3*x^4 + 8*x^3 + 6*x^2 - 1
g(f)
= 3*x^3 + 5*x^2 + x - 1
But
factor(f)
=
[ x + 1 3]
[3*x - 1 1]
Is there any way to be able to nicely include multiple cyclotomic factors of f to divide by? Or will I have to look at factorising f and try and removing cyclotomic factors that way?
The following two suggestions are based on repeating the divisions until no more can be done (they are both very similar).
Suggestion 1:
r(f)={my(c); while(c=polcyclofactors(f); #c, f=f/vecprod(c)); f}
Suggestion 2:
r(f)={my(g=vecprod(polcyclofactors(f))); while(poldegree(g), f=f/g; g=gcd(f,g)); f}
Another suggestion without a loop:
r(f)={my(g=vecprod(polcyclofactors(f))); numerator(f/g^(poldegree(f)))}
Now a version that is probably superior: For each factor valuation can be used to get the required power.
r(f)={f/vecprod([t^valuation(f,t) | t<-polcyclofactors(f)])}

C++ --- leading zeros in filenames (CSV-files) --- storing/splitting values of a std::vector

I want to store the values of a std::vector<T> into a bunch of csv-files.
The values shall be split in a way that N (with N < std::vector<T>.size()) values are stored in one csv-file, except the last file, it can store between 1 and N values.
Assuming std::vector<T>.size() == 113 and a N == 10 results in
00.csv
01.csv
.
.
.
12.csv (with only 3 elements)
Is there an easy way out there?
To generate the filename do sprintf(fileName, "%02d.csv", fileNumber);
See http://www.cplusplus.com/reference/cstdio/sprintf/

Not Equals Constraint in PROC OPTMODEL

I have an optimization problem that I need to solve. It's a binary linear programming problem, so all of the decision variables are equal to 0 or 1. I need certain combinations of these decision variables to add up to either 0 or 2+, they cannot sum to 1. I'm struggling with how to accomplish this in PROC OPTMODEL.
Something like this is what I need:
con sum_con: x+y+z~=1;
Unfortunately, this just throws a syntax error... Is there any way to accomplish this?
See below for a linear reformulation. However, you may not need it. In SAS 9.4m2 (SAS/OR 13.2), your expression works as written. You just need to invoke the (experimental) CLP solver:
proc optmodel;
/* In SAS/OR 13.2 you can use your code directly.
Just invoke the experimental CLP solver */
var x binary, y binary, z binary;
con sum_con: x+y+z~=1;
solve with clp / findall;
print {i in 1 .. _NSOL_} x.sol[i]
{i in 1 .. _NSOL_} y.sol[i]
{i in 1 .. _NSOL_} z.sol[i];
produces immediately:
[1] x.SOL y.SOL z.SOL
1 0 0 0
2 0 1 1
3 1 0 1
4 1 1 0
5 1 1 1
In older versions of SAS/OR, you can still call PROC CLP directly,
which is not experimental.
The syntax for your example will be very similar to PROC OPTMODEL's.
I am sure, however, that your model has other variables and constraints.
In that case, remember that no matter how you formulate this,
it is still a search space with a hole in the middle.
So it potentially can make the solver perform poorly.
How poorly is hard to predict. It depends on other features of your model.
If MILP is a better fit for the rest of your model,
you can reformulate your constraint as a valid MILP in two steps.
First, add a binary variable that is zero only when the expression is zero:
/* If solve with CLP is not available, you can linearize the disjunction: */
var IsGTZero binary; /* 1 if any variable in the expression is 1 */
con IsGTZeroBoundsExpression: 3 * IsGTZero >= x + y + z;
Then add another constraint that forces the expression to be
at least the constant you want (in this case 2) when it is nonzero.
num atLeast init 2;
con ZeroOrAtLeast: x + y + z >= atLeast * IsGTZero;
min f=0; /* Explicit objectives are unnecessary in 13.2 */
solve;
The following equation should work:
(x+y-z)*z + (y+z-x)*x + (x+z-y)*y > -1
It can be generalized to more than three variables and if you have some large number you should be able to use index expansions to make it easier.

Unexpected output for test case

Codeforces problem 158B-http://codeforces.com/problemset/problem/158/B
I am getting an unexpected output for test case 5.I think I should get 1 as output but I am it as 2.Please guide me.Judge's log:
Test: #5, time: 30 ms., memory: 380 KB, exit code: 0, checker exit code: 1, verdict: WRONG_ANSWER
Input
2
2 1
Output
2
Answer
1
Checker Log
wrong answer expected 1, found 2
My solution:
#include<iostream>
using namespace std;
int n,a[100000],i,b,c,d,e,f,g,h;
int main()
{
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
b=0;
c=0;
d=0;
e=0;
for(i=0;i<n;i++)
{
if(a[i]==1) //To check for number of 1,2,3 and 4 membered groups.
b=b+1;
if(a[i]==2)
c=c+1;
if(a[i]==3)
d=d+1;
if(a[i]==4)
e=e+1;
}
f=e;
if(d>b) //More 3 member groups than 1.
{
f=f+d; //f=f+b+(g-b) 3 and 1 member groups combine.Remaining 3 i.e. (g-b) member groups will can't combine with 2 member groups.Hence,they take separate taxies.
g=-1;
}
if(b>=d) //More 1 member groups than 3.
{
f=f+d;
g=b-d; //g=remaining 1 member groups.
}
h=(2*c)%4; //Empty seats in last taxi.Possible values can be 0,1,2,3.
if(h==0)
f=f+(c/2);
else
f=f+((c+1)/2);
if(g!=-1)
{
g=g-h; //Remaining 1 member groups after combining with remaining seats in last 2 member taxi.
if((g%4)==0)
f=f+(g/4);
else
f=f+(g/4)+1;
}
cout<<f;
}
If your input is 2 2 1, then b and c will both be 1, making f 0 and g 1 in the first set of conditionals. h will be (2 * 1) % 4 or 2, making an update to f (0 + 1 = 1). Since g is 1, g-h is -1, which will lead to you executing f=f+(g/4)+1 which is f=1 + (-1/4)+1 which is 1 + 0 + 1 = 2 in integer math.
I think you wanted to check if g-h>0 instead of g!=-1, but there are a ton of places you could simplify your code. Note that using a debugger and stepping through this would have shown you where your problems are much faster, and be much more helpful to increasing your skills, than asking SO.
Just for anyone else looking at this question, this is a fairly simple answer to the problem.
Do it by hand and see if you get the same answer. If you get the same answer by hand as the computation, your algorithm is wrong. If you don't, your code is wrong.
Print variables from intermediate computations to see if they are what you think they should be.
Make sure, if it might matter, that you reinitialize your variables (including arrays) before each use.
Other tips:
Use a switch statement instead of multiple if-equal statements.
Name your variables. It helps you keep track when looking at your code.
When you have multiple variables with similar use, consider using an array instead. b, c, d, and e all seem similar.

Solving a linear equation in one variable

What would be the most efficient algorithm to solve a linear equation in one variable given as a string input to a function? For example, for input string:
"x + 9 – 2 - 4 + x = – x + 5 – 1 + 3 – x"
The output should be 1.
I am considering using a stack and pushing each string token onto it as I encounter spaces in the string. If the input was in polish notation then it would have been easier to pop numbers off the stack to get to a result, but I am not sure what approach to take here.
It is an interview question.
Solving the linear equation is (I hope) extremely easy for you once you've worked out the coefficients a and b in the equation a * x + b = 0.
So, the difficult part of the problem is parsing the expression and "evaluating" it to find the coefficients. Your example expression is extremely simple, it uses only the operators unary -, binary -, binary +. And =, which you could handle specially.
It is not clear from the question whether the solution should also handle expressions involving binary * and /, or parentheses. I'm wondering whether the interview question is intended:
to make you write some simple code, or
to make you ask what the real scope of the problem is before you write anything.
Both are important skills :-)
It could even be that the question is intended:
to separate those with lots of experience writing parsers (who will solve it as fast as they can write/type) from those with none (who might struggle to solve it at all within a few minutes, at least without some hints).
Anyway, to allow for future more complicated requirements, there are two common approaches to parsing arithmetic expressions: recursive descent or Dijkstra's shunting-yard algorithm. You can look these up, and if you only need the simple expressions in version 1.0 then you can use a simplified form of Dijkstra's algorithm. Then once you've parsed the expression, you need to evaluate it: use values that are linear expressions in x and interpret = as an operator with lowest possible precedence that means "subtract". The result is a linear expression in x that is equal to 0.
If you don't need complicated expressions then you can evaluate that simple example pretty much directly from left-to-right once you've tokenised it[*]:
x
x + 9
// set the "we've found minus sign" bit to negate the first thing that follows
x + 7 // and clear the negative bit
x + 3
2 * x + 3
// set the "we've found the equals sign" bit to negate everything that follows
3 * x + 3
3 * x - 2
3 * x - 1
3 * x - 4
4 * x - 4
Finally, solve a * x + b = 0 as x = - b/a.
[*] example tokenisation code, in Python:
acc = None
for idx, ch in enumerate(input):
if ch in '1234567890':
if acc is None: acc = 0
acc = 10 * acc + int(ch)
continue
if acc != None:
yield acc
acc = None
if ch in '+-=x':
yield ch
elif ch == ' ':
pass
else:
raise ValueError('illegal character "%s" at %d' % (ch, idx))
Alternative example tokenisation code, also in Python, assuming there will always be spaces between tokens as in the example. This leaves token validation to the parser:
return input.split()
ok some simple psuedo code that you could use to solve this problem
function(stinrgToParse){
arrayoftokens = stringToParse.match(RegexMatching);
foreach(arrayoftokens as token)
{
//now step through the tokens and determine what they are
//and store the neccesary information.
}
//Use the above information to do the arithmetic.
//count the number of times a variable appears positive and negative
//do the arithmetic.
//add up the numbers both positive and negative.
//return the result.
}
The first thing is to parse the string, to identify the various tokens (numbers, variables and operators), so that an expression tree can be formed by giving operator proper precedences.
Regular expressions can help, but that's not the only method (grammar parsers like boost::spirit are good too, and you can even run your own: its all a "find and recourse").
The tree can then be manipulated reducing the nodes executing those operation that deals with constants and by grouping variables related operations, executing them accordingly.
This goes on recursively until you remain with a variable related node and a constant node.
At the point the solution is calculated trivially.
They are basically the same principles that leads to the production of an interpreter or a compiler.
Consider:
from operator import add, sub
def ab(expr):
a, b, op = 0, 0, add
for t in expr.split():
if t == '+': op = add
elif t == '-': op = sub
elif t == 'x': a = op(a, 1)
else : b = op(b, int(t))
return a, b
Given an expression like 1 + x - 2 - x... this converts it to a canonical form ax+b and returns a pair of coefficients (a,b).
Now, let's obtain the coefficients from both parts of the equation:
le, ri = equation.split('=')
a1, b1 = ab(le)
a2, b2 = ab(ri)
and finally solve the trivial equation a1*x + b1 = a2*x + b2:
x = (b2 - b1) / (a1 - a2)
Of course, this only solves this particular example, without operator precedence or parentheses. To support the latter you'll need a parser, presumable a recursive descent one, which would be simper to code by hand.