Solução escrita por Caique Paiva
Conhecimento prévio necessário:
- Bitmask DP
Vamos fazer uma dp! A ideia é calcular para cada subconjunto de pessoa dois valores: O número mínimo de subidas no elevador e o peso mínimo do último grupo. Podemos representar cada conjunto por uma bitmask. Portanto, a dp seria
Onde . Agora, a transição seria o seguinte:
- Dada uma bitmask , vamos percorrer todos os elementos de até (Estamos fazendo os valores serem indexados). Seja o elemento que estamos agora
- Se , ou seja, se , então, suponha que já calculamos a resposta para , logo, seja uma variável auxiliar, então, temos duas possibilidades.
- Se podemos colocar na última corrida de modo que não estoure o limite do peso do elevador (Ou seja, se onde é o peso da pessoa e é o limite do elevador), então, faça , pois isso significa colocar na viagem atual.
- Senão, ou seja, colocando na última corrida, isso derrubaria o elevador, então, para colocar , temos que começar outra viajem, portanto, faça , pois isso significa subir a viagem atual até o último andar e começar uma nova.
- E portanto, basta comparar com , se for menor que , então fazemos . Veja que ser menor que significa que a quantidade de viagens que eu faço em é menor que a quantidade de viagens que eu faço em e, se for a mesma quantidade de viagens, o peso da última viagem em é menor que o peso da última viagem em .
Depois de rodar tudo, basta retornar a resposta de
.
( retorna a quantidade de vezes que andamos no elevador e se significa que temos uma viagem que ainda não acabou, então, temos que acresentar ela na resposta).
Esse códgio roda em , pois temos estados de para calcular, e a transição é em .
Recomendamos que você tente implementar o problema antes de ver o código. Veja a implementação nesse link.