My logic of Minimum coins required - algorithm

I was trying to do Coin Change problem on my own.But it seem like my logic is somewhere lacking,Please help me.I have commented what was in my mind.
#include <bits/stdc++.h>
using namespace std;
vector<int>nom;
int dp[1000004];
int recurse(int v){
if(dp[v]!=-1)return dp[v]; // If already found something just return
if(v==0)return 0; // If value is 0.Minimum changes req is 0.
if(v<0)return INT_MAX; // If reached out of bound return MAX.
int ans=INT_MAX; // For storing Ans.
for(int i=0;i<nom.size();i++){
ans=min(ans,recurse(v-nom[i])+1); //Min Number of changes req fir val-nom[i]+1 for value val.
}
dp[v]=ans;
return dp[v];
}
int main() {
int v,n,x;
cin>>v>>n; // Value for which I have to find change,No. of change available
for(int i=0;i<n;i++){
cin>>x;
nom.push_back(x); // changes
dp[x]=1; // If we want x money only 1 change req so dp[x]=1
}
int mincoins=0; // For storing answer
mincoins=recurse(v); // Answer for value v.
cout<<mincoins<<endl;
}
return 0;
}

The only problem here is that you forgot to initialise all elements of dp[] to -1.

Related

why am i getting access violation error c++?

i am getting 0xc0000005 error(access violation error), where am i wrong in this code?
i couldnt debug this error. please help me.
question is this
Formally, given a wall of infinite height, initially unpainted. There occur N operations, and in ith operation, the wall is painted upto height Hi with color Ci. Suppose in jth operation (j>i) wall is painted upto height Hj with color Cj such that Hj >= Hi, the Cith color on the wall is hidden. At the end of N operations, you have to find the number of distinct colors(>=1) visible on the wall.
#include<iostream>
#include <bits/stdc++.h>
#include <algorithm>
using namespace std;
int main()
{
int t;
cin>>t;
for(int tt= 0;tt<t;tt++)
{
int h,c;
int temp = 0;
cin>>h>>c;
int A[h], B[c];
vector<int> fc;
for(int i = 0;i<h;i++)
{
cin>>A[i];
}
for(int j =0;j<h;j++)
{
cin>>B[j];
}
if(is_sorted(A,A+h))
{
return 1;
}
if(count(A,A+h,B[0]) == h)
{
return 1;
}
for(int i = 0;i<h;i++)
{
if(A[i]>=temp)
{
temp = A[i];
}
else
{
if(temp == fc[fc.size()-1])
{
fc[fc.size()-1] = B[i];
}
else
{
fc.push_back(B[i]);
}
}
}
}
}
There are several issues.
When reading values into B, your loop check is j<h. How many elements are in B?
You later look at fc[fc.size()-1]. This is Undefined Behavior if fc is empty, and is the likely source of your problem.
Other issues:
Don't use #include <bits/stdc++.h>
Avoid using namespace std;
Variable declarations like int A[h], where h is a variable, are not standard C++. Some compilers support them as an extension.

Hashing using int array or unordered_map in STL?

Which is more efficient in terms of memory and time complexity hashing using int array or unordered_map in STL?
By hashing I mean storing elements formed by the combination of a key value and a mapped value, and fast retrieval of individual elements based on their keys.
Actually I was trying to solve this question.
Here's my solution:-
#include <bits/stdc++.h>
#define MAX 15000005
using namespace std;
/*
* author: vivekcrux
*/
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
int c[MAX];
int n;
int sieve()
{
bitset<MAX> m;
m.set();
int ans = 0;
for(int i=2;i<MAX;i++)
{
if(m[i])
{
int mans = 0;
for(int j=i;j<MAX;j+=i)
{
m[j]=0;
mans += c[j];
}
if(mans<n)
ans = max(ans,mans);
}
}
return ans;
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int i,j;
cin>>n;
int a[n+1];
for(i=0;i<n;i++)
{
cin>>a[i];
}
int g = a[0];
for(i=1;i<n;i++)
{
g = gcd(g,a[i]);
}
for(i=0;i<n;i++)
{
a[i] /= g;
if(a[i]!=1) c[a[i]]++;
}
int m = sieve();
if(m==0)
cout<<"-1";
else
cout<<n - m<<endl;
return 0;
}
In this code if I use
unordered_map<int,int> c;
instead of
int c[MAX];
I get a Memory limit exceeded verdict.I have found here that unordered_map has a constant average time complexity on average, but no details about space complexity is mentioned here.I wonder why am I getting MLE with unordered_map.
unordered_map uses bucket to store values. A bucket is a slot in the container's internal hash table to which elements are assigned based on the hash value of their key. Lets see the following code in C++17.
#include <bits/stdc++.h>
using namespace std;
int main() {
unordered_map<int,int> mp;
mp[4] = 1;
mp[41] = 5;
mp[67] = 6;
cout<<mp.bucket_count();
}
The output comes out be 7 (depends on compiler). This is the number of buckets used in the above code. But if we use an array of size 67, it will obviously take more memory. Another case would be that if we would had numbers 1, 2 and 3 instead of 4, 41 and 67, the output would have been 7. Here using array was the way to go for saving space. So it depends on the keys you are storing in the hash table. For time complexity, both performs equally same. There is a collision condition in unordered_map which would blow the overall time complexity of the code. Here is the codeforces link of the blog.

Make unique array with minimal sum

It is a interview question. Given an array, e.g., [3,2,1,2,7], we want to make all elements in this array unique by incrementing duplicate elements and we require the sum of the refined array is minimal. For example the answer for [3,2,1,2,7] is [3,2,1,4,7] and its sum is 17. Any ideas?
It's not quite as simple as my earlier comment suggested, but it's not terrifically complicated.
First, sort the input array. If it matters to be able to recover the original order of the elements then record the permutation used for the sort.
Second, scan the sorted array from left to right (ie from low to high). If an element is less than or equal to the element to its left, set it to be one greater than that element.
Pseudocode
sar = sort(input_array)
for index = 2:size(sar) ! I count from 1
if sar(index)<=sar(index-1) sar(index) = sar(index-1)+1
forend
Is the sum of the result minimal ? I've convinced myself that it is through some head-scratching and trials but I haven't got a formal proof.
If you only need to find ONE of the best solution, here's the algorythm with some explainations.
The idea of this problem is to find an optimal solution, which can be found only by testing all existing solutions (well, they're infinite, let's stick with the reasonable ones).
I wrote a program in C, because I'm familiar with it, but you can port it to any language you want.
The program does this: it tries to increment one value to the max possible (I'll explain how to find it in the comments under the code sections), than if the solution is not found, decreases this value and goes on with the next one and so on.
It's an exponential algorythm, so it will be very slow on large values of duplicated data (yet, it assures you the best solution is found).
I tested this code with your example, and it worked; not sure if there's any bug left, but the code (in C) is this.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
typedef int BOOL; //just to ease meanings of values
#define TRUE 1
#define FALSE 0
Just to ease comprehension, I did some typedefs. Don't worry.
typedef struct duplicate { //used to fasten the algorythm; it uses some more memory just to assure it's ok
int value;
BOOL duplicate;
} duplicate_t;
int maxInArrayExcept(int *array, int arraySize, int index); //find the max value in array except the value at the index given
//the result is the max value in the array, not counting th index
int *findDuplicateSum(int *array, int arraySize);
BOOL findDuplicateSum_R(duplicate_t *array, int arraySize, int *tempSolution, int *solution, int *totalSum, int currentSum); //resursive function used to find solution
BOOL check(int *array, int arraySize); //checks if there's any repeated value in the solution
These are all the functions we'll need. All split up for comprehension purpose.
First, we have a struct. This struct is used to avoid checking, for every iteration, if the value on a given index was originally duplicated. We don't want to modify any value not duplicated originally.
Then, we have a couple functions: first, we need to see the worst case scenario: every value after the duplicated ones is already occupied: then we need to increment the duplicated value up to the maximum value reached + 1.
Then, there are the main Function we'll discute later about.
The check Function only checks if there's any duplicated value in a temporary solution.
int main() { //testing purpose
int i;
int testArray[] = { 3,2,1,2,7 }; //test array
int nTestArraySize = 5; //test array size
int *solutionArray; //needed if you want to use the solution later
solutionArray = findDuplicateSum(testArray, nTestArraySize);
for (i = 0; i < nTestArraySize; ++i) {
printf("%d ", solutionArray[i]);
}
return 0;
}
This is the main Function: I used it to test everything.
int * findDuplicateSum(int * array, int arraySize)
{
int *solution = malloc(sizeof(int) * arraySize);
int *tempSolution = malloc(sizeof(int) * arraySize);
duplicate_t *duplicate = calloc(arraySize, sizeof(duplicate_t));
int i, j, currentSum = 0, totalSum = INT_MAX;
for (i = 0; i < arraySize; ++i) {
tempSolution[i] = solution[i] = duplicate[i].value = array[i];
currentSum += array[i];
for (j = 0; j < i; ++j) { //to find ALL the best solutions, we should also put the first found value as true; it's just a line more
//yet, it saves the algorythm half of the duplicated numbers (best/this case scenario)
if (array[j] == duplicate[i].value) {
duplicate[i].duplicate = TRUE;
}
}
}
if (findDuplicateSum_R(duplicate, arraySize, tempSolution, solution, &totalSum, currentSum));
else {
printf("No solution found\n");
}
free(tempSolution);
free(duplicate);
return solution;
}
This Function does a lot of things: first, it sets up the solution array, then it initializes both the solution values and the duplicate array, that is the one used to check for duplicated values at startup. Then, we find the current sum and we set the maximum available sum to the maximum integer possible.
Then, the recursive Function is called; this one gives us the info about having found the solution (that should be Always), then we return the solution as an array.
int findDuplicateSum_R(duplicate_t * array, int arraySize, int * tempSolution, int * solution, int * totalSum, int currentSum)
{
int i;
if (check(tempSolution, arraySize)) {
if (currentSum < *totalSum) { //optimal solution checking
for (i = 0; i < arraySize; ++i) {
solution[i] = tempSolution[i];
}
*totalSum = currentSum;
}
return TRUE; //just to ensure a solution is found
}
for (i = 0; i < arraySize; ++i) {
if (array[i].duplicate == TRUE) {
if (array[i].duplicate <= maxInArrayExcept(solution, arraySize, i)) { //worst case scenario, you need it to stop the recursion on that value
tempSolution[i]++;
return findDuplicateSum_R(array, arraySize, tempSolution, solution, totalSum, currentSum + 1);
tempSolution[i]--; //backtracking
}
}
}
return FALSE; //just in case the solution is not found, but we won't need it
}
This is the recursive Function. It first checks if the solution is ok and if it is the best one found until now. Then, if everything is correct, it updates the actual solution with the temporary values, and updates the optimal condition.
Then, we iterate on every repeated value (the if excludes other indexes) and we progress in the recursion until (if unlucky) we reach the worst case scenario: the check condition not satisfied above the maximum value.
Then we have to backtrack and continue with the iteration, that will go on with other values.
PS: an optimization is possible here, if we move the optimal condition from the check into the for: if the solution is already not optimal, we can't expect to find a better one just adding things.
The hard code has ended, and there are the supporting functions:
int maxInArrayExcept(int *array, int arraySize, int index) {
int i, max = 0;
for (i = 0; i < arraySize; ++i) {
if (i != index) {
if (array[i] > max) {
max = array[i];
}
}
}
return max;
}
BOOL check(int *array, int arraySize) {
int i, j;
for (i = 0; i < arraySize; ++i) {
for (j = 0; j < i; ++j) {
if (array[i] == array[j]) return FALSE;
}
}
return TRUE;
}
I hope this was useful.
Write if anything is unclear.
Well, I got the same question in one of my interviews.
Not sure if you still need it. But here's how I did it. And it worked well.
num_list1 = [2,8,3,6,3,5,3,5,9,4]
def UniqueMinSumArray(num_list):
max=min(num_list)
for i,V in enumerate(num_list):
while (num_list.count(num_list[i])>1):
if (max > num_list[i]+1) :
num_list[i] = max + 1
else:
num_list[i]+=1
max = num_list[i]
i+=1
return num_list
print (sum(UniqueMinSumArray(num_list1)))
You can try with your list of numbers and I am sure it will give you the correct unique minimum sum.
I got the same interview question too. But my answer is in JS in case anyone is interested.
For sure it can be improved to get rid of for loop.
function getMinimumUniqueSum(arr) {
// [1,1,2] => [1,2,3] = 6
// [1,2,2,3,3] = [1,2,3,4,5] = 15
if (arr.length > 1) {
var sortedArr = [...arr].sort((a, b) => a - b);
var current = sortedArr[0];
var res = [current];
for (var i = 1; i + 1 <= arr.length; i++) {
// check current equals to the rest array starting from index 1.
if (sortedArr[i] > current) {
res.push(sortedArr[i]);
current = sortedArr[i];
} else if (sortedArr[i] == current) {
current = sortedArr[i] + 1;
// sortedArr[i]++;
res.push(current);
} else {
current++;
res.push(current);
}
}
return res.reduce((a,b) => a + b, 0);
} else {
return 0;
}
}

Memory limit of 256 mb exceeded? Why?

I was solving this problem on codeforces here, the code displays right answer but it exceeds the memory limit on the site. I can't figure out why. Also tried to use vectors but it doesn't work.
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,a,b,c,deny=0;
int groups[n];
scanf("%d %d %d",&n,&a,&b);
for(int i=0;i<n;i++){
cin>>groups[i];
}
int two_one=b*2;
//two kinds of tables:one seater,2 seater
//find no of ppl denied service
for(int j=0;j<n;j++){
if(groups[j]==1 and a!=0){
a-=1;
}
else if(groups[j]==1 and a==0){
two_one-=1;
b-=1;
}
else if(groups[j]==1 and a==0 and two_one==0){
deny+=1;
}
else if(groups[j]==2 and b!=0){
b-=1;
}
else if(groups[j]==2 and b==0){
deny+=2;
}
}
printf("%d",deny);
return 0;
}
It looks like you are trying to allocate an array before reading its size:
int n,a,b,c,deny=0; // <------ Unknown n value
int groups[n]; // <----- Allocation of array of n: undefined behavior
scanf("%d %d %d",&n,&a,&b); // <------ Reading 'groups' size
Just swap the last two lines.
Edit: according to the C++ standard, you should be using vectors:
int n,a,b,c,deny=0;
scanf("%d %d %d",&n,&a,&b);
std::vector<int> groups(n);

spoj ACPC10D -Why i am getting the wrong answer?

Here's my code .It is passing the testcase given in the problem statement.
Link for problem :http://www.spoj.com/problems/ACPC10D/
tri[i][j] stores the min value to reach at index (i,j) from tri[0][1].
//trigraphs-dp
#include<iostream>
#include<limits.h>
using namespace std;
int tri[1000000][3];
int min(int a,int b)
{
if(a<=b)
return a;
else
return b;
}
int main()
{
int n,t=1;
while(cin>>n)
{
if(n==0)
break;
for(int i=0;i<n;i++)
for(int j=0;j<3;j++)
cin>>tri[i][j];
tri[0][0]=INT_MAX;
tri[0][2]=tri[0][1]+tri[0][2];
//cout<<tri[0][2];
int a,b,c,d;
for(int i=1;i<n;i++)
for(int j=0;j<3;j++)
{
a=tri[i-1][j];
b=(j==2)?INT_MAX:tri[i-1][j+1];
c=(j==0)?INT_MAX:tri[i-1][j-1];
d=(j==0)?INT_MAX:tri[i][j-1];
tri[i][j]+=min(min(a,b),min(c,d));
}
cout<<t<<". "<<tri[n-1][1]<<"\n";
}
return 0;
}
1- You forgot to increment t in the end of the loop
2- Define tri as long long type because of possible overflow when you add up numbers.

Resources