// File: /workspace/github_cpp_makefile_star2_O2/A-deLuna[P]encora-cpp-test/largest_sum.cpp
// Function: find_largest_sum(unsigned int, std::vector<unsigned int, std::allocator<unsigned int>> const&, std::vector<unsigned int, std::allocator<unsigned int>>&, unsigned int&)
void find_largest_sum(const uint32_t T,
                      const std::vector<uint32_t>& I,
                      std::vector<uint32_t>& M,
                      uint32_t& S) {
  M.clear();
  // Traditional implementation uses booleans to indicate whether subset
  // adds up to j. We can optimize the path finding step by additionally storing
  // an offset to the first index i where I[0..i] sums up to j. The element in
  // this first index i is guaranteed to be part of a set that adds up to j.
  // Here -1 is the same as false and any other number is true.
  std::vector<std::vector<int>> dp(I.size() + 1, std::vector<int>(T + 1, -1));

  // Base case, we can always take an empty set to sum up to zero.
  for (size_t i = 0; i <= I.size(); i++) {
    dp[i][0] = 0;
  }

  std::optional<int32_t> maxSoFar;
  for (size_t i = 1; i <= I.size(); i++) {
    for (size_t j = 1; j <= T; j++) {
      if (I[i - 1] > j) {
        dp[i][j] = dp[i - 1][j] == -1 ? -1 : dp[i - 1][j] + 1;
      }
      if (I[i - 1] <= j) {
        if (dp[i - 1][j] != -1) {
          dp[i][j] = dp[i - 1][j] + 1;
        } else if (dp[i - 1][j - I[i - 1]] != -1) {
          dp[i][j] = 0;
        }
        if (dp[i][j] != -1) {
          // keep track of the greatest j <= T for which we have an answer.
          maxSoFar = j;
        }
      }
    }
  }
  // Could not find a subset in I with sum <= T.
  if (!maxSoFar.has_value() || maxSoFar.value() == 0) {
    S = 0;
    return;
  }

  S = maxSoFar.value();
  int current = maxSoFar.value();

  // All elements at position [I.size()][j] contain an offset to the
  // first index where the sum of elements in subset [0..i] equal to j.
  // This element is guaranteed to be part of the path.
  while (current != 0) {
    int offset = dp[I.size()][current];
    int idx = I.size() - offset;
    M.push_back(I[idx - 1]);
    current -= I[idx - 1];
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rcx, %rbx
movq %rsi, %r14
movl %edi, %r12d
movq (%rdx), %rax
cmpq %rax, 0x8(%rdx)
je 0x13a4
movq %rax, 0x8(%rdx)
movq %rdx, 0x18(%rsp)
movq (%r14), %r15
movq 0x8(%r14), %r13
leal 0x1(%r12), %esi
leaq 0x3c(%rsp), %rdx
orl $-0x1, (%rdx)
leaq 0x40(%rsp), %rdi
leaq 0xf(%rsp), %rcx
callq 0x1580
subq %r15, %r13
sarq $0x2, %r13
incq %r13
leaq 0x20(%rsp), %rdi
leaq 0x40(%rsp), %rdx
leaq 0xe(%rsp), %rcx
movq %r13, %rsi
callq 0x15d6
leaq 0x40(%rsp), %rdi
callq 0x16a2
movq (%r14), %rax
movq 0x8(%r14), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
pushq $-0x1
popq %rdx
movq 0x20(%rsp), %rsi
cmpq %rdx, %rcx
je 0x1421
movq (%rsi), %rdi
andl $0x0, (%rdi)
incq %rdx
addq $0x18, %rsi
jmp 0x140d
movq %rbx, 0x10(%rsp)
movl %r12d, %edx
negq %rdx
pushq $0x1
popq %r10
xorl %esi, %esi
pushq $-0x1
popq %r8
pushq $0x1
popq %r9
cmpq %rcx, %r10
ja 0x14e3
movq 0x20(%rsp), %r11
imulq $0x18, %r10, %rdi
leaq (%r11,%rdi), %r12
addq $-0x18, %r12
addq %rdi, %r11
pushq $0x1
popq %r13
leaq (%rdx,%r13), %rdi
cmpq $0x1, %rdi
je 0x14db
movl -0x4(%rax,%r10,4), %r15d
cmpq %r15, %r13
jae 0x1489
movq (%r12), %rdi
movl (%rdi,%r13,4), %edi
incl %edi
cmovel %r8d, %edi
movq (%r11), %rbx
movl %edi, (%rbx,%r13,4)
movl -0x4(%rax,%r10,4), %r15d
cmpq %r15, %r13
jb 0x14d0
movq (%r12), %rdi
movl (%rdi,%r13,4), %ebx
cmpl $-0x1, %ebx
je 0x14ab
incl %ebx
movq (%r11), %rdi
movl %ebx, (%rdi,%r13,4)
cmpl $-0x1, %ebx
jne 0x14c1
jmp 0x14d0
shlq $0x2, %r15
subq %r15, %rdi
cmpl $-0x1, (%rdi,%r13,4)
movq (%r11), %rdi
je 0x14d5
andl $0x0, (%rdi,%r13,4)
movzbl %sil, %esi
testb $0x1, %sil
cmovel %r9d, %esi
movl %r13d, %ebp
incq %r13
jmp 0x145b
movl (%rdi,%r13,4), %ebx
jmp 0x14a4
incq %r10
jmp 0x143a
testb $0x1, %sil
je 0x1536
testl %ebp, %ebp
je 0x1536
movq 0x10(%rsp), %rcx
movl %ebp, (%rcx)
movq 0x18(%rsp), %r15
testl %ebp, %ebp
je 0x153e
movq 0x8(%r14), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
movq 0x20(%rsp), %rdx
imulq $0x18, %rcx, %rsi
movslq %ebp, %rdi
movq (%rdx,%rsi), %rdx
movl (%rdx,%rdi,4), %edx
notl %edx
addl %ecx, %edx
movslq %edx, %rbx
leaq (%rax,%rbx,4), %rsi
movq %r15, %rdi
callq 0x162c
movq (%r14), %rax
subl (%rax,%rbx,4), %ebp
jmp 0x14f9
movq 0x10(%rsp), %rax
andl $0x0, (%rax)
leaq 0x20(%rsp), %rdi
callq 0x164a
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x16a2
jmp 0x1578
movq %rax, %rbx
jmp 0x1578
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x164a
movq %rbx, %rdi
callq 0x1160