Just as an example for the math: a two input/two output P2PKH transaction returns 746 chars, so it is in hex 373 Bytes.
$ printf 010000000253603B3FDB9D5E10DE2172305FF68F4B5227310BA6BD81D4E1BF60C0DE6183BC010000006A4730440220128487F04A591C43D7A6556FFF9158999B46D6119C1A4D4CF1F5D0AC1DD57A94022061556761E9E1B1E656C0A70AA7B3E83454CD61662DF61EBDC31E43196B5E0C10012102B12126A716CE7BBB84703BCFBF0AFA80283C75A7304A48CD311A5027EFD906C2FFFFFFFF0E52C4701577287B6DD02F422C2A8033FA0B4614F75FA9F0A5C4AB69634B5BA7000000006B483045022100A428348FF55B2B59BC55DDACB1A00F4ECDABE282707BA5185D39FE9CDF05D7F0022074232DAE76965B6311CEA2D9E5708A0F137F4EA2B0E36D0818450C67C9BA259D0121025F95E8A33556E9D7311FA748E9434B333A4ECFB590C773480A196DEAB0DEDEE1FFFFFFFF0290257300000000001976A914FCA68658B537382E27A85522D292E1AD9543FE0488AC98381100000000001976A9146AF1D17462C6146A8A61217E8648903ACD3335F188AC00000000 | wc -c
It has two inputs with signatures and compressed keys, and two P2PKH outputs. It can be decomposed this way:
VERSION 01000000
TX_IN COUNT [var_int]: hex=02, decimal=2
TX_IN[0] OutPoint hash (char[32]) BC8361DEC060BFE1D481BDA60B3127524B8FF65F307221DE105E9DDB3F3B6053
TX_IN[0] OutPoint index (uint32_t) hex=01000000, reversed=00000001, decimal=1
TX_IN[0] Script Length (var_int) hex=6A, decimal=106
TX_IN[0] Script Sig (uchar[]) 4730440220128487F04A591C43D7A6556FFF9158999B46D6119C1A4D4CF1F5D0AC1DD57A94022061556761E9E1B1E656C0A70AA7B3E83454CD61662DF61EBDC31E43196B5E0C10012102B12126A716CE7BBB84703BCFBF0AFA80283C75A7304A48CD311A5027EFD906C2
TX_IN[0] Sequence (uint32_t) FFFFFFFF
TX_IN[1]
TX_IN[1] OutPoint hash (char[32]) A75B4B6369ABC4A5F0A95FF714460BFA33802A2C422FD06D7B28771570C4520E
TX_IN[1] OutPoint index (uint32_t) hex=00000000, reversed=00000000, decimal=0
TX_IN[1] Script Length (var_int) hex=6B, decimal=107
TX_IN[1] Script Sig (uchar[]) 483045022100A428348FF55B2B59BC55DDACB1A00F4ECDABE282707BA5185D39FE9CDF05D7F0022074232DAE76965B6311CEA2D9E5708A0F137F4EA2B0E36D0818450C67C9BA259D0121025F95E8A33556E9D7311FA748E9434B333A4ECFB590C773480A196DEAB0DEDEE1
TX_IN[1] Sequence (uint32_t) FFFFFFFF
TX_OUT COUNT hex=02, decimal=2
TX_OUT[0] Value (uint64_t) hex=9025730000000000, reversed_hex=0000000000732590, dec=7546256, bitcoin=0.07546256
TX_OUT[0] PK_Script Length (var_int) hex=19, dec=25
TX_OUT[0] pk_script (uchar[]) 76A914FCA68658B537382E27A85522D292E1AD9543FE0488AC
TX_OUT[1] Value (uint64_t) hex=9838110000000000, reversed_hex=0000000000113898, dec=1128600, bitcoin=0.01128600
TX_OUT[1] PK_Script Length (var_int) hex=19, dec=25
TX_OUT[1] pk_script (uchar[]) 76A9146AF1D17462C6146A8A61217E8648903ACD3335F188AC
LOCK_TIME 00000000
Based on the formula (X * 148 + Y * 34 + 10 +- X) it should give 2*148+2*34+2=366Bytes ... close. Ok.
Now comes a (2-of-2) multisig with 1 input, two outputs, 670 chars, 335 Bytes - compressed keys:
$ printf 0100000001B9C6777F2D8D710F1E0E3BB5FBFFA7CDFD6C814A2257A7CFCED9A2205448DD0601000000DA0048304502210083A93C7611F5AEEE6B0B4D1CBFF2D31556AF4CD1F951DE8341C768AE03F780730220063B5E6DFB461291B1FBD93D58A8111D04FD03C7098834BAC5CDF1D3C5FA90D0014730440220137C7320E03B73DA66E9CF89E5F5ED0D5743EBC65E776707B8385FF93039408802202C30BC57010B3DD20507393EBC79AFFC653473A7BAF03C5ABF19C14E2136C646014752210285CB139A82DD9062B9AC1091CB1F91A01C11AB9C6A46BD09D0754DAB86A38CC9210328C37F938748DCBBF15A0E5A9D1BA20F93F2C2D0EAD63C7C14A5A10959B5CE8952AEFFFFFFFF0280C42B03000000001976A914D199925B52D367220B1E2A2D8815E635B571512F88AC65A7B3010000000017A9145C4DD14B9DF138840B34237FDBE9159C420EDBBE8700000000 | wc -c
the difference is that you need to have two signatures, and the 3 pubkeys of the multisig. Decoded:
VERSION 01000000
TX_IN COUNT [var_int]: hex=01, decimal=1
TX_IN[0] OutPoint hash (char[32]) 06DD485420A2D9CECFA757224A816CFDCDA7FFFBB53B0E1E0F718D2D7F77C6B9
TX_IN[0] OutPoint index (uint32_t) hex=01000000, reversed=00000001, decimal=1
TX_IN[0] Script Length (var_int) hex=DA, decimal=218
TX_IN[0] Script Sig 1 (uchar[]) 0048304502210083A93C7611F5AEEE6B0B4D1CBFF2D31556AF4CD1F951DE8341C768AE03F780730220063B5E6DFB461291B1FBD93D58A8111D04FD03C7098834BAC5CDF1D3C5FA90D001
TX_IN[0] Script Sig 2 (uchar[]) 4730440220137C7320E03B73DA66E9CF89E5F5ED0D5743EBC65E776707B8385FF93039408802202C30BC57010B3DD20507393EBC79AFFC653473A7BAF03C5ABF19C14E2136C64601
TX_IN[0] Multisig Pubkeys (decoded details):
47: OP_DATA_0x47: push hex 47 (decimal 71) bytes on stack
52: OP_2: the number 2 is pushed onto stack
21: OP_DATA_0x21: compressed pub key (33 Bytes)
0285CB139A82DD90:62B9AC1091CB1F91:A01C11AB9C6A46BD:09D0754DAB86A38C:C9
This is MultiSig's compressed Public Key (X9.63 form)
corresponding bitcoin address is: 1LcBDzTGSJiN5snVBHiyeWsT7SqRWUW7mp
21: OP_DATA_0x21: compressed pub key (33 Bytes)
0328C37F938748DC:BBF15A0E5A9D1BA2:0F93F2C2D0EAD63C:7C14A5A10959B5CE:89
This is MultiSig's compressed Public Key (X9.63 form)
corresponding bitcoin address is: 1LisHErVXWhY1A1ZJqZSDdGYKrbGn1M6bx
52: OP_2: the number 2 is pushed onto stack
AE: OP_CHECKMULTISIG: terminating multisig TX_IN[0] Sequence (uint32_t)
TX_IN[0] Sequence (uint32) FFFFFFFF
TX_OUT COUNT hex=02, decimal=2
TX_OUT[0] Value (uint64_t) hex=80C42B0300000000, reversed_hex=00000000032BC480, dec=53200000, bitcoin=.53200000
TX_OUT[0] PK_Script Length (var_int) hex=19, dec=25
TX_OUT[0] pk_script (uchar[]) 76A914D199925B52D367220B1E2A2D8815E635B571512F88AC
TX_OUT[1] Value (uint64_t) hex=65A7B30100000000, reversed_hex=0000000001B3A765, dec=28551013, bitcoin=.28551013
TX_OUT[1] PK_Script Length (var_int) hex=17, dec=23
TX_OUT[1] pk_script (uchar[]) A9145C4DD14B9DF138840B34237FDBE9159C420EDBBE87
LOCK_TIME 00000000
one can easily change to 2-3 multisig or 3-of-7, which would increase the number of signatures and pubkeys accordingly.
Signatures can have different length, starting with 00 (especially when having negative S-values), and then 0x47 or 0x48 as length indicator.
Pubkeys can be compressed (33 bytes) or uncompressed (66bytes).
Math can't be tricked :-)