Optimizing the number of calls to expensive function - c++

I have an mainFun that takes four parameters x, a, b, and c, all vector-valued and possibly of varying length. This function calls expensiveFun that is computationally expensive so I'd like to reduce the number of calls to expensiveFun. This function needs to be called for each value in x[i], a[i], b[i], c[i] and if a, b, or c are of shorter length, then they need to be "wrapped" (their index is in modulo a[i % a.size()]). It would be the best to precompute the expensiveFun for each possible distinct value of x (i.e. all integers 0,...,max(x)) and then just fill-in the output out by out[i] = precomputedValues[x[i]]. This can be easily achieved if a, b, and c have the same length (example below), but it gets ugly if they are not. Is there any way to make it more efficient for case when the lengths of parameter vectors differ?
Below I provide a reproducible example. It's a simplified code, written just to serve as example.
std::vector<int> expensiveFun(int x, int a, int b, int c) {
std::vector<int> out(x+1);
out[0] = a+b*c;
for (int i = 1; i <= x; i++)
out[i] = out[i-1] * i + a * (b+c);
return out;
}
std::vector<int> mainFun(
std::vector<int> x,
std::vector<int> a,
std::vector<int> b,
std::vector<int> c
) {
int n = x.size();
int a_size = a.size();
int b_size = b.size();
int c_size = c.size();
std::vector<int> out(n);
// easy
if (a_size == b_size && b_size == a_size) {
int max_x = 0;
for (int j = 0; j < n; j++)
if (x[j] > max_x)
max_x = x[j];
for (int i = 0; i < a_size; i++) {
int max_x = 0;
for (int j = 0; j < n; j += a_size) {
if (x[j] > max_x)
max_x = x[j];
}
std::vector<int> precomputedValues = expensiveFun(max_x, a[i], b[i], c[i]);
for (int j = i; j < n; j += a_size) {
out[j] = precomputedValues[x[j]];
}
}
// otherwise give up
} else {
for (int j = 0; j < n; j++) {
out[j] = expensiveFun(x[j], a[j % a_size], c[j % c_size], c[j % c_size]).back();
}
}
return out;
}
Example input:
x = {0, 1, 5, 3, 2, 1, 0, 4, 4, 2, 3, 4, 1}
a = {1, 2, 3}
b = {1, 2}
c = {3, 4, 5, 6}
Parameters should be folded so that they become:
x = {0, 1, 5, 3, 2, 1, 0, 4, 4, 2, 3, 4, 1}
a = {1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1}
b = {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1}
c = {3, 4, 5, 6, 3, 4, 5, 6, 3, 4, 5, 6, 3}
The output is not important at the moment since the main issue in here is about efficiently dealing with varying-size parameter vectors.

Memoize your function.
Once you compute a vector for a combination of a, b, and c, store it in an std::unordered_map. The next time you see the same combination, you retrieve the vector that you have already computed - the classic approach of paying with computer memory for computation speed-up.
std::map<std::tuple<int,int,int>,std::vector<int>> memo;
int expensiveFunMemo(int x, int xMax, int a, int b, int c) {
assert(x <= xMax);
std::vector<int>& out = memo[std::make_tuple(a, b, c)];
if (!out.size()) {
out.push_back(a+b*c);
for (int i = 1; i <= xMax; i++)
out.push_back(out[i-1] * i + a * (b+c));
}
assert(out.size == xMax+1);
return out[x];
}
This way you would never compute expensiveFunMemo for any combination of {a, b, c} more than once.
Your mainFun becomes simpler, too:
std::vector<int> mainFun(
const std::vector<int>& x,
const std::vector<int>& a,
const std::vector<int>& b,
const std::vector<int>& c
) {
size_t n = x.size();
size_t a_size = a.size();
size_t b_size = b.size();
size_t c_size = c.size();
std::vector<int> out(n);
int xMax = *std::max_element(x.begin(), x.end());
for (size_t j = 0 ; j < n ; j++) {
out[j] = expensiveFunMemo(x[j], xMax, a[j % a_size], c[j % c_size], c[j % c_size]);
}
return out;
}
Note: this solution uses std::map<K,V> instead of std::unordered_map<K,V> because std::tuple<...> lacks a generic hash function. This Q&A offers a solution to fix this problem.

Related

what is the purpose of passing -1 in add function?

I am currently programming a Strassen multiplication program in CPP using vectors. I just want to know why at some function add -1 are passed and at some add function call, -1 is not passed. what is the use purpose of passing -1 in function? if I remove that -1 from the calls I got a different incorrect output.
// Strassen’s Matrix Multiplication
#include <bits/stdc++.h>
using namespace std;
// Size of two matrices
#define ROW_1 4
#define COL_1 4
#define ROW_2 4
#define COL_2 4
// print the matrix
void print(vector<vector<int> > matrix) {
for(int i = 0; i < matrix.size(); i++){
for(int j = 0; j < matrix[i].size(); j++){
cout << matrix[i][j] << ' ';
}
cout << endl;
}
}
// Add two matrices and return the result
vector<vector<int>> add(vector<vector<int> > A, vector<vector<int> > B, int split_index, int multiplier = 1) {
for (auto i = 0; i < split_index; i++)
for (auto j = 0; j < split_index; j++)
A[i][j] = A[i][j] + (multiplier * B[i][j]);
return A;
}
vector<vector<int>> strassen_multiplication(vector<vector<int> > A, vector<vector<int> > B) {
// calculating the size of matrix
int row_1 = A.size();
int col_1 = A[0].size();
int row_2 = B.size();
int col_2 = B[0].size();
// checking if multiplication is possible or not
// between the input matrices
if (col_1 != row_2) {
cout << "The Two Matrices cannot be multiplied";
return {};
}
// creating an empty matrix to store the result
vector<int> result_row(col_2, 0);
vector<vector<int> > result(row_1, result_row);
// Base case
// if size of matrix is 1
if (col_1 == 1)
result[0][0]
= A[0][0] * B[0][0];
else {
// split index
int split_index = col_1 / 2;
vector<int> row_vector(split_index, 0);
// Splitting the matrices in sub matrices
vector<vector<int> > a00(split_index, row_vector);
vector<vector<int> > a01(split_index, row_vector);
vector<vector<int> > a10(split_index, row_vector);
vector<vector<int> > a11(split_index, row_vector);
vector<vector<int> > b00(split_index, row_vector);
vector<vector<int> > b01(split_index, row_vector);
vector<vector<int> > b10(split_index, row_vector);
vector<vector<int> > b11(split_index, row_vector);
// calculating and storing the result
// inside our quadrants
for (auto i = 0; i < split_index; i++)
for (auto j = 0; j < split_index; j++) {
a00[i][j] = A[i][j];
a01[i][j] = A[i][j + split_index];
a10[i][j] = A[split_index + i][j];
a11[i][j] = A[i + split_index]
[j + split_index];
b00[i][j] = B[i][j];
b01[i][j] = B[i][j + split_index];
b10[i][j] = B[split_index + i][j];
b11[i][j] = B[i + split_index]
[j + split_index];
}
// Calculating the multiplication using the formula
// given by strassent algorithm
vector<vector<int>> p1(strassen_multiplication(a00, add(b01, b11, split_index, -1)));
vector<vector<int>> p2(strassen_multiplication(add(a00, a01, split_index), b11));
vector<vector<int>> p3(strassen_multiplication(add(a10, a11, split_index), b00));
vector<vector<int>> p4(strassen_multiplication(a11, add(b10, b00, split_index, -1)));
vector<vector<int>> p5(strassen_multiplication(add(a00, a11, split_index),add(b00, b11, split_index)));
vector<vector<int>> p6(strassen_multiplication(add(a01, a11, split_index, -1),add(b10, b11, split_index)));
vector<vector<int>> p7(strassen_multiplication(add(a00, a10, split_index, -1),add(b00, b01, split_index)));
// calculating the result
vector<vector<int> > result_00(add(add(add(p5, p4, split_index), p6, split_index), p2, split_index, -1));
vector<vector<int> > result_01(add(p1, p2, split_index));
vector<vector<int> > result_10(add(p3, p4, split_index));
vector<vector<int> > result_11(add(add(add(p5, p1, split_index), p3, split_index, -1), p7, split_index, -1));
// calulating and storing the result
// inside matrix
for (auto i = 0; i < split_index; i++){
for (auto j = 0; j < split_index; j++) {
result[i][j] = result_00[i][j];
result[i][j + split_index] = result_01[i][j];
result[split_index + i][j] = result_10[i][j];
result[i + split_index][j + split_index] = result_11[i][j];
}
}
// clearing all the arrays
a00.clear(); a01.clear(); a10.clear(); a11.clear();
b00.clear(); b01.clear(); b10.clear(); b11.clear();
p1.clear(); p2.clear(); p3.clear(); p4.clear(); p5.clear(); p6.clear(); p7.clear();
result_00.clear(); result_01.clear(); result_10.clear(); result_11.clear();
}
return result;
}
int main()
{
// Input Matrix A
vector<vector<int>> A = {{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}};
// Input Matrix B
vector<vector<int>> B = {{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1},{1, 1, 1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1, 1, 1}};
// Getting the result
vector<vector<int> > result(strassen_multiplication(A, B));
// Printing the result
print(result);
}
If you take a moment to read the add function, you will discover the fourth parameter is named multiplier and has a default value of 1. It is a good name for a variable, because it describes clearly what it will be used for.
Continuing to read the function, you will see that multiplier is used to scale B during addition. Logically, that means if you pass -1 as a multiplier, then the operation becomes a subtraction instead of an addition.
What seems strange to me is that you say you are programming this. One would expect that means the code is yours. So you should understand what it does and why. I guess the code is not yours.
You could make the code a bit clearer if you do this:
// Add two matrices and return the result
vector<vector<int>> add_scaled(
vector<vector<int>> A,
const vector<vector<int>>& B,
int split_index,
int multiplier)
{
for (auto i = 0; i < split_index; i++)
for (auto j = 0; j < split_index; j++)
A[i][j] = A[i][j] + (multiplier * B[i][j]);
return A;
}
vector<vector<int>> add(
vector<vector<int>> A,
const vector<vector<int>>& B,
int split_index)
{
return add_scaled(A, B, split_index, 1);
}
vector<vector<int>> subtract(
vector<vector<int>> A,
const vector<vector<int>>& B,
int split_index)
{
return add_scaled(A, B, split_index, -1);
}
This turns your original add function into add_scaled, and creates two simpler functions add and subtract which do not do any scaling. Then you have:
vector<vector<int>> p1(strassen_multiplication(a00, subtract(b01, b11, split_index)));
vector<vector<int>> p2(strassen_multiplication(add(a00, a01, split_index), b11));
vector<vector<int>> p3(strassen_multiplication(add(a10, a11, split_index), b00));
vector<vector<int>> p4(strassen_multiplication(a11, subtract(b10, b00, split_index)));
// etc...

LeetCode 417 solution in C++. I'm getting a heap buffer overflow error

I'm working through this problem: https://leetcode.com/problems/pacific-atlantic-water-flow/
After battling through my own solution for several hours, I ended up not being able to fully solve it, so I'm tracing through how others did it. My new code is based on this: https://leetcode.com/problems/pacific-atlantic-water-flow/discuss/608490/C%2B%2B-Implementation-(DFS)
It's basically the same, except I made it more verbose, and I added some comments for clarity. Even though the code is virtually the same, I'm getting a heap overflow error for very large inputs. I'm not sure what's causing it, but I'm guessing that I'm not correctly passing references to vectors and end up making copies in memory. Can someone please help me figure out the inefficiency?
#include <vector>
#include <assert.h>
using namespace std;
bool isOutOfBounds(int row, int col, vector<vector<int>>& matrix) {
bool rowOutOfBound = row < 0 || row == matrix.size();
bool colOutOfBound = col < 0 || col == matrix[0].size();
return rowOutOfBound || colOutOfBound;
}
void explore(vector<vector<int>>& matrix, int i, int j, int prevHeight, vector<vector<bool>>& explored) {
// if we are out of bounds, or our height is greater, or if this cell was already explored
if (isOutOfBounds(i, j, matrix) || matrix[i][j] < prevHeight || explored[i][j]) return;
int height = matrix[i][j];
explored[i][j] = true;
explore(matrix, i - 1, j, height, explored); // flow up
explore(matrix, i, j + 1, height, explored); // flow right
explore(matrix, i + 1, j, height, explored); // flow down
explore(matrix, i, j - 1, height, explored); // flow left
}
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
vector<vector<int>> result;
if (matrix.size() == 0) return result;
// create boolean grids of explored paths, one for pacific, one for atlantic
vector<vector<bool>> pacific(matrix.size(), vector<bool>(matrix[0].size(), false));
vector<vector<bool>> atlantic(pacific);
for (int i = 0; i < matrix.size(); i++) {
explore(matrix, i, 0, INT_MIN, pacific); // explore first column
explore(matrix, i, matrix.size() - 1, INT_MIN, atlantic); // explore last column
}
for (int j = 0; j < matrix[0].size(); j++) {
explore(matrix, 0, j, INT_MIN, pacific); // explore first row
explore(matrix, matrix[j].size() - 1, j, INT_MIN, atlantic); // explore last row
}
// for every column of each row
for (int i = 0; i < matrix.size(); i++) {
for (int j = 0; j < matrix[i].size(); j++) {
if (pacific[i][j] && atlantic[i][j]) {
result.push_back({ i, j });
}
}
}
return result;
}
void main() {
vector<vector<int>> matrix {
{ 1, 2, 2, 3, 5 },
{ 3, 2, 3, 4, 4 },
{ 2, 4, 5, 3, 1 },
{ 6, 7, 1, 4, 5 },
{ 5, 1, 1, 2, 4 }
};
vector<vector<int>> expected{ {0, 4}, {1, 3}, {1, 4}, {2, 2}, {3, 0}, {3, 1}, {4, 0} };
vector<vector<int>> result = pacificAtlantic(matrix);
assert(result == expected);
}
I had an error when exploring last column, and last row, so was accessing invalid vector indexes.
when I fixed
for (int i = 0; i < matrix.size(); i++) {
explore(matrix, i, 0, INT_MIN, pacific); // explore first column
explore(matrix, i, matrix.size() - 1, INT_MIN, atlantic); // explore last column
}
for (int j = 0; j < matrix[0].size(); j++) {
explore(matrix, 0, j, INT_MIN, pacific); // explore first row
explore(matrix, matrix[j].size() - 1, j, INT_MIN, atlantic); // explore last row
}
the solution worked.
The code should have read as:
for (int i = 0; i < matrix.size(); i++) {
explore(matrix, i, 0, INT_MIN, pacific); // explore first column
explore(matrix, i, matrix[0].size() - 1, INT_MIN, atlantic); // explore last column
}
for (int j = 0; j < matrix[0].size(); j++) {
explore(matrix, 0, j, INT_MIN, pacific); // explore first row
explore(matrix, matrix.size() - 1, j, INT_MIN, atlantic); // explore last row
}

Algorithms - Circular Array Rotation

Is this linear complexity implementation of circular array rotation correct?
n = number of elements
k = number of rotations
int write_to = 0;
int copy_current = 0;
int copy_final = a[0];
int rotation = k;
int position = 0;
for (int i = 0; i < n; i++) {
write_to = (position + rotation) % n;
copy_current = a[write_to];
a[write_to] = copy_final;
position = write_to;
copy_final = copy_current;
}
No.
Consider this example.
#include <iostream>
int main(void) {
int n = 6;
int k = 2;
int a[] = {1, 2, 3, 4, 5, 6};
int write_to = 0;
int copy_current = 0;
int copy_final = a[0];
int rotation = k;
int position = 0;
for (int i = 0; i < n; i++) {
write_to = (position + rotation) % n;
copy_current = a[write_to];
a[write_to] = copy_final;
position = write_to;
copy_final = copy_current;
}
for (int i = 0; i < n; i++) {
std::cout << a[i] << (i + 1 < n ? ' ' : '\n');
}
return 0;
}
Expected result:
5 6 1 2 3 4
Actual result:
3 2 1 4 1 6
Using stl::rotate on std::array, you can left rotate by, say 2, as:
std::array<int, 6> a{1, 2, 3, 4, 5, 6};
std::rotate(begin(a), begin(a) + 2, end(a)); // left rotate by 2
to yield: 3 4 5 6 1 2, or right-rotate by, say 2, as:
std::rotate(begin(a), end(a) - 2, end(a)); // right rotate by 2
to yield: 5 6 1 2 3 4, with linear complexity.
Rotate an Array of length n for k times in left or right directions.
The code is in Java
I define a Direction Enum:
public enum Direction {
L, R
};
Rotation with times and direction:
public static final void rotate(int[] arr, int times, Direction direction) {
if (arr == null || times < 0) {
throw new IllegalArgumentException("The array must be non-null and the order must be non-negative");
}
int offset = arr.length - times % arr.length;
if (offset > 0) {
int[] copy = arr.clone();
for (int i = 0; i < arr.length; ++i) {
int j = (i + offset) % arr.length;
if (Direction.R.equals(direction)) {
arr[i] = copy[j];
} else {
arr[j] = copy[i];
}
}
}
}
Complexity: O(n).
Example:
Input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Rotate 3 times left
Output: [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]
Input: [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]
Rotate 3 times right
Output: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Mixing two arrays by alternating elements two by two

What is an elegant algorithm to mix the elements two by two in two arrays (of potentially differing sizes) so that the items are drawn in an alternating fashion from each array, with the leftovers added to the end?
E.g.
Array 1: 0, 2, 4, 6
Array 2: 1, 3, 5, 7
Mixed array: 0, 2, 1, 3, 4, 6, 5, 7
Don't worry about null checking or any other edge cases, I'll handle those.
Here is my solution but it does not work properly:
for (i = 0; i < N; i++) {
arr[2 * i + 0] = A[i];
arr[2 * i + 1] = A[i+1];
arr[2 * i + 0] = B[i];
arr[2 * i + 1] = B[i+1];
}
It is very fiddly to calculate the array indices explicitly, especially if your arrays can be of different and possibly odd lengths. It is easier if you keep three separate indices, one for each array:
int pairwise(int c[], const int a[], size_t alen, const int b[], size_t blen)
{
size_t i = 0; // index into a
size_t j = 0; // index into b
size_t k = 0; // index into c
while (i < alen || j < blen) {
if (i < alen) c[k++] = a[i++];
if (i < alen) c[k++] = a[i++];
if (j < blen) c[k++] = b[j++];
if (j < blen) c[k++] = b[j++];
}
return k;
}
The returned value k will be equal to alen + blen, which is the implicit dimension of the result array c. Because the availability of a next item is checked for each array operation, this code works for arrays of different lengths and when the arrays have an odd number of elements.
You can use the code like this:
#define countof(x) (sizeof(x) / sizeof(*x))
int main()
{
int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
int b[] = {-1, -2, -3, -4, -5, -6};
int c[countof(a) + countof(b)];
int i, n;
n = pairwise(c, a, countof(a), b, countof(b));
for (i = 0; i < n; i++) {
if (i) printf(", ");
printf("%d", c[i]);
}
puts("");
return 0;
}
(The example is in C, not C++, but your code doesn't use any of C++'s containers such as vector, so I've uses plain old ´int` arrays with explicit dimensions, which are the same in C and C++.)
Some notes on the loop you have;
You use the same position in the result array arr to assign two values to it (one from A and one from B).
The calculation for the index is possibly more complex than it needs to be, consider using two indexers given the two ways you are indexing over the arrays.
I would propose you use a loop that has two indexers (i and j) and explicitly loop over the four elements of the result (i.e. two position for each input array). In each loop you increment the indexers appropriately (by 4 for the output array and by 2 for the input arrays).
#include <iostream>
int main()
{
using namespace std;
constexpr int N = 4;
int A[N] = {2, 4, 6, 8};
int B[N] = {1, 3, 5, 7};
int arr[N*2];
for (auto i = 0, j=0; i < N*2; i+=4, j+=2) {
arr[i + 0] = A[j];
arr[i + 1] = A[j+1];
arr[i + 2] = B[j];
arr[i + 3] = B[j+1];
}
for (auto i =0; i < N*2; ++i) {
cout << arr[i] << ",";
}
cout << endl;
}
Note: you mention you take care of corner cases, so the code here requires the input arrays to be of the same length and that the length is even.
Try this:
for (i = 0; i < N; i += 2) {
arr[2 * i + 0] = A[i];
arr[2 * i + 1] = A[i+1];
arr[2 * i + 2] = B[i];
arr[2 * i + 3] = B[i+1];
}
Didn't consider any corner case, just fixing your concept. For example, check whether any array index out of bound occurs or not. You can run live here.
it should like this.
for (i = 0; i < N; i+=2) {
arr[2 * i + 0] = A[i];
arr[2 * i + 1] = A[i+1];
arr[2 * i + 2] = B[i];
arr[2 * i + 3] = B[i+1];
}

C++ Chocolate Puzzle [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
Let's say I have N chocolates that have to be packed into exactly P boxes in the order they arrive. Each chocolate also has a number of calories X and each box has a capacity K which has to be less than or equal to 3*sum(x1, x2, ..., xn) + max(x1, x2, ..., xn)^2 - min(x1, x2, ..., xn)^2.
In the task I'm given N, P and X for each chocolate and I have to figure out the lowest possible K. Could anyone help me on this (not looking for a solution just for some hints regarding the problem)?
Example:
N = 8,
P = 3,
X = {1, 4, 5, 6, 3, 2, 5, 3}
K for first three chocolates = 3*(1+4+5) + 5^2 - 1^2 = 54
K for next two chocolates = 3*(6+3) + 6^2 - 3^2 = 54
K for last three chocolates = 3*(2+5+3) + 5^2 - 2^2 = 51
Lowest possible K = 54
So the goal is to find the best combination using exactly P boxes that has the lowest K.
Thanks!
Here is how I would solve this in Java:
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class ChocolatePuzzle {
private static final Map <String, Integer> solutions =
new HashMap <String, Integer> ();
private static final Map <String, Integer> bestMoves =
new HashMap <String, Integer> ();
private static int [] x;
private static int k (int from, int to)
{
int sum = x [from];
int max = x [from];
int min = x [from];
for (int i = from + 1; i < to; i++)
{
sum += x [i];
max = Math.max (max, x [i]);
min = Math.min (min, x [i]);
}
return sum * 3 + max * max - min * min;
}
public static int solve (int n, int p)
{
String signature = n + "," + p;
Integer solution = solutions.get (signature);
if (solution == null)
{
solution = Integer.valueOf (doSolve (n, p, signature));
solutions.put (signature, solution);
}
return solution.intValue ();
}
public static int doSolve (int n, int p, String signature)
{
if (p == 1)
{
bestMoves.put (signature, Integer.valueOf (x.length - n));
return k (n, x.length);
}
else
{
int result = Integer.MAX_VALUE;
int bestMove = 0;
int maxI = x.length - n - p + 1;
for (int i = 1; i <= maxI; i++)
{
int k = Math.max (k (n, n + i), solve (n + i, p - 1));
if (k < result)
{
result = k;
bestMove = i;
}
}
bestMoves.put (signature, Integer.valueOf (bestMove));
return result;
}
}
public static void main(String[] args) {
int n = 20;
int p = 5;
x = new int [n];
Random r = new Random ();
for (int i = 0; i < n; i++)
x [i] = r.nextInt (9) + 1;
System.out.println("N: " + n);
System.out.println("P: " + p);
System.out.print("X: {");
for (int i = 0; i < n; i++)
{
if (i > 0) System.out.print (", ");
System.out.print (x [i]);
}
System.out.println("}");
System.out.println();
int k = solve (0, p);
int o = 0;
for (int i = p; i > 0; i--)
{
int m = bestMoves.get (o + "," + i);
System.out.print ("{");
for (int j = 0; j < m; j++)
{
if (j > 0)
System.out.print (", ");
System.out.print (x [o + j]);
}
System.out.print ("} (k: ");
System.out.print(k (o, o + m));
System.out.println (")");
o += m;
}
System.out.println("min(k): " + k);
}
}
Probably you could find some useful tips in this code.
Sample input:
N: 20
P: 5
X: {1, 7, 6, 6, 5, 5, 7, 9, 1, 3, 9, 5, 3, 7, 9, 1, 4, 2, 4, 8}
Sample output:
{1, 7, 6, 6} (k: 108)
{5, 5, 7, 9} (k: 134)
{1, 3, 9, 5} (k: 134)
{3, 7, 9} (k: 129)
{1, 4, 2, 4, 8} (k: 120)
min(k): 134