Skip to content

Instantly share code, notes, and snippets.

@matklad
Last active October 14, 2016 15:16
Show Gist options
  • Save matklad/7ce9a06cbaeb4ae6166ee7b0cd4f6432 to your computer and use it in GitHub Desktop.
Save matklad/7ce9a06cbaeb4ae6166ee7b0cd4f6432 to your computer and use it in GitHub Desktop.
int upper = 0;
for (int i = 0; i < (1 << n); i++) {
if (i == 2^{upper+1}) upper++;
function[i] = function[i ^ (1 << upper)] и что-нибудь ещё.
}
Число единичных бит можно так: f[i] = f[i >> 1] + (i & 1);
Сумма элементов: f[i] = f[i ^ (1 << upper)] + weight[upper]
#include <bitset>
#include <cassert>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <vector>
void f(size_t idx, // Loop counter
size_t set, int32_t sum, // Accumulators
// Environment
std::vector<int32_t> const &items, std::vector<int32_t> &result) {
if (idx == items.size()) {
assert(result[set] == 0);
result[set] = sum;
return;
}
assert(idx < items.size());
// 1) We pick next item and update accumulators.
f(idx + 1, set | (1 << idx), sum + items[idx], items, result);
// 2) We don't pick the item, accumulators stay intact.
f(idx + 1, set, sum, items, result);
}
std::vector<int32_t> sums_of_subsets(std::vector<int32_t> const &items) {
size_t n = 1 << items.size();
std::vector<int32_t> result(n, 0);
f(0, 0, 0, items, result);
return result;
}
int main() {
std::vector<int32_t> items = {1, 2, 5, 10};
auto sums = sums_of_subsets(items);
for (size_t i = 0; i < sums.size(); ++i) {
std::cout << std::setw(2);
std::cout << i << " " << std::bitset<3>(i) << " " << sums[i] << "\n";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment