Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
- //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,tune=native")
- #include <iostream>
- #include <cmath>
- #include <vector>
- #include <algorithm>
- #include <map>
- #include <set>
- #include <bitset>
- #define MAX_INT 2147483647
- #define ll long long
- using namespace std;
- vector<int> coins, change, costs;
- set<int> S_coins, S_change;
- template <size_t N>
- void increment ( std::bitset<N>& in ) {
- for ( size_t i = 0; i < N; ++i ) {
- if ( in[i] == 0 ) {
- in[i] = 1;
- break;
- }
- in[i] = 0;
- }
- }
- void parse_digits(const string& str, int i,int j, vector<int>& vec){
- string value;
- for(;i < j; ++i){
- if(str[i] == ','){
- vec.push_back(stoi(value));
- value = "";
- continue;
- }
- value.push_back(str[i]);
- }
- vec.push_back(stoi(value));
- }
- void parse(const string& str){
- vector<int> left_bracket_idx, right_bracket_idx;
- for(int i = 0; i < str.size(); ++i){
- if(str[i] == '['){
- left_bracket_idx.push_back(i);
- }
- if(str[i] == ']'){
- right_bracket_idx.push_back(i);
- }
- }
- parse_digits(str,left_bracket_idx[0]+1,right_bracket_idx[0],coins);
- parse_digits(str,left_bracket_idx[1]+1,right_bracket_idx[1],change);
- parse_digits(str,left_bracket_idx[2]+1,right_bracket_idx[2],costs);
- }
- template<size_t N>
- long long can_afford(const bitset<N>& b){
- long long sum = 0;
- for(int i = 0; i < min(N,costs.size()); ++i){
- if(b[i] == 1){
- sum += costs[i];
- }
- }
- for( auto it = S_coins.lower_bound(sum); it != S_coins.end(); ++it){
- if(S_change.find(*it-sum) != S_change.end()){
- return sum;
- }
- }
- return -1;
- }
- void generate_combinations(vector<int>& vec, set<int>& S){
- bitset<20> b(1);
- for(int i = 1; i < (1 << vec.size()); ++i){
- ll sum = 0;
- for(int j = 0; j < min(vec.size(),(size_t)20); ++j){
- if(b[j] == 1){
- sum += vec[j];
- }
- }
- S.insert(sum);
- increment(b);
- }
- }
- int main() {
- string input;
- getline(cin,input);
- parse(input);
- generate_combinations(change,S_change);
- generate_combinations(coins,S_coins);
- S_change.insert(0);
- long long min_sum = INT32_MAX;
- int amount = 0;
- bitset<20> b(1);
- for(int i = 1; i < (1 << costs.size()); ++i){
- auto ret = can_afford(b);
- if(ret != -1){
- int t = __builtin_popcountll(i);
- if(__builtin_popcountll(i) == amount && ret < min_sum){
- min_sum = ret;
- }
- if(__builtin_popcountll(i) > amount){
- amount = __builtin_popcountll(i);
- min_sum = ret;
- }
- }
- increment(b);
- }
- cout << min_sum << '\n';
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement