The usual phrase for this is that you are looking for the value closest to, but not exceeding K. If you mean "less than K", it means that your K value is greater than usual. If you really mean just “not equal to K,” then you basically run the algorithm twice as soon as you find the largest amount less than K, then again find the smallest amount greater than K, then choose one that is completely different from K is the smallest.
At the moment, I'm going to assume that you really mean the largest amount, less than or equal to K, since the most common wording and other features do not really have a big impact on the algorithm.
, ( ) . K + 1 N + 1 ( N = ). 0.
, , , , , , . : , , ( , ).
, . Boolean true , , ( ). - , . , Boolean true, , , . , , , , .
++, C, .
#include <iostream>
#include <functional>
#define elements(array) (sizeof(array)/sizeof(array[0]))
int main() {
int v[] = {0, 7, 15, 2, 1};
const int MAX = 17;
const int K = MAX + 1;
const int rows = elements(v);
int table[rows][K] = {0};
bool used[rows][K] = {false};
for (int i=1; i<rows; i++)
for (int c = 0; c<K; c++) {
int prev_val = table[i-1][c];
int new_val;
if (v[i] <= c && (new_val=v[i]+table[i-1][c-v[i]]) > prev_val) {
table[i][c] = new_val;
used[i][c] = true;
}
else
table[i][c] = prev_val;
}
std::cout << "Result: " << table[rows-1][MAX] << "\n";
std::cout << "Used items where:\n";
int column = MAX;
for (int i=rows; i>-1; i--)
if (used[i][column]) {
std::cout << "\tv[" << i << "] = " << v[i] << "\n";
column -= v[i];
}
return 0;
}
, ( ). -, , , , 1 ( 15 2 17).
-, : . ( ) (.. [n] row[n-1], row[n-2], row[n-3],... row[0]. , , . , C, , , d table[i] table[i-1] table[i&1] table[(i-1)&1] ( - used.