My router uses DHCP, and whenever I reformat my raspberry pi, even when using a different microSD card, it always has the same LAN ip. I'm not quite sure how IPs are assigned, but I assume the device has a unique id on the network which my router recognises?
Your Raspberry Pi has a unique ID, called a MAC address, actually two to be precise. Each network adapter has one of those. So the Wi-Fi adapter has one unique ID and the Ethernet adapter does.
And this is why your Raspberry Pi gets the same IP. For your router it's not important what you are doing with the device exactly. It just recognizes the MAC and provides the same IP as before.
Edit: As Beege pointed out, the IP can still change as the 'D' in DHCP stands for dynamic. But if your device gets the same IP as before via DHCP its because of the MAC that's recognized.
In addition to the already given answers I will give some additional background information.
In general the DHCP protocol is made to reduce dynamic changes as much as possible. It is an aspect of stability. It does not matter much on small home networks but big networks with switches and routers need some time to get into an optimized state. Switches have to learn its neighbors and router have to learn the routes. Heavy changes of ip addresses is not good for this state.
Most people may think the DHCP server just give an ip address to a client and that's it. But it is only half the truth. Here is a typical DHCP handshake:
(client) DHCPREQUEST for 192.168.10.75 from b8:27:eb:0e:3c:6f (raspi3) via wlan0 (server) DHCPACK on 192.168.10.75 to b8:27:eb:0e:3c:6f (raspi3) via wlan0
As you can see the client identified with its mac address b8:27:eb:0e:3c:6f requests a specific ip address it prefers. It knows what ip address it has before, also after a new startup. The DHCP server only confirms it. That what it gives to the client is called a lease. It contains a timeout (together with many other important options) how long the client can use the ip address without requesting again. The timeout depends on the setup and is mostly set to some hours. The DHCP server stores the lease in its cache and will reserve it as long as possible for the same client, also if it is shutdown. So it will just confirm the client for its lease when it bootup again. Only when the server does not have other unused leases to give to clients it will take the used one. The handshake then will look like this:
(client) DHCPREQUEST for 192.168.10.75 from b8:27:eb:0e:3c:6f (raspi3) via wlan0 (server) DHCPNAK on 192.168.10.75 to b8:27:eb:0e:3c:6f via wlan0 (client) DHCPDISCOVER from b8:27:eb:0e:3c:6f via wlan0 (server) DHCPOFFER on 192.168.10.99 to b8:27:eb:0e:3c:6f via wlan0 (client) DHCPREQUEST for 192.168.10.99 from b8:27:eb:0e:3c:6f (raspi3) via wlan0 (server) DHCPACK on 192.168.10.99 to b8:27:eb:0e:3c:6f (raspi3) via wlan0
As you can see the DHCP server rejects (DHCPNAK) the request and offers a new ip address that then in the next step is requested by the client. This additional step is made to give the client the possibility to not accept the offered ip address ...