This is a problem from competitive programmer's handbook:
We are given the prices of k
products over n days, and we want to buy each product exactly once. However,
we are allowed to buy at most one product in a day. What is the minimum total
price?
| Day | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| Product 0 | 6 | 9 | 5 | 2 | 8 | 9 | 1 | 6 |
| Product 1 | 8 | 2 | 6 | 2 | 7 | 5 | 7 | 2 |
| Product 2 | 5 | 3 | 9 | 7 | 3 | 5 | 1 | 4 |
The Optimal Selection is:
- product 0 on day 3 at price 2,
- product 1 on day 1 at price 2,
- product 2 on days 6 at price 1.
which gives us the total of 5.
The solution:
We either do not buy any product on day d or buy a product x
that belongs to set S. In the latter case, we remove x from set S and add the price of x to the total price.
Here's the code from book:
#include <stdio.h>
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
int main()
{
int price[3][8] = {{ 6, 9, 5, 2, 8, 9, 1, 6 },
{ 8, 2, 6, 2, 7, 5, 7, 2 },
{ 5, 3, 9, 7, 3, 5, 1, 4 }};
int n = 8, k = 3;
int total[1<<10][10];
//Buy all products on day 0
for (int x = 0; x < k; x++) {
total[1<<x][0] = price[x][0];
}
for (int d = 1; d < n; d++) {
for (int s = 0; s < (1<<k); s++) {
total[s][d] = total[s][d-1];
for (int x = 0; x < k; x++) {
if (s & (1<<x)) {
total[s][d] = min(total[s][d], total[s ^ (1<<x)][d-1] + price[x][d]);
break;
}
}
}
}
//Output
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
printf("%d", total[i][j]);
}
printf("\n");
}
}
The problem restricts us to buy only one product a day but the code seems to not address that issue at all (also, we buy all products on first day which is fine). The output is just the minimum for each product available by that day [1,2,1]. What am I doing wrong here?