Advertisement
ThegeekKnight16

Nova Moeda

Sep 6th, 2024
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.82 KB | None | 0 0
  1. /*
  2.     Sao varios brutes, um para cada tarefa do problema.
  3.     O codigo roda em uns 21 segundos (na minha maquina) e tem a seguinte saida:
  4.  
  5.     nova moeda: 18, soma: 319
  6.     ---------//--------------
  7.     novas moedas: 8 37, soma: 281
  8.     -----------//--------------
  9.     novo conjunto: 1 5 16 23 33 soma: 333
  10. */
  11. #include <bits/stdc++.h>
  12. using namespace std;
  13. #define int long long
  14.  
  15. //Funcao para calcular, dado um conjunto de moedas, qual a soma das quantidades de moedas necessarias para formar cada valor
  16. //Eh um knapsack O(#moedas * #valores)
  17. int calcSum(const vector<int> &moedas)
  18. {
  19.     vector<int> dp(101, (int)1e9); dp[0] = 0;
  20.     for (int x = 1; x <= 100; x++)
  21.         for (auto moeda : moedas)
  22.             if (moeda <= x)
  23.                 dp[x] = min(dp[x], dp[x-moeda]+1);
  24.     return accumulate(dp.begin(), dp.end(), 0LL);
  25. }
  26.  
  27. void bt(int id, vector<int> &conj, vector<int> &atual, int m, int &resp)
  28. {
  29.     if (id == 5)
  30.     {
  31.         int soma = calcSum(atual);
  32.         if (soma < resp) resp = soma, conj = atual;
  33.         return;
  34.     }
  35.     if (m > 100) return;
  36.  
  37.     for (int x = m; x <= 100; x++)
  38.     {
  39.         atual.push_back(x);
  40.         bt(id+1, conj, atual, x+1, resp);
  41.         atual.pop_back();
  42.     }
  43. }
  44.  
  45. int32_t main()
  46. {
  47.     ios_base::sync_with_stdio(false);
  48.     cin.tie(NULL);
  49.     vector<int> moedas = {1, 5, 10, 25, 50, 100};
  50.     int resp = (int)1e9;
  51.     int nova = 0;
  52.     //Acha a moeda que, junto as outras, miniza a soma total
  53.     //So um brute. O(#valores * knapsack)
  54.     for (int i = 1; i <= 100; i++)
  55.     {
  56.         moedas.push_back(i);
  57.         int soma = calcSum(moedas);
  58.         if (soma < resp) nova = i, resp = soma;
  59.         moedas.pop_back();
  60.     }
  61.     cout << "nova moeda: " << nova << ", soma: " << resp << '\n';
  62.  
  63.     cout << "---------//--------------" << '\n';
  64.     //Acha o par de moedas que miniza a soma total
  65.     //Mesma coisa que o problema de uma moeda, mas com duas. O(#valores^2 * knapsack)
  66.     resp = (int)1e9; pair<int, int> novas = {0,0};
  67.     for (int i = 1; i <= 100; i++)
  68.     {
  69.         moedas.push_back(i);
  70.         for (int j = i+1; j <= 100; j++)
  71.         {
  72.             moedas.push_back(j);
  73.             int soma = calcSum(moedas);
  74.             if (soma < resp) novas = make_pair(i, j), resp = soma;
  75.             moedas.pop_back();
  76.         }
  77.         moedas.pop_back();
  78.     }
  79.     cout << "novas moedas: " << novas.first << " " << novas.second << ", soma: " << resp << '\n';
  80.  
  81.     cout << "-----------//--------------" << '\n';
  82.     vector<int> conj = {1}, atual = {1}; resp = (int)1e9;
  83.     //Acha o conjunto de 5 moedas que tem menor soma. Precisa ter 1, ent sempre esta no grupo
  84.     //Uma backtrack. O(escolhe(99, 4) * knapsack)
  85.     bt(1, conj, atual, 2, resp);
  86.     cout << "novo conjunto: "; for (auto x : conj) cout << x << " "; cout << "soma: " << resp << '\n';
  87. }
  88.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement