How to read from scanf values of the 01-knapsack algorithm and pass to a function - knapsack-problem

If I enter the numbers:
3 10
7 6
5 5
4 5
the output is : 9. OK — that's the correct value. But if I enter:
10 25
3 5
3 5
3 5
3 5
3 5
3 5
3 5
3 5
3 5
3 5
the correct output should be: 15 but I receive 2005985278.
What's the problem in this code?
#include<stdio.h>
#include<stdlib.h>
#define MA 29
int max(int a, int b) {
return (a > b)? a : b;
}
int knapsack(int W, int P[], int V[], int N)
{
int i, w;
int K[N+1][W+1];
for (i = 0; i <= N; i++)
{
for (w = 1; w <= W; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (P[i-1] <= w)
K[i][w] = max(V[i-1] + K[i-1][w-P[i-1]], K[i-1][w]);
else
K[i][w] = K[i-1][w];
}
}
return K[N][W];
}
int main()
{
int N,W,i;// N: Quantidade de Objetos - W: Capacidade da Mochila; i: interação
int Val=1;//V: Valor;
int Pes=1;//P: Peso;
do{
scanf("%d %d",&N,&W);//ler N e W
for (i=1;i<=N;i++) // iteração
scanf("%d %d",&Val,&Pes);//ler V
//ler P
int V[]={Val};//declaração do vetor V e recebendo Val do scanf
int P[]={Pes};//declaração do vetor P e recebendo Pes do scanf
printf("%d",knapsack(W, P, V, N));
printf("\n");
}while(N!=0 && W!=0);
return 0;
}
I need to enter the number of items N and the capacity W:
When I enter N = 1, W - 7 and the objects P = 4, V = 5 the output is 4.
If I enter other values such as N = 10, W = 25 and P = 3 3 3 3 3 3 3 3 3 3, V = 5 5 5 5 5 5 5 5 5 5, I receive 2005985278 instead of 15.
Please what's the error in my code?
Now my code is this but I receive the erro in my output:
3 10
7 6
5 5
4 5
1 7
4 5
the correct output is : 9 and 4 and i received 7 and 0;
in this case how may i add a end the programm when enter N==0 && W==0?
#include<stdio.h>
#include<stdlib.h>
#define MA 29
int max(int a, int b) {
return (a > b)? a : b;
}
int knapsack(int W, int P[], int V[], int N)
{
int i, w;//interação;
int K[N+1][W+1];//declaração de K recebendo o valor de N e W +1;
for (i = 0; i <=N; i++) // para i=0 i< = N incrementa i;
{
for (w = 0; w <= W; w++)
{
if (i==0 || w==0)
K[i][w] = 0;
else if (P[i-1] <= w)
K[i][w] = max(V[i-1] + K[i-1][w-P[i-1]], K[i-1][w]);
else
K[i][w] = K[i-1][w];
}
}
return K[N][W];
}
int main()
{
int N,W,i;// N: Quantidade de Objetos - W: Capacidade da Mochila; i: interação
//P: Peso;
while (scanf("%d %d", &N, &W) == 2)
{
int V[N];
int P[N];
for (i = 1; i <= N; i++)
if (scanf("%d %d", &V[i], &P[i]) != 2)
break;
printf("%d\n", knapsack(W, P, V, N));
}
}

Your problem is that you are allocating arrays of size 1 and then trying to access 10 elements in those arrays. C won't stop you trying, but it will usually give you the wrong answer.
Existing code:
do{
scanf("%d %d",&N,&W); // Should test for success and terminate loop on failure
for (i=1;i<=N;i++)
scanf("%d %d",&Val,&Pes); // Should check for success; should store values
int V[]={Val}; // V is an array with one entry, the last value entered as Val.
int P[]={Pes}; // P is an array with one entry, the last value entered as Pes.
printf("%d",knapsack(W, P, V, N));
printf("\n");
} while (N!=0 && W!=0);
C99 code:
while (scanf("%d %d", &N, &W) == 2)
{
int V[N];
int P[N];
for (i = 1; i <= N; i++)
if (scanf("%d %d", &V[i], &P[i]) != 2)
break;
printf("%d\n", knapsack(W, P, V, N));
}
Note that if you'd printed the inputs to your knapsack() function, either in the calling code or in the function itself, you'd have seen the trouble very quickly. It is a powerful technique to print your input data after you've finished reading it. Note that printing it while you're reading can mask problems that printing after you've finished reading will reveal.
Clearly, if your knapsack algorithm is incorrect, you'll still get wrong answers; I've not reviewed that and have no particular plans to do so. However, you should be getting the correct input data, which improves enormously the chances of getting the right output.

Related

Using heap sort, append an array elements

I have given an array int A[] = {12,10,9,2,11,8,14,3,5};
In this array, 1st 4 elements(from index 0 to index 3) follow max heap condition. But last 5 elements(index 4 to index 8) don't follow max heap condition. So, I have to write a code so that the whole array follow max heap condition.
I have given a function call max_heap_append(A,3,8); and I have to use it in my code to write the program. It is an assignment so I have to follow the instruction.
I have written this code bellow but when I run the program, nothing happens.
#include <stdio.h>
#include <stdlib.h>
void swap(int * a, int * b )
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void heapify( int A[], int q, int i)
{
int largest = i;
int l = 2 * i + 1 ;
int r = 2 * i + 2;
if( l < q && A[l] > A[largest])
{
largest = l;
}
if( r < q && A[r] > A[largest])
{
largest = r;
}
if( largest != i)
{
swap( &A[i] , &A[largest]);
heapify(A, q, largest);
}
}
void max_heap_append(int A[], int p , int q)
{
int i;
for( i = q / 2 -1; i >= 0; i--)
{
heapify( A , q , i);
}
// sort the heap
for( i = q; i>= 0; i--)
{
swap(&A[0] , &A[i]);
heapify(A, i, 0);
}
}
void printA(int A[], int q)
{
int i;
for( i = 0; i <= q; i++)
{
printf("%d", A[i]);
}
printf("%d\n");
}
int main()
{
int A[] = {12,10,9,2,11,8,14,3};
max_heap_append(A,3,8);
printf("Sorted: ");
printA(A, 8);
return 0;
}
Its not followed heapify from 0 to 3 index.. so u need to heapify all. there is some mistake. if your array size is 8 then u can not excess a[8], you can access a[0] to a[7]. so you need to iterate from 0 to 7.
Try with this:
#include <stdio.h>
#include <stdlib.h>
void swap(int * a, int * b )
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
void heapify( int A[], int q, int i)
{
int largest = i;
int l = 2 * i + 1 ;
int r = 2 * i + 2;
if( l < q && A[l] > A[largest])
{
largest = l;
}
if( r < q && A[r] > A[largest])
{
largest = r;
}
if( largest != i)
{
swap( &A[i] , &A[largest]);
heapify(A, q, largest);
}
}
void max_heap_append(int A[], int p , int q)
{
int i;
for( i = q-1; i >= 0; i--)
{
heapify( A , q , i);
}
// sort the heap
for( i = q-1; i>= 0; i--)
{
swap(&A[0] , &A[i]);
heapify(A, i, 0);
}
}
void printA(int A[], int q)
{
int i;
for( i = 0; i < q; i++)
{
printf("%d ", A[i]);
}
printf("\n");
}
int main()
{
int A[] = {12,10,9,2,11,8,14,3};
max_heap_append(A,3,8);
printf("Sorted: ");
printA(A, 8);
return 0;
}
You have several problems in your code
printA
One is/can be indicated by the compiler, in printA :
printf("%d\n");
‘%d’ expects a matching ‘int’ argument, but there no no argument
It is easy to guess you just wanted to print a newline, so that line can be replaced by
putchar('\n');
Still in printA you print the numbers without a separator, the result is not usable, for instance do
printf("%d ", A[i]);
When I look at the call of printA in main the parameter n is the number of elements in A, so the end test of the for is invalid because you try to print a value out of the array, the loop must be :
for( i = 0; i < q; i++)
max_heap_append
in the second for the index i can value 0, in that case you swap the first element of the array with itself, that has no sense and the same for the call of heapify with the 2 last arguments valuing 0
When you call that function in main the parameter q receive the number of elements in the array, which is also the first value of i still in that second for and &A[i] is out of the array. You need to replace that line by
for( i = q-1; i> 0; i--)
If I do all these changes :
Compilation and execution :
bruno#bruno-XPS-8300:/tmp$ gcc -g -Wall h.c
bruno#bruno-XPS-8300:/tmp$ ./a.out
Sorted: 2 3 8 9 10 11 12 14
bruno#bruno-XPS-8300:/tmp$

Print all verticies in graph's cycle

I've tried according to this Algorithm to find and print simple cycle in complexity of O(n) on undirected graph.
Did it in C++ according to my tutor and following is my code:
int parent[1000] = {0};
int status[1000] = {0};
bool oriented = true;
#include ...
using namespace std;
array<list<int>, 1000 + 1> g;
void PrintCycle(int v, int u) {
do {
printf("%d",u);
u = parent[u];
} while (u != v);
}
bool DFS_cycle(int u) {
status[u] = 1;
for (int v:g[u]) {
if (status[v] == 0) {
parent[v] = u;
DFS_cycle(v);
}
if (status[v] == 1 && v != parent[u]) {
PrintCycle(v,u);
}
}
status[u] = 2;
}
int main() {
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int N, u, v;
cin >> N;
while (cin >> u >> v) {
g[u].push_back(v);
g[v].push_back(u);
}
parent[1] = 1;
DFS_cycle(1);
return 0;
}
But it doesn't work for the following input: (First line is the number of vertices. Vertices are numbered from 1. After that each line describes an edge.)
8
3 1
3 4
3 2
2 5
2 6
6 7
6 8
What did I do wrong?
First of all you have used C++ not C.
For the given input there is no cycle. It doesn't print any cycle either. So it does work for the given input.
However your code has bug. If we add another edge (5,8) a cycle is formed (2 -> 5 -> 8 -> 6). But your code prints the cycle as (6 -> 8 -> 5).
Check out my code for your bug :
void PrintCycle(int v, int u) {
while(u != v)
{
printf("%d ",u); // You didn't give any space after %d
// It could not be possible to differentitate between '1''2'
// and '12'
u = parent[u];
}
printf("%d \n", v);
}
bool DFS_cycle(int u) {
status[u] = 1;
for (int v:g[u]) {
if (status[v] == 0) {
parent[v] = u;
DFS_cycle(v);
}
else if (status[v] == 1 && v != parent[u]) { // It should be 'else if' NOT 'if'
PrintCycle(v,u);
break;
}
}
status[u] = 2;
}
And it is a good idea to #define WHITE 0, #define GRAY 1 etc and then using WHITE, GRAY etc instead of using bare 1, 2 etc.

Is Matrix Good or Bad?

A matrix B (consisting of integers) of dimension N × N is said to be good if there exists an array A (consisting of integers) such that B[i][j] = |A[i] - A[j]|, where |x| denotes absolute value of integer x.
You are given a partially filled matrix B of dimension N × N. Q of the entries of this matrix are filled by either 0 or 1. You have to identify whether it is possible to fill the remaining entries of matrix B (the entries can be filled by any integer, not necessarily by 0 or 1) such that the resulting fully filled matrix B is good.
Example
Input 4
2 2
1 1 0
1 2 1
2 3
1 1 0
1 2 1
2 1 0
3 2
2 2 0
2 3 1
3 3
1 2 1
2 3 1
1 3 1
Output
yes
no
yes
no
Here is my code, but failing some tests.
include int main(){
int t;
scanf("%d", &t);
while(t--){
int n, q;
scanf("%d %d", &n, &q);
int arr[n][n];
int brr[n];
for(int i=0;i<n;i++){
brr[i]=1;
for(int j=0;j<n;j++)
arr[i][j]=-1;
}
int result=0;
while(q--){
int l, r, val;
scanf("%d %d %d", &l, &r, &val);
arr[l-1][r-1]=val;
arr[r-1][l-1]=val;
if( abs(brr[l-1]-brr[r-1])!=val && l!=r){
brr[r-1]=brr[r-1]-val;
}
}
for(int i=0;i<n;i++)
printf("%d ", brr[i]);
printf("\n");
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(arr[i][j]!=-1 ){
if( abs(brr[i]-brr[j])==arr[i][j] && abs(brr[i]-brr[j])==arr[j][i]){
continue;
}
else{
result=1;
break;
}
}
}
if(result)
break;
}
if(result)
printf("no\n");
else
printf("yes\n");
}
return 0; }
The question is from live contest : https://www.codechef.com/SEPT17/problems/FILLMTR/. Please focus on learning rather than increase the count of accepted problems.

QuickSort Hoare's partitioning not working

Hi I'v been trying to write Hoare's partition function for like 5 hours now. I read this and this and even straight up copied the "correct" function from these questions and it's still nowhere near the answer. Here is my "translated" code from Cormen's book.
int Hpartition(int A[], int p, int r){
int x = A[p];
int i = p - 1;
int j = r + 1;
while(true){
do{
j--;
}while(A[j] <= x);
do{
i++;
}while(A[i] >= x);
if(i < j){
swap(A[i],A[j]);
}
else
return j;
}
}
QuickSort:
void qs(int A[],int p,int r){
if(p<r){
int q=Hpartition(A,p,r);
qs(A,p,q-1);
qs(A,q+1,r);
}
}
Main:
int main(int argc, const char * argv[]) {
int tab[10];
for(int k=0;k<10;k++){
cin >> tab[k];
}
qs(tab,0,9);
for(int i=0;i<10;i++){
cout << tab[i] << " ";
}
return 0;
}
For this data :
2 4 1 3 5 7 6 8 10 9
It produces this result:
2 4 9 3 5 7 6 8 10 1
Based on the previous questions regarding the topic I know there may be some mistakes in the book. But even when I apply the answers from the previous questions it just won't work .
Here is the algorithm from the book:
HOARE-PARTITION(A, p, r)
1 x = A[p]
2 i = p - 1
3 j = r + 1
4 while TRUE
5 repeat
6 j = j - 1
7 until A[j] <= x
8 repeat
9 i = i + 1
10 until A[i] >= x
11 if i < j
12 exchange A[i] with A[j]
13 else return j
Thanks in advance for any help.
You have 2 error translating code from book:
do{
j--;
}while(A[j] <= x);
You should inverse this:
do{
j--;
}while(A[j] > x);
The same with:
do{
i++;
}while(A[i] >= x);
And one more here:
qs(A,p,q-1);
qs(A,q+1,r);
Change to:
qs(A,p,q);
qs(A,q+1,r);

Number of submatricies containing all zeros

Is there a way to find a number of rectangular submatrices containing all zeros with a complexity smaller than O(n^3), where n is the dimension of given matrix?
Here is a solution O(n² log n).
First, let's convert the main problem to something like this:
For given histogram, find the number of submatrices containing all zeros.
How to convert it ?
For each position calculate the height of column that start on that position and contain only zeros.
Example:
10010 01101
00111 12000
00001 -> 23110
01101 30020
01110 40001
It can be easily find in O(n²).
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
up[i][j] = arr[i][j] ? 0 : 1 + up[i - 1][j];
Now we can consider each row as histogram with given heights.
Let's solve the problem with histogram.
Our goal is to travel all heights from left to right, and on each step we are going to update array L.
This array for each height is going to contain maximum widths so that we can make a rectangle of this width from current position, to the left and of given height.
Consider example:
0
0 0
0 000
00000 -> heights: 6 3 4 4 5 2
000000
000000
L[6]: 1 0 0 0 0 0
L[5]: 1 0 0 0 1 0
L[4]: 1 0 1 2 3 0
L[3]: 1 2 3 4 5 0
L[2]: 1 2 3 4 5 6
L[1]: 1 2 3 4 5 6
steps: 1 2 3 4 5 6
As you can see if we add all those numbers we will receive an answer for given histogram.
We can simply update array L in O(n), however we can also do it in O(log n) by using segment tree (with lazy propagation) that can add in interval, set value in interval and get sum from interval.
In each step we just add 1 to interval [1, height] and set 0 in interval[height + 1, maxHeight] and get sum from interval [1, maxHeight].
height - height of current column in histogram.
maxHeight - maximum height of column in histogram.
And thats how you can get O(n² * log n) solution :)
Here is main code in C++:
const int MAXN = 1000;
int n;
int arr[MAXN + 5][MAXN + 5]; // stores given matrix
int up[MAXN + 5][MAXN + 5]; // heights of columns of zeros
long long answer;
long long calculate(int *h, int maxh) { // solve it for histogram
clearTree();
long long result = 0;
for(int i = 1; i <= n; i++) {
add(1, h[i]); // add 1 to [1, h[i]]
set(h[i] + 1, maxh); // set 0 in [h[i] + 1, maxh];
result += query(); // get sum from [1, maxh]
}
return result;
}
int main() {
ios_base::sync_with_stdio(0);
cin >> n;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
cin >> arr[i][j]; // read the data
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
up[i][j] = arr[i][j] ? 0 : 1 + up[i - 1][j]; // calculate values of up
for(int i = 1; i <= n; i++)
answer += calculate(up[i], i); // calculate for each row
cout << answer << endl;
}
Here is the beginning of code, segment tree:
#include <iostream>
using namespace std;
// interval-interval tree that stores sums
const int p = 11;
int sums[1 << p];
int lazy[1 << p];
int need[1 << p];
const int M = 1 << (p - 1);
void update(int node) {
if(need[node] == 1) { // add
sums[node] += lazy[node];
if(node < M) {
need[node * 2] = need[node * 2] == 2 ? 2 : 1;
need[node * 2 + 1] = need[node * 2 + 1] == 2 ? 2 : 1;
lazy[node * 2] += lazy[node] / 2;
lazy[node * 2 + 1] += lazy[node] / 2;
}
} else if(need[node] == 2) { // set
sums[node] = lazy[node];
if(node < M) {
need[node * 2] = need[node * 2 + 1] = 2;
lazy[node * 2] = lazy[node] / 2;
lazy[node * 2 + 1] = lazy[node] / 2;
}
}
need[node] = 0;
lazy[node] = 0;
}
void insert(int node, int l, int r, int lq, int rq, int value, int id) {
update(node);
if(lq <= l && r <= rq) {
need[node] = id;
lazy[node] = value * (r - l + 1);
update(node);
return;
}
int mid = (l + r) / 2;
if(lq <= mid) insert(node * 2, l, mid, lq, rq, value, id);
if(mid + 1 <= rq) insert(node * 2 + 1, mid + 1, r, lq, rq, value, id);
sums[node] = sums[node * 2] + sums[node * 2 + 1];
}
int query() {
return sums[1]; // we only need to know sum of the whole interval
}
void clearTree() {
for(int i = 1; i < 1 << p; i++)
sums[i] = lazy[i] = need[i] = 0;
}
void add(int left, int right) {
insert(1, 0, M - 1, left, right, 1, 1);
}
void set(int left, int right) {
insert(1, 0, M - 1, left, right, 0, 2);
}
// end of the tree

Resources