I cannot understand/think of a case where my code fails to give correct output.
Link to the problem: http://www.spoj.pl/problems/MKBUDGET/
The problem clearly has a DP solution. I am posting my solution below:
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
vector<vector <int> > opt;
void compute_opt(vector<int> A,int n,int hire,int fire,int sal,int max_a)
{
for(int i = A[0]; i <= max_a; i++) //for num workers in 1st month
opt[0][i] = i*(hire + sal);
for(int i = 1; i < n; i++) //num of months
for(int j = A[i]; j <= max_a; j++) //num of workers for ith month >=A[i] and <= max_a
{
opt[i][j] = opt[i-1][A[i-1]] + j*sal + (A[i] > A[i-1] ? (A[i]-A[i-1])*hire : (A[i-1] - A[i])*fire);
for(int k = A[i-1]; k <= max_a; k++)
opt[i][j] = min(opt[i][j], opt[i-1][k] + j*sal + (j>k ? (j-k)*hire : (k-j)*fire));
}
}
int ans(vector<int> A, int n, int max_a)
{
int ret = opt[n-1][A[n-1]];
for(int i = A[n-1]; i <= max_a; i++)
ret = min (ret, opt[n-1][i]);
return ret;
}
int main()
{
vector<int> A;
int n, hire, fire, sal,max_a, c = 1;
while(1)
{
cin >> n;
if(n == 0)
break;
A.clear();
opt.clear();
max_a = 0;
cin >> hire >> sal >> fire;
A.resize(n);
for(int i = 0; i < n; i++)
{cin >> A[i];
max_a = max(max_a,A[i]);
}
opt.resize(n);
for(int i = 0; i < n; i++)
opt[i].resize(max_a + 2);
compute_opt(A,n,hire,fire,sal,max_a);
cout << "Case " << c << ", cost = $" << ans(A,n,max_a) << endl;
c++;
}
return 0;
}
I am getting correct answers for the two sample test cases but I get a WA when I submit. Any help ?
OK, so your problem is that you disallow the case where you hire any number of employees between A[i] and A[i - 1]. Maybe it's a good idea to fire some unneeded employees, but not all. That's why you get WA. I modified your code and got it accepted:
void compute_opt(vector<int> A,int n,int hire,int fire,int sal,int max_a)
{
// Fill all disallowed entries with infinity
for (int i = 0; i < A[0]; ++i)
opt[0][i] = 1000000000;
for(int i = A[0]; i <= max_a; i++) //for num workers in 1st month
opt[0][i] = i*(hire + sal);
for(int i = 1; i < n; i++)
for(int j = 0; j <= max_a; j++)
{
// No need for special case handling,
//just check all previous numbers of employees
opt[i][j] = 1000000000;
if (A[i] > j) continue;
for(int k = 0; k <= max_a; k++)
opt[i][j] = min(opt[i][j],
opt[i-1][k] + j*sal + (j>k ? (j-k)*hire : (k-j)*fire));
}
}
By the way, there's a "greedier" solution than the one you have that does not depend on the number of employees being small (so that the table can be allocated).
Related
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
int n, a[n];
cin >> n;
float b = n / 2;
for (int i = 1; i <= n; i++)
cin >> a[i];
// the code seems to be not working from here till the point marked below
if (n % 2 == 0)
{
for (int k = 1; k <= b; k++)
{
for (int j = (b + 1); j <= n; j++)
{
if (a[k] > a[j])
swap(a[k], a[j]);
}
}
}
// till this point(pls tell me what's wrong with this part of the code)
for (int i = 1; i <= n; i++)
cout << a[i] << " ";
getch();
return 0;
}
I'm working on C++ representation/implementation of Dijkstra's algorithm and I found this program online which fails to execute properly on TurboC++.
Any one know the solution? I also want to know why there is a minimum value of 31999 and the coding runs on a mobile emulator but refuses to run on PC TurboC++
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
//using namespace std;
int shortest(int, int);
int cost[10][10], dist[20], i, j, n, k, m, S[20], v, totcost, path[20], p;
int main()
{
int c;
cout << "enter no of vertices";
cin >> n;
cout << "enter no of edges";
cin >> m;
cout << "\nenter\nEDGE Cost\n";
for (k = 1; k <= m; k++)
{
cin >> i >> j >> c;
cost[i][j] = c;
}
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
if (cost[i][j] == 0)
cost[i][j] = 31999;
cout << "enter initial vertex";
cin >> v;
cout << v << "\n";
shortest(v, n);
}
int shortest(int v, int n)
{
int min;
for (i = 1; i <= n; i++)
{
S[i] = 0;
dist[i] = cost[v][i];
}
path[++p] = v;
S[v] = 1;
dist[v] = 0;
for (i = 2; i <= n - 1; i++)
{
k = -1;
min = 31999;
for (j = 1; j <= n; j++)
{
if (dist[j] < min && S[j] != 1)
{
min = dist[j];
k = j;
}
}
if (cost[v][k] <= dist[k])
p = 1;
path[++p] = k;
for (j = 1; j <= p; j++)
cout << path[j];
cout << "\n";
//cout <<k;
S[k] = 1;
for (j = 1; j <= n; j++)
if (cost[k][j] != 31999 && dist[j] >= dist[k] + cost[k][j] && S[j] != 1)
dist[j] = dist[k] + cost[k][j];
}
}
Arrays are 0 based so all the loops from 1 to <= n are suspect.
I'm beginner in c++, and I want to make a program that delete a row from a matrix.. Like, If I say 3 3 2
1 2 3 it need to show 1 2 3
4 5 6 7 8 9
7 8 9
The program works like this: 3 = rows, 3 = columns, 2 = the deleted row. "3 3 2" is not a row...
I wrote this :
#include <iostream>
using namespace std;
int main() {
int N, M, v[100][100];
cin>>N>>M;
int i,j,p;
cin>>p;
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
cin>>v[i][j];
for (i = 1; i <= N; ++i) {
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<" ";
cout<<"\n";
}
for (i = p; i < N; ++i)
v[i][j]=v[i+1][j];
--N;
for (i = 1; i <= N; ++i){
for (j = 1; j <= N; ++j)
cout<<v[i][j]<<' ';
cout<<"\n";
}
return 0;
}
But it doesn't work.... Can someone help me?
modified code (it will work fine ):
#include <iostream>
using namespace std;
int main()
{
int N, M, v[100][100];
cin>>N>>M;
int i,j,p;
cin>>p;
for (i = 1; i <= N; ++i)
for (j = 1; j <= M; ++j)
cin>>v[i][j];
for (i = 1; i <= N; ++i)
{
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<" ";
cout<<"\n";
}
for (i = p; i < N; ++i)
for(j=1; j<=M; ++j)
v[i][j]=v[i+1][j];
--N;
for (i = 1; i <= N; ++i)
{
for (j = 1; j <= M; ++j)
cout<<v[i][j]<<' ';
cout<<"\n";
}
return 0;
}
This doesn't work, what do you think j is doing in this code?
for (i = p; i < N; ++i)
v[i][j]=v[i+1][j];
--N;
You need to loop over rows and columns. Copy each column in every row greater that the row you want to delete. In other words you need nested loops here
for (i = p; i < N; ++i)
for (j = 1; j <= M; ++j)
v[i][j] = v[i+1][j];
--N;
You should use vector
#include <vector>
#include <iostream>
using namespace std;
int main()
{
//matrix
vector< vector<int> > V;
//To Add
for(int i=0; i<100; i++)
{
vector<int> R;
for(int j=0; j<100; j++)
{
int x;
cin>>x;
R.push_back(x);
}
V.push_back(R);
}
//To delete a row
int row_to_delete = 2;
V.erase(V.begin() + row_to_delete);
//To access
for(int i=0; i<V.size(); i++)
{
for(int j=0; j<V[i].size(); j++)
{
cout<<V[i][j];
}
}
}
vector<T> is class that use a template to create a dynamic array.
vector<int> is a var array int. V.push_back(T) you can add a element to array with type T, and with V.erase(V.begin() + int ) you can delete a element to array in this case a row. With V.size() you can take a elements count inside the array.
This code is supposed to calculate the frequency of maximum number in an array I.E the number of times the highest number in the array has occured unfortunately this code does not display any output:-
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
int birthdayCakeCandles(int n, int a[]){
int j=0,max,count=0;
max = a[j];
while(j<n){
if(a[j+1]> max){
max = a[j+1];
j++;
}
}
int seen[n];
for(int i = 0; i < n; i++)
seen[i] = 0;
for(int i = 0; i < n;i++) {
if(seen[i] == 0) {
int count = 0;
for(int j = i; j < n;j++)
if(a[j] == a[i] && a[i] == max)
count += 1;
seen[j] = 1;
}
}
return count;
}
int main() {
int i,n;
cin >> n;
int a[n];
for(i = 0; i < n; i++){
cin >> a[i];
}
int result = birthdayCakeCandles(n, a);
cout << result << endl;
return 0;
}
Your program never stops, because your maximum finding loop is for n > 0 endless. Your loop in birthdayCakeCandles should be changed to:
while (j < n)
{
if (a[j + 1] > max)
{
max = a[j + 1];
}
j++;
}
Also consider using more readable coding style and please read this.
In addition to the bug found by vasek, you made at least another mistake in the (overcomplicated) following loops, where you are trying to count the occurences of the maximum value.
// I've kept OP's indentation on purpose...
int seen[n]; // <-- Variable Length Arrays are not standard in C++
for(int i = 0; i < n; i++)
seen[i] = 0;
for(int i = 0; i < n;i++) {
if(seen[i] == 0) {
int count = 0;
for(int j = i; j < n;j++)
if(a[j] == a[i] && a[i] == max)
count += 1;
seen[j] = 1; // <-- misleading indentation, this is always executed
// no matter what the condition is
}
}
While all you need to do, once you have found the maximum value, is:
int count = 0;
for( int i = 0; i < n; ++i ) {
if( a[i] == max )
++count;
}
As a matter of fact (unless you want to create a function operating on an array for other reasons), you don't need any array (or std::vector) at all to complete your assignment. This code will perform the same task:
#include <iostream>
#include <limits>
int main()
{
int n;
std::cin >> n;
int x,
max = std::numeric_limits<int>::min();
int count = 0;
for ( int i = 0;
i < n && std::cin >> x;
++i )
{
if ( x >= max )
{
if ( x > max )
{
max = x;
count = 1;
}
else
{
++count;
}
}
}
std::cout << count << '\n';
}
I have been struggling with it for 2 days.Please, could anyone tell me why does it exceed the time limit when i use as input 20000 and 0 and 40000 numbers afterwards ? I tried to make the variables type as large as possible, but that does not seem to help either.
#include <bits/stdc++.h>
using namespace std;
int main()
{
/*freopen("file.in", "r", stdin);
freopen("file.out", "w" , stdout);*/
long long int aux,i, n, k, j, total = 0;
cin >> n >> k;
long long int a[n], b[n], order[n];
signed long long int profit[n];
for(i = 0; i < n; i++)
cin >> a[i];
for(i = 0; i < n; i++)
cin >> b[i];
for(i = 0; i < n; i++)
profit[i] = a[i] - b[i];
for(i = 0; i < n; i++)
order[i] = i;
for(i = 0; i < n; i++)
for(j = i + 1; j < n; j++)
if(profit[order[i]] > profit[order[j]])
{
aux = order[i];
order[i] = order[j];
order[j] = aux;
}
if(k > 0)
for(i = 0; i < k; i++)
{
total += a[order[i]];
}
for(i = k; i < n; i++)
{
if(profit[order[i]] < 0)
total += a[order[i]];
else
total += b[order[i]];
}
cout << total;
return 0;
}
The complexity of your code is O(n^2), which is too much for N=20000. Reduce the complexity, replacing your bubble sort with Qsort. Try std::sort with custom comparison function.