Heres the problem:
A Milkman serves milk in packaged bottles of varied sizes. The possible size of the bottles are {1, 5, 7 and 10} litres. He wants to supply desired quantity using as less bottles as possible irrespective of the size. Your objective is to help him find the minimum number of bottles required to supply the given demand of milk.
Input Format:
First line contains number of test cases N
Next N lines, each contain a positive integer Li which corresponds to the demand of milk.
Output Format:
For each input Li, print the minimum number of bottles required to fulfill the demand
I have written this code for the problem.
#include <iostream>
#include <vector>
#include <stdio.h>
#include <set>
#include <algorithm>
#include <string>
#include <queue>
#include <map>
#include <iomanip>
#include <locale>
#include <stdlib.h>
#include <cstring>
#include <cmath>
#include <tgmath.h>
using namespace std;
const int INF = 1000000000;
int m[4] = { 1, 5, 7, 10 };
int r[100000000];
int milk(int n) {
int q;
if (r[n] < INF)
return r[n];
if (n <= 0)
q = 0;
else {
q = INF;
for (int i = 0; i < 4; i++) {
if (n >= m[i])
q = min(q, 1 + milk(n - m[i]));
}
}
r[n] = q;
return q;
}
int main() {
int t, n;
cin >> t;
while (t--) {
cin >> n;
memset(r, INF, sizeof(r));
cout << milk(n) << endl;
}
return` 0;
}
I have used dynamic programming for this.But I only get an output zero for every input.I am new to dp.Please help.
int milk(int n) {
int min;
memset(r, 0, sizeof(r));
for (int i = 1; i <= n; i++) {
min = 10000000; // some very large value greater than n
for (j = 0; j <= 3; j++) {
if (m[j] > i)
continue;
else if (r[i - m[j]] < min)
min = r[i - m[j]];
}
r[i] = min;
}
return r[n];
}
I hope this works and it would help you , comment if you have any doubts.
Related
This question is not about where to put the srand function.
I have just started learning DSA with Insertion Sort. I have written a C++ program to perform Insertion Sort and wanted to create some neat visuals of the Time Analysis. I tried generating Random Arrays for the Time Analysis using the rand() function but the Arrays generated seem to have a character at the end. The elements in the character array should all be single digit integers like '0' '3' and so on.....
The Main Function of the Program:
#include <iostream>
#include <time.h>
#include <cstdlib>
#include <iomanip>
using namespace std;
int size(char a[]) {
int l = 0;
while (a[l] != NULL) {
l++;
}
return l;
}
void InsertionSort(char arr[]) {
for (int k = 1; k < size(arr); k++) {
char temp = arr[k];
int i = k - 1;
while (i >= 0 && arr[i] > temp) {
arr[i + 1] = arr[i];
i--;
}
arr[i + 1] = temp;
}
}
int main(void) {
//Generate Random Arrays of size snum
for (int k = 1; k < 100; k++) {
int snum = k * 100;
char Array[snum];
srand(time(NULL));
for (int s = 0; s < snum; s++)
{
int no = rand() % 9 + 1;
Array[s] = no + '0';
}
cout << "START\t";
//cout<<"\n"<<Array<<"END\n"; // Character is being Printed at the end........ :-(
clock_t start, end;
start = clock();
InsertionSort(Array);
end = clock();
double time_taken = double(end - start) / double(CLOCKS_PER_SEC);
cout << "\"" << fixed << time_taken << setprecision(9) << "\",\"" << 100 * k << "\"" << endl;
}
}
How I Compile and Run the Program:
g++ InsertionSort.cpp
./a.out > InsertionSort.txt
--------------EDIT--------------
Based on the suggestions, I have replaced the Array with a vector. Please provide any further suggestions....
RandomIntVector.cpp
#include "RandomIntVector.h"
#include <random>
#include <vector>
using namespace std;
vector<int> RandomVector(int size){
uniform_int_distribution<> d(1, 1000);
mt19937 gen;
vector<int> Ar;
for(int s=0; s<(size-1); s++)
{
int no = d(gen);
Ar.push_back(no);
}
return Ar;}
InsertionSort.cpp
#include "InsertionSort.h"
#include <vector>
using namespace std;
void InsertionSort(vector<int> arr){
int size=arr.size();
for(int k=1;k<size;k++){
int temp = arr[k];
int i=k-1;
while(i>=0 && arr[i]>temp ){
arr[i+1]=arr[i];
i--;
}
arr[i+1]=temp;
}
}
Main.cpp
#include <iostream>
#include <vector>
#include <chrono>
#include <iomanip>
#include "RandomIntVector.h"
#include "InsertionSort.h"
using namespace std;
int main(void){
//Generate Random Arrays of size snum
for(int k=1;k<100;k++){
vector<int> Array = RandomVector(100*k);
clock_t start, end;
start = clock();
InsertionSort(Array);
end = clock();
double time_taken = double(end - start) /
double(CLOCKS_PER_SEC);
//Print the Time Taken along with the size of the Input
cout<<"\""<<fixed << time_taken << setprecision(9)<<"\",\""
<<100*k<<"\""<<endl;
}
return 0;
}
C++ beginner here. I'm trying to write a program without the usage of arrays that would take a N number and allow the user to write a sequence of elements consisting of the N number (e.g. the N is 5, then the sequence of elements should be consisted of 5 integers (e.g. 8,21,7,21,10)). Then the program should count how much does the max element of the sequence occurr (in the example the output should be 2, because the max number is 21, which occurrs 2 times).
Here is the code I've wrote so far, which detects the max nubmer of the sequence.
#include <iostream>
#include <limits.h>
using namespace std;
int main() {
int n , n_seq, count = 0;
int max = INT_MIN;
cin>>n;
for(int i = 0; i < n; i++)
{
cin>>n_seq;
if(n_seq > max)
{
max = n_seq;
}
}
cout<<max;
}
But I can't figure out the rest on how to increment the count variable each time the max nubmer occurs.
You need to increase the count when n_seq == max and when you encounter a new maximum number you need to reset the counter:
if(n_seq > max)
{
counter = 1;
max = n_seq;
} else if (n_seq == max) {
++count;
}
#include <iostream>
#include <limits.h>
using namespace std;
int main() {
int n, n_seq, count = 0;
int max = INT_MIN;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> n_seq;
if (n_seq > max) {
count = 1;
max = n_seq;
} else if(max == n_seq)
++count;
}
std::cout << max << std::endl;
std::cout << count << std::endl;
}
#include <iostream>
#include <limits.h>
using namespace std;
int main() {
int n , n_seq, count = 0;
int max = INT_MIN;
cin>>n;
for(int i = 0; i < n; i++)
{
cin>>n_seq;
if(n_seq > max)
{
max = n_seq;
count = 1;
}
else if(n_seq == max){
count++;
}
}
cout<<max;
}
I need to write a program which counts n digit number sum. For example, sum of 1 digit number is 45 (from 1 to 9) and so on.
I wrote this code but it's useless so I need little bit help.
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
int n;
long suma = 0;
cin >> n;
for (int i = 1; i <= n; i++)
{
suma = suma + i;
}
cout << suma;
return 0;
}
Basically what you're missing is a way to determine what an N digit number is. Fortunately you know that N-digit number ranges from 10^(N-1) to 10^N, so you have this as the loop condition:
#include <cmath>
for (long i = pow(10, n-1); i < pow(10, n); i++)
If you want to do this faster, you need some Maths work beforehand and rework the algorithm. You probably want the summing formula:
a = pow(10, n-1);
b = pow(10, n);
sum = (a + b - 1) * (b - a) / 2; // (a1 + an)* n / 2
You can use the following code to find the sum of N digit numbers:
include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
int n;
long suma = 0;
cin >> n;
for (long i = pow(10, n-1); i < pow(10, n); i++) // this is what was wrong in your approach,
{
suma = suma + i;
}
cout << suma;
return 0;
}
OR
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
int main()
{
int n,x,y;
long suma = 0;
cin >> n;
x =pow(10,n-1);
y =pow(10,n);
suma = (x + (y-1)) * (x - y) / 2; //this will reduce your time complexity from O(n) by eliminating the for loop.
cout << suma;
return 0;
}
I am trying to solve the Non-Divisible Subset problem from Hackerrank (https://www.hackerrank.com/challenges/non-divisible-subset). I am trying to use the idea that if the sum of a and b is divisible by k, then a%k+b%k = k, however, it's not working very well.
Here is what I've written so far:
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
int k;
cin >> n;
cin >> k;
int j;
vector<int>numbers;
vector<int>remainders;
for(int i = 0; i < n; i++) {
int z;
cin >> z;
numbers.push_back(z);
}
for (vector<int>::iterator it = numbers.begin(); it != numbers.end(); it++) {
j = *it % k;
remainders.push_back(j);
}
for(vector<int>::iterator it2 = remainders.begin(); it2 != remainders.end(); it2++) {
int remainderCount = 0;
int otherRemainderCount = 0;
otherRemainderCount = std::count(remainders.begin(), remainders.end(), k-*it2);
remainderCount = std::count(remainders.begin(), remainders.end(), *it2);
if (remainderCount > otherRemainderCount) {
theChosenOne = *it2;
} else if (otherRemainderCount > remainderCount) {
theChosenOne = k-*it2;
}
cout << theChosenOne << endl;
}
return 0;
}
I created a vector for the remainders and I am using the std::cout function to find out which remainder appears more in the vector. If K would be 5, *it2 = 4, and k-*it2 = 1. If *it2 appears more times, then I would choose *it2. Otherwise, I would choose k-*it2.
Your solution looks to be on the right track, but there is some change that is needed.
You basically need to hash the numbers in the array to proper location.
Have an array rem[k] initialised to 0.
Iterate over the n numbers in the array, and do the following:
rem[array[i]%k]++;
Now you have to deal with only the rem[] array, to find the maximum subset. The rem array has size of maximum k<=100. Make use of the small size of rem[] array to find the solution efficiently.
Edit: Adding the code for you.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n,i,k;
cin>>n>>k;
int arr[n];
int rem[k]={0};
for(i=0;i<n;i++)
{
cin>>arr[i];
}
for(i=0;i<n;i++)
{
rem[arr[i]%k]++;
}
int count = 0;
for(i=1;i<=k/2;i++)
{
count = count + max(rem[i],rem[k-i]);
}
count = count + (rem[0]>0?1:0);
if(k%2==0)
{
count = count - rem[k/2];
if(rem[k/2]>0)
count = count + 1;
}
cout<<count;
return 0;
}
After you have found out the contents of the rem[] array, its time to find the maximum subset. If you select rem[1] then you cannot select rem[k-1] as any two numbers, one from rem[1] and another from rem[k-1] can be summed together which will be divisible by k that we don't want. So we find whichever is maximum out of rem[i] and rem[k-i] and add it to the count
My code uses the above logic..
Hope it helps!!!
int main() {
int n,k;
cin>>n>>k;
vector <int> a(n);
vector <int> r(k,0);
for(int i=0;i<n;i++)
{
cin>>a[i];
r[a[i]%k]++;
}
int ctr=min(1,r[0]);
for(int a=1;a<(k/2+1);a++)
{
if(a!=k-a)
ctr+=max(r[a],r[k-a]);
}
if(k%2==0&&r[k/2]!=0)
ctr++;
cout<<ctr;
return 0;
}
This seemed to work
#include <stdio.h>
int min(int a, int b) { return a < b ? a : b; }
int max(int a, int b) { return a > b ? a : b; }
int main() {
int n, k, a, total = 0;
scanf("%d %d", &n, &k);
int mods[k];
for (int i = 0; i < k; i++)
mods[i] = 0;
while (n--) {
scanf("%d", &a);
mods[a % k]++;
}
// can only have 1 value congruent to 0 mod k
total += min(1, mods[0]);
// if even, can only have 1 value congruent to k/2 mod k
if (k % 2 == 0)
total += min(1, mods[k / 2]);
// for all others, pick max of those k and n-k mod k
for (int d = 1; d < (k + 1) / 2; d++) { // for all others,
total += max(mods[d], mods[k - d]);
}
printf("%d", total);
return 0;
}
Please read the task first: http://codeabbey.com/index/task_view/neumanns-random-generator
I have to keep track of the number of iterations, but I get very strange results. In the example after the task we have the numbers 0001 and 4100 and they should come to loop after 2 and 4 iterations. But my results are 1, 4 or if I change the place of the counter 2 or 5 but never 2 and 4. Here is my code:
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
int value;
int counter;
int result;
int setvalue = 1; // use to exit the loop if setvalue == 0;
cin >> n;
vector<int> new_results(0); // use to store all the results from iterations
vector<int> results_vec(0); // use to store the number of iterations for each number
for (int i = 0; i < n ; i++)
{
cin >> value;
while(setvalue == 1)
{
value = value*value;
value = (value % 1000000) / 100;
if(find(results_vec.begin(), results_vec.end(), value) == results_vec.end())
{
results_vec.push_back(value);
}
else
{
counter = results_vec.size();
new_results.push_back(counter);
setvalue = 0;
}
}
results_vec.clear();
}
for (int i = 0; i < new_results.size() ; i++)
{
cout << new_results[i] << " ";
}
}
Going in and out of a string the way you have is really very ugly and extremely expensive computationally.
Use
(value % 1000000) / 100;
instead to extract the middle four digits. This works by (1) taking the modulus to remove the leading two digits then (2) removing the last two with integer division.
As it's so much simpler, I suspect that will fix your bugs too.
Here is the correct code, thank you for all your help.
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int n;
int value;
int counter;
int result;
cin >> n;
vector<int> new_results(0); // use to store all the results from iterations
vector<int> results_vec(0); // use to store the number of iterations for each number
for (int i = 0; i < n ; i++)
{
cin >> value;
results_vec.push_back(value);
while(true)
{
value = value*value;
value = (value % 1000000) / 100;
if(find(results_vec.begin(), results_vec.end(), value) == results_vec.end())
{
results_vec.push_back(value);
}
else
{
counter = results_vec.size();
new_results.push_back(counter);
break;
}
}
results_vec.clear();
}
for (int i = 0; i < new_results.size() ; i++)
{
cout << new_results[i] << " ";
}
}