An SPOJ question:
Given two arrays, A and B, of positive numbers between 1 and 1,000,000. I have to pair each integer a in A with an integer b in B such that the sum of absolute values of differences is minimized. A and B can contain a maximum of 5000 integers each.
For example:
Let A=[10, 15, 13] and B=[14,13, 12], then the best pairing is (10, 12), (15, 14) and (13, 13) because |10-12|+|15-14|+|13-13|=3, which is the least we can achieve. Thus, the minimum sum achieved is 3.
I believe it is a dynamic programming question.
Edit:
The arrays may be of different sizes but can contain a maximum of 5000 elements each.
My code:
#include <cmath>
#include <vector>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
static int DP[5002][5002], N, M, tmp;
vector<int> B, C;
int main()
{
scanf("%d %d", &N, &M); memset(DP, -1, sizeof DP);
B.push_back(0); C.push_back(0); DP[0][0]=0;
for(int i=1; i<=N; ++i){scanf("%d", &tmp); B.push_back(tmp);} \\inputting numbers.
for(int i=1; i<=M; ++i){scanf("%d", &tmp); C.push_back(tmp);}
sort(B.begin(), B.end()); sort(C.begin(), C.end()); \\Sorting the two arrays.
if(C.size()<=B.size()){ \\Deciding whether two swap the order of arrays.
for(int i=1; i<=N; ++i){
for(int j=1; j<=M; ++j){
if(j>i)break;
if(j==1)DP[i][j]=abs(C[j]-B[i]);
else{
tmp=DP[i-1][j-1]+abs(C[j]-B[i]);
DP[i][j]=(DP[i-1][j]!=-1)? min(tmp, DP[i-1][j]): tmp;
}
}
}
printf("%d\n", DP[N][M]); \\Outputting the final result.
}
else{
for(int i=1; i<=M; ++i){
for(int j=1; j<=N; ++j){
if(j>i) break;
if(j==1)DP[i][j]=abs(C[i]-B[j]);
else{
tmp=DP[i-1][j-1]+abs(C[i]-B[j]);
DP[i][j]=(DP[i-1][j]!=-1)? min(tmp, DP[i-1][j]): tmp;
}
}
}
printf("%d\n", DP[M][N]);
}
return 0;
}
Niels's comment elucidates that, if the arrays are of the same size, then you should sort them and pair the values. We can build on that to construct the general case:
I'll assume the length of the first array arr1 is smaller than or equal to the length of the second arr2. If it isn't, just swap them. First, sort both arrays, and let dp[A][B] be the smallest difference when you consider only the subarrays arr1[A...] and arr2[B...] (that is, arr1 from A forward and arr2 from B to the end). You have two choices:
Pair A and B. In this case you'd get a total difference of |arr1[A]-arr2[B]| + dp[A+1][B+1].
Don't use B. Note that in this case you'll never consider B again (because if you pair A and B to different elements, then you could swap both pairs and the sum would go down). So you can simply ignore B and your answer will be dp[A][B+1].
Base cases should be fairly obvious:
dp[length of arr1][length of arr2] = 0
dp[A][length of arr2] = infinity (it's impossible to pair the remaining elements of arr1).
Related
I have to make a program that sorts 15 numbers from greatest to least, and then list the top five. Ive gotten some of it done. can someone help me on how to list the top five numbers?
#include <iostream>
using namespace std;
#define MAX 100
int main()
{
int arr[MAX];
int n,i,j;
int temp;
cout<<"Enter how many numbers to read: ";
cin>>n;
for(i=0;i<n;i++)
{
cout<<"Enter "<<i+1<<" number ";
cin>>arr[i];
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(arr[i]<arr[j])
{
temp =arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
cout<<"largest to smallest:"<<endl;
for(i=0;i<n;i++)
cout<<arr[i]<<"\t";
cout<<endl;
cout <<"the top five numbers are:"<< endl;
return 0;
}
Well you have already sorted it in descending order.
So to get the top 5, you just have to print the first 5 numbers in your array.
for (i=0; i<5; i++) cout << arr[i] << endl;
If you only need to have the top 5 elements, it is not necessary to sort the whole array. You can do a std::partial_sort to just have top 5 elements.
std::partial_sort(
std::begin(arr),
std::begin(arr) + 5,
std::end(arr),
[](int x, int y) { return x > y; });
In Hackerearth i tried solving bubble sort swap counting. and my output always different from correct output.for example;
my output is 2475 and correct output is 2788
#include <iostream>
using namespace std;
int main()
{
int *A,tm,times=0;
cin >> tm;
A = new int[tm];
for(int i = 0; i<tm;i++) {cin >> A[i];}
int temp;
for(int i = 0; i<tm;i++){
for(int j = 0; j < tm-i-1;j++){
if(A[j] > A[j+1]){
times++;;
temp = A[j];
A[j] = A[j+1];
A[j] = temp;
}
}
}
cout << times;
return 0;
}
Am i doing something wrong or correct outputs are wrong?
In the swap logic, in place of
A[j]=temp;
write
A[j+1]=temp;
In the outer for loop, i<tm-1 instead of i<tm
May be this is irrelevant, but it is possible to find the number of inversion with a better complexity. This solution will require O(n^2). It can be done in O(nlogn) time complexity. The idea is to use merge sort and at merging state you already know how many values are greater/smaller from a value without actually counting them. While merging, if a value of right subarray is greater, then all other values right of it are also greater. You just need to count how many values are at right. A detailed and pleasant explanation is provided here.
Number of swaps performed by Bubble-Sort on a given array
http://www.geeksforgeeks.org/counting-inversions/
In an array except three numbers all numbers occur odd number of times. How to find all three numbers occurring even number of times in an array?
I can get till a point where I have xor of all three even occurring numbers. How to get the three numbers from that xor value? My approach till now:
#include <iostream>
#include <set>
using namespace std;
int main() {
// Find the 3 numbers occuring even times in an array
int arr[] = {1,6,2,88,34,4,98,25,61,7,2,78,2,78,8,25,9,34,56,331};
int a = arr[0];
for (int i=1;i<20;i++)
a ^= arr[i];
set<int> myset;
myset.insert(arr,arr+20);
set<int>::iterator it;
for (it=myset.begin(); it!=myset.end(); ++it)
a ^= *it;
cout<<a<<endl; // a stores xor of the three numbers occuring even number of times, i.e., (25^78^34)=117
return 0;
}
Note: Hashtable and sorting should not be used. The solution should be in O(n) time.
The solution of your problem is as
`
#include <iostream>
#include <set>
using namespace std;
int main() {
// Find the 3 numbers occuring even times in an array
int arr[] = {1,6,2,88,34,4,98,25,61,7,2,78,2,78,8,25,9,34,56,331};
set<int> myset;
set<int> myset_final;
for (int i=1;i<20;i++)
{
if(myset.exists(a[i]))
myset.remove(a[i]);
else myset.insert(a[i]);
}
for(int i=0;i<i<20;i++)
{
if(!myset.exists(a[i]))
myset_final.insert(a[i]);
}
//Now the myset_final contains the numbers that are occured even number of times.
return 0;
}
`
This is the best solution according to me but not the O(n) it O(nlog(n)).
I found this solution which does the job in O(n) time and O(1) space but the only thing is the numbers of the array can be in range [0,63].
Halo I just write code to perform Matrix chain multiplication, which can be solved by Dynamic Programming
http://en.wikipedia.org/wiki/Matrix_chain_multiplication#A_Dynamic_Programming_Algorithm
Here is the code I wrote, which I think is simpler than the one provided by wikipedia. So I doubt am i doing dynamic programming or not?
and I can't figure out the time complexity of my program. Can someone help me to figure the time complexity of this program?
Here's my guess..
the for loop will run n times for each call? if mem is not used..
for each loop, it will then expand into two
if mem is used, it prevent recalculation...
ahhh I can't figure it out, hope someone can help me :-)
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <climits>
using namespace std;
int mem[10][10];
int row[10];
int col[10];
int m[10];
#define NUM 4
int DP(int c, int r){
if(mem[c][r] != INT_MAX) return mem[c][r];
if(c == r) return 0;
int min_cost;
for(int j=c; j<r; j++){
min_cost = DP(c, j) + DP(j+1, r) + m[c-1]*m[j]*m[r];
if(min_cost < mem[c][r])
mem[c][r] = min_cost;
}
return mem[c][r];
}
int main(){
for(int i=0; i< 10;i++){
for(int j=0; j<10;j++){
mem[i][j] = INT_MAX;
}
}
int n = NUM; // MAX 4 matrix
int a,b;
for(int i=0; i< NUM+1; i++){
cin >> a;
m[i] = a;
}
cout << "Lowest Cost for matrix multiplicatoin " << DP(1,NUM);
}
The technique you have used is called memoization. Most of the time, you may solve DP problems using memoization with little (or no) overhead.
The complexity of your implementation is just like the original DP solution: O(n^3) (Note: Every cell of mem array should be computed at least once, and each cell takes O(n) time to be computed. Further computation of a cell, does not involve any loop, since it would be a simple lookup.)
See also http://en.wikipedia.org/wiki/Memoization
I'm a little bit confused. How is the problem of generating permutations in Lexicographic Order any different from the problem of sorting? Can someone please explain it to me with an example? Thanks
These are two different things. There are N! permutations, but there is only one sorted order (the sorted permutation is the smallest lexicographically).
Here is an example of a sorted permutation:
brown fox quick
Here is a list of permutations in lexicographic order:
brown fox quick
brown quick fox
fox brown quick
fox quick brown
quick brown fox
quick fox brown
Here is a program in C++ to generate permutations in lexicographic order:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> s;
s.push_back("quick");
s.push_back("brown");
s.push_back("fox");
sort(s.begin(), s.end());
do {
for(int i = 0 ; i != s.size() ; i++) {
cout << s[i] << " ";
}
cout << endl;
} while (next_permutation(s.begin(), s.end()));
return 0;
}
Permutations are not addressed in the problem of sorting.
One way that they could relate is if you generate Permutations that are not in lexicographic order then you sort to get it in lexicographical order. This however would require to have factorial space. Generation usually spits out one element at a time therefore not having to have all elements in memory.
There's a fairly easy way to generate the nth permutation in lexicographic order. The set of choices you make in selecting the permutation elements are: pick 1 of N, then 1 of N-1, then 1 of N-2, ... then 1 of 2, and finally there's just one left. Those choices, as index values into a running "what's left" list, can be looked at as a variable-base number.
You can develop the digits from right to left as d[1] = n%2, d[2] = (n/2)%3, d[3] = (n/6)%4, ... d[k] = (n/k!) % (k+1). The result has d[N-1]==0 for the first (N-1)! permutations, d[N-1]==1 for the next (N-1)!, and so on. You can see that these index values will be in lex. order. Then choose the symbols out of your sorted set (Any random-access collection will do if syms[0], syms[1], ... are in the order you want.)
Here's some code I whipped up for working on Project Euler problems. It just generates the index values, and allows for choosing permutations of k symbols out of n. The header file defaults k to -1, and the argument check code converts this to n and generates full length permutations. There's also a change of notation here: "index" is the number of the permutation ("n" above) and "n" is the set size ("N" above).
vector<int> pe_permutation::getperm(long long index, int n, int k)
{
if (n<0) throw invalid_argument("permutation order (n)");
if (k<0 || k>n)
{
if (k==-1)
k=n;
else throw invalid_argument("permutation size (k)");
}
vector<int> sset(n, 0); // generate initial selection set {0..n-1}
for (int i=1; i<n; ++i)
sset[i] = i;
// Initialize result to sset index values. These are "without replacement"
// index values into a vector that decreases in size as each result value
// is chosen.
vector<int> result(k,0);
long long r = index;
for (int m=n-k+1; m<=n; ++m)
{
result[n-m] = (int)(r % m);
r = (r / m);
}
// Choose values from selection set:
for (int i=0; i<k; ++i)
{
int j = result[i];
result[i] = sset[j];
sset.erase(sset.begin()+j);
}
return result;
} // getperm(long long, int, int)
import java.util.*;
public class Un{
public static void main(String args[]){
int[]x={1,2,3,4};
int b=0;int k=3;
while(b!=(1*2*3*4)){
int count=0;
while(count!=6){
for(int i=2;i>0;i--){
int temp=x[i];
x[i]=x[3];
x[3]=temp;
count++;
System.out.println(x[0]+""+x[1]+""+x[2]+""+x[3]);
}
}
b+=count;
int temp=x[0];
x[0]=x[k];
x[k]=temp;
k--;
}
}
}