```ts
/** Fixed-point money helpers: parse, format, and allocate integer cents. */

export function parseAmount(text: string): number {
  if (typeof text !== "string") {
    throw new Error("amount must be a string");
  }
  const match = /^(\d+)(?:\.(\d{2}))?$/.exec(text);
  if (match === null) {
    throw new Error(`malformed amount: ${text}`);
  }
  const whole = Number(match[1]);
  const cents = match[2] === undefined ? 0 : Number(match[2]);
  return whole * 100 + cents;
}

export function formatAmount(cents: number): string {
  if (!Number.isInteger(cents) || cents < 0) {
    throw new Error("cents must be a non-negative integer");
  }
  const whole = Math.floor(cents / 100);
  const rest = String(cents % 100).padStart(2, "0");
  return `${whole}.${rest}`;
}

export function allocateCents(totalCents: number, weights: number[]): number[] {
  if (typeof totalCents !== "number" || !Number.isInteger(totalCents) || totalCents < 0) {
    throw new Error("totalCents must be a non-negative integer");
  }
  
  if (!Array.isArray(weights) || weights.length === 0) {
    throw new Error("weights must be a non-empty array of integers");
  }

  const sum = weights.reduce((acc, weight) => acc + weight, 0);

  if (sum === 0) {
    throw new Error("totalCents cannot be zero when weights are not");
  }

  const allocateExact = (weight: number): number => Math.floor((totalCents * weight) / sum);
  const allocateLeftover = () => { 
    let leftover = totalCents;
    for (let i = 0; i < weights.length && leftover > 0; i++) {
      const share = allocateExact(weights[i]);
      if (share === 0) continue;
      weights[i] -= share;
      leftover -= share;
    }
    return leftover;
  };

  const shares = weights.map((weight, index) => Math.floor(totalCents * weight / sum));
  let leftover = allocateLeftover();
  const zeroShareIndex = shares.findIndex(share => share === 0);

  while (leftover > 0 && zeroShareIndex !== -1) {
    shares[zeroShareIndex] += 1;
    leftover -= 1;
    zeroShareIndex = shares.findIndex(share => share === 0);
  }

  if (leftover > 0) {
    throw new Error("totalCents is not a multiple of the weights sum");
  }

  return shares;
}
```