DataContractSerializer is contract-based, meaning it is not tied to any specific type model. All it has is data (typically xml). This means that if you have a model like:
Customer
SuperCustomer : Customer
AwesomeCustomer : Customer
then the serializer needs to know in advance what each type means if it sees it in the data; otherwise it won't know what type to create. This is done in a number of ways, the simplest of which is KnownTypeAttribute.
Consider the alternative; all the serializer knows is "Customer", which it expects to see as ... in some xml. Instead, it gets something else (it doesn't matter what, but let's say .... Now what does it do? Does it start scrounging for likely looking types? that is very imprecise and risky. Also consider, it needs to be able to generate a WSDL/MEX export for this data - if all it knows about is "Customer", it can't possible warn callers to also expect SuperCustomer / AwesomeCustomer - which would mean the WSDL/MEX is incomplete and useless.
This same approach is used by XmlSerializer (XmlIncludeAttribute) and protobuf-net (ProtoIncludeAttribute), and probably my most contract based serializers.
The alternative is type based serializers (BinaryFormatter, NetDataContractSerializer, etc) - in this it includes the type in the data, meaning Your.Namespace.Type, Your.Assembly, blah - this means it doesn't need to know in advance (since it is explicit in the data), but also means that it can't possibly work for different models (or indeed, cross-platform).