i want to to calculate minimum sum in given two dimensional array
#include<iostream>
#include<limits.h>
using namespace std;
#define R 3
#define C 3
int Min(int x,int y,int z){
if(x<y){
return (x<z)?x:z;
}
else
return (y<z)?y:z;
}
int mincost(int cost[R][C],int m,int n){
int i,j;
int t[R][C];
t[0][0]=cost[0][0];
for(i=1;i<=m;i++)
t[i][0]=t[i-1][0]+cost[i][0];
for(j=1;j<=n;j++)
t[0][j]=t[0][j-1]+cost[0][j];
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
t[i][j]=Min(t[i-1][j-1],t[i-1][j],t[i][j-1]+cost[i][j]);
}
}
return t[m][n];
}
int main(){
int cost[R][C]={{1,2,3},
{4,8,2},
{1,5,3}};
cout<<mincost(cost,2,2)<<endl;
return 0;
}
from starting point (0,0) to some point (m,n) for this array it equals 8,but output shows me 1,why?what is wrong with this code?
algorithm in words
Given a cost matrix cost[][] and a position (m, n) in cost[][], write a function that returns cost of minimum cost path to reach (m, n) from (0, 0). Each cell of the matrix represents a cost to traverse through that cell. Total cost of a path to reach (m, n) is sum of all the costs on that path (including both source and destination). You can only traverse down, right and diagonally lower cells from a given cell, i.e., from a given cell (i, j), cells (i+1, j), (i, j+1) and (i+1, j+1) can be traversed. You may assume that all costs are positive integers.
I see that this is a dynamic programming solution.
you have a typo here:
t[i][j]=Min(t[i-1][j-1],t[i-1][j],t[i][j-1]+cost[i][j]);
it should be:
t[i][j]=Min(t[i-1][j-1],t[i-1][j],t[i][j-1]) + cost[i][j];
basically it worked like t[i][j] = t[i-1][j-1].
Note: A good way to debug these problems is to print the intermediate matrix (here: t).
Given that t[0][0] = cost[0][0] = 1
then
for(i=1;i<=m;i++){
for(j=1;j<=n;j++){
t[i][j]=Min(t[i-1][j-1],t[i-1][j],t[i][j-1]+cost[i][j]);
}
for i=1, j=1
t[1][1] = Min(t[0][0], t[0][1], t[1][0]+cost[1][1]) = Min(1, ...) = 1
for i=2 j=2
t[2][2] = Min(t[1][1], t[1][2], t[2][1]+cost[2][2]) = Min(1, ...) = 1
Min(t[i-1][j-1],t[i-1][j],t[i][j-1]+cost[i][j])
should probably be
Min(t[i-1][j-1],t[i-1][j],t[i][j-1]) +cost[i][j]
Just guessing, it's hard to read your intent, but looks like a pathfinding algorithm. Your code wasn't adding the cost properly to diagonal or horizontal movement, and since the cost of the beginning was one, that was also your result. This should return a cost of eleven for your sample.
Related
I want to solve a problem that gives the (integral) coordinates of n points (n<=10^5)
and asks q queries (q<=10^4). In each query it gives the (integral) coordinates of two other points and we need to answer how many of the n points are located within the rectangle created by those two points.
(edit) Also the coordinates are huge (x,y <= 10^9) (/edit)
I created a quad tree and then used this function to get the answer, however i get time limit exceeded (time limit = 2s). Is this approach too slow or have I done something wrong?
int sum(int left, int right, int down, int up, int i=1, int begx=0, int endx=1e9, int begy=0, int endy=1e9)
{
if (!i || left>right || down>up) return 0;
if (left==begx && right==endx && down==begy && up==endy) return num[i];
int midx = (begx+endx)/2, midy = (begy+endy)/2;
return sum(left,min(midx,right),down,min(midy,up),child[i][0],begx,midx,begy,midy)
+ sum(left,min(midx,right),max(midy+1,down),up,child[i][1],begx,midx,midy+1,endy)
+ sum(max(midx+1,left),right,down,min(midy,up),child[i][2],midx+1,endx,begy,midy)
+ sum(max(midx+1,left),right,max(midy+1,down),up,child[i][3],midx+1,endx,midy+1,endy);
}
If I comment this function out (and don't answer the queries, just add the points to the quad tree) I get an execution time of about 0.2 secs.
Array num stores the sum of a node and child stores the index of the four children of each node. Node 0 is dummy. The partitioning of a rectangle in children looks like this:
___
|1 3|
|0 2|
---
I'm trying to solve the following problem:
A rectangular paper sheet of M*N is to be cut down into squares such that:
The paper is cut along a line that is parallel to one of the sides of the paper.
The paper is cut such that the resultant dimensions are always integers.
The process stops when the paper can't be cut any further.
What is the minimum number of paper pieces cut such that all are squares?
Limits: 1 <= N <= 100 and 1 <= M <= 100.
Example: Let N=1 and M=2, then answer is 2 as the minimum number of squares that can be cut is 2 (the paper is cut horizontally along the smaller side in the middle).
My code:
cin >> n >> m;
int N = min(n,m);
int M = max(n,m);
int ans = 0;
while (N != M) {
ans++;
int x = M - N;
int y = N;
M = max(x, y);
N = min(x, y);
}
if (N == M && M != 0)
ans++;
But I am not getting what's wrong with this approach as it's giving me a wrong answer.
I think both the DP and greedy solutions are not optimal. Here is the counterexample for the DP solution:
Consider the rectangle of size 13 X 11. DP solution gives 8 as the answer. But the optimal solution has only 6 squares.
This thread has many counter examples: https://mathoverflow.net/questions/116382/tiling-a-rectangle-with-the-smallest-number-of-squares
Also, have a look at this for correct solution: http://int-e.eu/~bf3/squares/
I'd write this as a dynamic (recursive) program.
Write a function which tries to split the rectangle at some position. Call the function recursively for both parts. Try all possible splits and take the one with the minimum result.
The base case would be when both sides are equal, i.e. the input is already a square, in which case the result is 1.
function min_squares(m, n):
// base case:
if m == n: return 1
// minimum number of squares if you split vertically:
min_ver := min { min_squares(m, i) + min_squares(m, n-i) | i ∈ [1, n/2] }
// minimum number of squares if you split horizontally:
min_hor := min { min_squares(i, n) + min_squares(m-i, n) | i ∈ [1, m/2] }
return min { min_hor, min_ver }
To improve performance, you can cache the recursive results:
function min_squares(m, n):
// base case:
if m == n: return 1
// check if we already cached this
if cache contains (m, n):
return cache(m, n)
// minimum number of squares if you split vertically:
min_ver := min { min_squares(m, i) + min_squares(m, n-i) | i ∈ [1, n/2] }
// minimum number of squares if you split horizontally:
min_hor := min { min_squares(i, n) + min_squares(m-i, n) | i ∈ [1, m/2] }
// put in cache and return
result := min { min_hor, min_ver }
cache(m, n) := result
return result
In a concrete C++ implementation, you could use int cache[100][100] for the cache data structure since your input size is limited. Put it as a static local variable, so it will automatically be initialized with zeroes. Then interpret 0 as "not cached" (as it can't be the result of any inputs).
Possible C++ implementation: http://ideone.com/HbiFOH
The greedy algorithm is not optimal. On a 6x5 rectangle, it uses a 5x5 square and 5 1x1 squares. The optimal solution uses 2 3x3 squares and 3 2x2 squares.
To get an optimal solution, use dynamic programming. The brute-force recursive solution tries all possible horizontal and vertical first cuts, recursively cutting the two pieces optimally. By caching (memoizing) the value of the function for each input, we get a polynomial-time dynamic program (O(m n max(m, n))).
This problem can be solved using dynamic programming.
Assuming we have a rectangle with width is N and height is M.
if (N == M), so it is a square and nothing need to be done.
Otherwise, we can divide the rectangle into two other smaller one (N - x, M) and (x,M), so it can be solved recursively.
Similarly, we can also divide it into (N , M - x) and (N, x)
Pseudo code:
int[][]dp;
boolean[][]check;
int cutNeeded(int n, int m)
if(n == m)
return 1;
if(check[n][m])
return dp[n][m];
check[n][m] = true;
int result = n*m;
for(int i = 1; i <= n/2; i++)
int tmp = cutNeeded(n - i, m) + cutNeeded(i,m);
result = min(tmp, result);
for(int i = 1; i <= m/2; i++)
int tmp = cutNeeded(n , m - i) + cutNeeded(n,i);
result = min(tmp, result);
return dp[n][m] = result;
Here is a greedy impl. As #David mentioned it is not optimal and is completely wrong some cases so dynamic approach is the best (with caching).
def greedy(m, n):
if m == n:
return 1
if m < n:
m, n = n, m
cuts = 0
while n:
cuts += m/n
m, n = n, m % n
return cuts
print greedy(2, 7)
Here is DP attempt in python
import sys
def cache(f):
db = {}
def wrap(*args):
key = str(args)
if key not in db:
db[key] = f(*args)
return db[key]
return wrap
#cache
def squares(m, n):
if m == n:
return 1
xcuts = sys.maxint
ycuts = sys.maxint
x, y = 1, 1
while x * 2 <= n:
xcuts = min(xcuts, squares(m, x) + squares(m, n - x))
x += 1
while y * 2 <= m:
ycuts = min(ycuts, squares(y, n) + squares(m - y, n))
y += 1
return min(xcuts, ycuts)
This is essentially classic integer or 0-1 knapsack problem that can be solved using greedy or dynamic programming approach. You may refer to: Solving the Integer Knapsack
I'm starting to learn how to implement divide and conquer algorithms, but I'm having some serious trouble with this exercise.
I have written an algorithm which finds the minimum value in a given vector using the divide and conquer method:
int minimum (int v[], int inf, int sup)
{
int med, m1, m2;
if (inf == sup)
return v[inf];
med = (inf+sup)/2;
m1 = minimum (v, inf, med);
m2 = minimum (v, med+1, sup);
if (m1 < m2)
return m1;
else
return m2;
}
And it works. Now, I have to do the same exercise on a matrix, but I'm getting lost. Specifically, I have been told to do the following:
Let n = 2^k. Consider a nxn square matrix. Calculate its minimum value using a recursive function
double (minmatrix(Matrix M))
return minmatrix2(M, 0, 0, M.row);
(the Matrix type is given, and as you can imagine M.row gives the number of rows and columns of the matrix). Use an auxiliary function
double minmatrix2(Matrix M, int i, int j, int m)
This has to be done use a recursive divide and conquer algorithm.
So.. I can't figure out a way of doing it. I have been given the suggestion of splitting the matrix in 4 parts each time (from (i,j) to (i+m/2, j+m/2), from (i+m/2,j) to (i+m,j+m/2), from (i,j+m/2) to (i+m/2,j+m), from (i+m/2,j+m/2) to (i+m,j+m)) and try to implement a code working in a similar way to the one I have written for the array.. but I just seem to be unable to do it. Any suggestions? Even if you don't want to post a complete answer, just give me some indications. I really want to understand this.
EDIT: All right, I've done this. I'm posting the code I have used just in case someone else has the same doubt.
double minmatrix2(Matrix M, int i, int j, int m)
{
int a1, a2, a3, a4;
if (m == 1)
return M[i][j];
else
a1 = minmatrix2(M, i, j, m/2);
a2 = minmatrix2(M, i+(m/2), j, m/2);
a3 = minmatrix2(M, i, j+(m/2), m/2);
a4 = minmatrix2(M, i+(m/2), j+(m/2), m/2);
if (min (a1, a2) < min (a3, a4))
return min (a1, a2);
else
return min (a3, a4);
}
(function min defined elsewhere)
Consider that a 2D matrix in C or C++ is often implemented as accessor functions on top of a 1D array. You already know how to do this for a 1D array, so the only difference is how you address the cells. If you do this, your performance will intrinsically be optimal because you will address neighboring cells together.
Alternatively, consider that a 2D matrix has two dimensions N and M. Just break it in half along the larger dimension repeatedly until the larger dimension is less than X, some reasonable value to stop and do the actual computation sequentially. This is not entirely optimal because you will have to "skip" over parts of the matrix as you address memory.
A final idea is to divide by the major dimension first, then the minor one. In C this means divide by rows until you have single rows, then run your 1D array algorithm on each row. This produces roughly optimal performance.
I came across this problem.
which asks to calculate the number of ways a lock pattern of a specific length can be made in 4x3 grid and follows the rules. there may be some of the points must not be included in the path
A valid pattern has the following properties:
A pattern can be represented using the sequence of points which it's touching for the first time (in the same order of drawing the pattern), a pattern going from (1,1) to (2,2) is not the same as a pattern going from (2,2) to (1,1).
For every two consecutive points A and B in the pattern representation, if the line segment connecting A and B passes through some other points, these points must be in the sequence also and comes before A and B, otherwise the pattern will be invalid. For example a pattern representation which starts with (3,1) then (1,3) is invalid because the segment passes through (2,2) which didn't appear in the pattern representation before (3,1), and the correct representation for this pattern is (3,1) (2,2) (1,3). But the pattern (2,2) (3,2) (3,1) (1,3) is valid because (2,2) appeared before (3,1).
In the pattern representation we don't mention the same point more than once, even if the pattern will touch this point again through another valid segment, and each segment in the pattern must be going from a point to another point which the pattern didn't touch before and it might go through some points which already appeared in the pattern.
The length of a pattern is the sum of the Manhattan distances between every two consecutive points in the pattern representation. The Manhattan distance between two points (X1, Y1) and (X2, Y2) is |X1 - X2| + |Y1 - Y2| (where |X| means the absolute value of X).
A pattern must touch at least two points
my approach was a brute force, loop over the points, start at the point and using recursive decremente the length until reach a length zero then add 1 to the number of combinations.
Is there a way to calculate it in mathematical equation or there is a better algorithm for this ?
UPDATE:
here is what I have done, it gives some wrong answers ! I think the problem is in isOk function !
notAllowed is a global bit mask of the not allowed points.
bool isOk(int i, int j, int di,int dj, ll visited){
int mini = (i<di)?i:di;
int minj = (j<dj)?j:dj;
if(abs(i-di) == 2 && abs(j-dj) == 2 && !getbit(visited, mini+1, minj+1) )
return false;
if(di == i && abs(j - dj) == 2 && !getbit(visited, i,minj+1) )
return false;
if(di == i && abs(j-dj) == 3 && (!getbit(visited, i,1) || !getbit(visited, i,2)) )
return false;
if(dj == j && abs(i - di) == 2 && !getbit(visited, 1,j) )
return false;
return true;
}
int f(int i, int j, ll visited, int l){
if(l > L) return 0;
short& res = dp[i][j][visited][l];
if(res != -1) return res;
res = 0;
if(l == L) return ++res;
for(int di=0 ; di<gN ; ++di){
for(int dj=0 ; dj<gM ; ++dj){
if( getbit(notAllowed, di, dj) || getbit(visited, di, dj) || !isOk(i,j, di,dj, visited) )
continue;
res += f(di, dj, setbit(visited, di, dj), l+dist(i,j , di,dj));
}
}
return res;
}
My answer to another question can be adapted to this problem as well.
Let f(i,j,visited,k) the number of ways to complete a partial pattern, when we are currently at node (i,j), have already visited the vertices in the set visited and have so far walked a path length of k. We can represent visited as a bitmask.
We can compute f(i,j,visited,k) recursively by trying all possible next moves and apply DP to reuse subproblem solutions:
f(i,j, visited, L) = 1
f(i,j, visited, k) = 0 if k > L
f(i,j, visited, k) = sum(possible moves (i', j'): f(i', j', visited UNION {(i',j')}, k + dis((i,j), (i',j')))
Possible moves are those that cross a number of visited vertices and then end in an univisited (and not forbidden) one.
If D is the set of forbidden vertices, the answer to the question is
sum((i,j) not in D: f(i,j, {(i,j)}, L)).
The runtime is something like O(X^2 * Y^2 * 2^(X*Y) * maximum possible length). I guess the maximum possible length is in fact well below 1000.
UPDATE: I implemented this solution and it got accepted. I enumerated the possible moves in the following way: Assume we are at point (i,j) and have already visited the set of vertices visited. Enumerate all distinct coprime pairs (dx,dy) 0 <= dx < X and 0 <= dy < Y. Then find the smallest k with P_k = (i + kdx, j + kdy) still being a valid grid point and P_k not in visited. If P_k is not forbidden, it is a valid move.
The maximum possible path length is 39.
I'm using a DP array of size 3 * 4 * 2^12 * 40 to store the subproblem results.
There are a couple of attributes of the combinations that may be used to optimize the brute force method:
Using mirror images (horizontal, vertical, or both) you can generate 4 combinations for each one found (except horizontal or vertical lines). Maybe you could consider only combinations starting in one quadrant.
You can usually generate additional combinations of the same length by translation (moving a combination).
The problem states that we have a set of points with their coordinates and that we have to find the shortest path always beginning at (0,0) reaching a destination and going back again to (0,0) passing all inbetween points only once.
The input looks like this
on the first line are the number of inbetween points, on the second the coordinates of the destination and then the coordinates of all inbetween points. No inbetween points have the same x coordinate and the x coordinate of each inbetween point is less than that of the destination.
5
6 5
1 1
2 3
3 2
4 4
5 3
I have an implementation of the problem in the programming language C++ but the problem is I can't understand it. I've gone through it step by step but I can't understand what it does.
#include <fstream>
#include <cmath>
#include <algorithm>
#include <limits>
using namespace std;
const double inf = numeric_limits<double>::max(); // an infinite number
double dist [205][205] = {0};
double res [205][205] = {0};
int N (0);
struct point {
double x,y;
point(int a,int b):x(a),y(b){}
point(){}
}points[205]; //struct to store inbetween points
inline const bool operator < ( const point &a, const point &b ){
return a.x < b.x;
}
int main()
{
ifstream in ("evripos.in");
ofstream out ("evripos.out");
in>>N;
N+=2;
int t1,t2;
points[0]= point(0,0);
// stores all points
for(int i=1;i<N;++i){
in>>t1>>t2;
points[i]=point(t1,t2);
}
in.close();
sort(points,points+N); // sorts all points according to their x coordinate
// creates a 2 dimensional array of the distances between all points
// called dist
for(int i=0;i<N;++i)
for(int j=0;j<N;++j){
dist [i][j]= sqrt( pow(points[i].x-points[j].x,2) + pow(points[i].y-points[j].y,2));;
res[i][j]=inf;
}
// computes the result, using a 2 dimensional array called res
res[0][0]=0;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j){
res[i+1][i] = min (res[i+1][i], res[i][j] + dist[j][i+1]);
res[i+1][j] = min (res[i+1][j], res[i][j] + dist[i][i+1]);
res[i+1][i+1] = min (res[i+1][i+1], res[i][j] + dist[i][i+1] + dist[i+1][j]);
}
out<<round(res[N-1][N-1])<<endl; //stores the end result
out.close();
}
I've found out that it is a dynamic programming problem and as I understand it the whole logic is in here
res[0][0]=0;
for(int i=0;i<N;++i)
for(int j=0;j<N;++j){
res[i+1][i] = min (res[i+1][i], res[i][j] + dist[j][i+1]);
res[i+1][j] = min (res[i+1][j], res[i][j] + dist[i][i+1]);
res[i+1][i+1]= min (res[i+1][i+1], res[i][j] + dist[i][i+1] + dist[i+1][j]);
}
What exactly is the logic behind this? How is this problem solved with dynamic programming?
This is Bitonic tour problem. You have a list of cities, from 0 to N-1, you need to start from city 0, go through each cities once to reach N-1 and from N-1 go back to 0.
In order to solve the problem, we need to change the way we look at it. Imagine there is not one, but two people starting from city 0, each of them will never be at same city (except 0 and N-1) and they all try to reach city N-1. So if we add the path taken by Person one and Person two, we have the answer for the original problem.
So, we have our int [][]res, with res[i][j] means the minimum total distance for Person one is at city i and Person two is at city j. We observe that this line
res[i+1][i] = min (res[i+1][i], res[i][j] + dist[j][i+1]);
means the Person two starting from city j will go to city i + 1. Notice that i + 1 , not i, which will avoid the case when two persons being at same city. (Also notice that the role of i and j can be interchangeable)
Similarly
res[i+1][j] = min (res[i+1][j], res[i][j] + dist[i][i+1]);
means Person one starting from i go to city i + 1.
Finally, assume that the destination is at i + 1, we have
res[i+1][i+1]= min (res[i+1][i+1], res[i][j] + dist[i][i+1] + dist[i+1][j]);
Note: By the way we increase the index from i to i + 1 in the outer for loop, we also guarantee that all city from 0 to i had been reached (by either Person one or two) before city i + 1 has been reached.
So, the answer for the problem will be at res[N-1][N-1]
Hope that's help!