Advertisement
ThegeekKnight16

Karen and Supermarket

May 31st, 2023
1,026
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.13 KB | None | 0 0
  1. /*
  2.     Ideia 1:
  3.     Vou criar uma lista de adjacencia no i, indicando quem que depende
  4.     do i. O grafo formado tera a forma de arvore, ja que cada vertice tirando o
  5.     1 tera um pai que eh menor do que ele.
  6.     Nesta arvore, poderei utilizar um cupom se, e somente se, eu tiver utilizado os cupons
  7.     de seus ancestrais.
  8.  
  9.     dp[i][k][f]: para o item i, qual o maior numero
  10.     de itens que posso comprar usando k de dinheiro,
  11.     sendo que se f eh 0 n posso usar o cupom e se f eh
  12.     1 posso usar o cupom
  13.     Para calcular a dp, calcularemos, em cada vertice, uma dp2[filhos][k][f]
  14.     dp2[filho_i][k][f] = max(dp2[filho_i-1][k - x][f] + dp[filho_i][x][f])   -> Complexidade: O(N*B²)
  15.     dp[i][k][0] = max(dp2[ultFilho][k][0], dp2[ultFilho][k - c[i]][0] + 1)   -> Complexidade: O(B)
  16.     dp[i][k][1] = max(dp[i][k][0], dp2[ultFilho][k - c[i] + d[i]][1] + 1)    -> Complexidade: O(B)
  17.  
  18.     Resposta: max(dp[1][B][0], dp[1][B][1])
  19.  
  20.     Ideia 2:
  21.     dp[i][t][f]: para o item i, qual o menor preco que tenho que pagar
  22.     se quiser comprar t itens, sendo que se f eh 0 n posso usar cupom e
  23.     se f eh 1 posso usar cupom
  24.  
  25.     Novamente, calcular uma dp2[filhos][t][f]
  26.     dp2[filho_i][t][f] = min(dp2[filho_i-1][t-x][f] + dp[filho_i][x][f])    -> Complexidade: O(N³) -> usa o truque do sub -> O(N²)
  27.     dp[i][t][0] = min(dp2[ultFilho][t][0], dp2[ultFilho][t-1][0] + c[i])    -> Complexidade: O(N)
  28.     dp[i][t][1] = min(dp[i][t][0], dp2[ultFilho][t-1][1] + c[i] - d[i])     -> Complexidade: O(N)
  29.  
  30.     Complexidade: O(N³) (Mais facil), O(N²) (Com o truque)
  31.     Resposta: Maximo t t.q. dp[1][t][1] <= B
  32. */
  33. #include <bits/stdc++.h>
  34. using namespace std;
  35. #define int long long
  36. const int MAXN = 5e3 + 10;
  37. const int INF = 0x3f3f3f3f3f3f3f3f;
  38.  
  39. int dp[MAXN][MAXN][2];
  40. array<vector<int>, MAXN> grafo;
  41. array<int, MAXN> c, d, tmp0, tmp1, sub;
  42. int N, B;
  43.  
  44. void dfs(int v)
  45. {
  46.     sub[v] = 0;
  47.     for (int i = 1; i <= N; i++) dp[v][i][0] = dp[v][i][1] = INF;
  48.  
  49.     for (auto viz : grafo[v])
  50.     {
  51.         dfs(viz);
  52.  
  53.         tmp0.fill(INF); tmp1.fill(INF);
  54.         for (int i = 0; i <= min(N, sub[v]); i++)
  55.         {
  56.             for (int j = 0; j <= min(N, sub[viz]) && i + j <= N; j++)
  57.             {
  58.                 tmp0[i+j] = min(tmp0[i+j], dp[v][i][0] + dp[viz][j][0]);
  59.                 tmp1[i+j] = min(tmp1[i+j], dp[v][i][1] + dp[viz][j][1]);
  60.             }
  61.         }
  62.         sub[v] += sub[viz];
  63.  
  64.         for (int i = 0; i <= min(N, sub[v]); i++)
  65.         {
  66.             dp[v][i][0] = tmp0[i];
  67.             dp[v][i][1] = tmp1[i];
  68.         }
  69.     }
  70.     ++sub[v];
  71.     for (int i = N; i >= 1; i--)
  72.     {
  73.         dp[v][i][0] = min(dp[v][i][0], dp[v][i-1][0] + c[v]);
  74.         dp[v][i][1] = min(dp[v][i][0], dp[v][i-1][1] + c[v] - d[v]);
  75.     }
  76. }
  77.  
  78. int32_t main()
  79. {
  80.     ios_base::sync_with_stdio(false);
  81.     cin.tie(NULL);
  82.     cin >> N >> B;
  83.     for (int i = 1; i <= N; i++)
  84.     {
  85.         cin >> c[i] >> d[i];
  86.         if (i != 1)
  87.         {
  88.             int X;
  89.             cin >> X;
  90.             grafo[X].push_back(i);
  91.         }
  92.     }
  93.     dfs(1);
  94.  
  95.     for (int i = N; i >= 0; i--) if (dp[1][i][1] <= B) {cout << i << '\n'; break;}
  96. }
  97.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement