Counting DP is a method that uses a memorized search similar to DP (which differs somewhat from DP in the narrow sense, namely optimization problems) to solve counting (and summation) problems.
Basics
Basic idea
A counting problem generally asks for the size of a set . In OI, the size of may sometimes reach the order of or even (of course, it is generally taken modulo some fixed number), where is the problem size, so we cannot find the elements of one by one.
If we can divide into several pairwise disjoint subsets, then the number of elements in equals the sum of the numbers of elements in these parts. If counting these subsets happens to resemble the original problem, we can solve it using a method similar to dynamic programming.
Example
Example
Given a positive integer , find the number of ways to express as the sum of positive integers, where changing the positions counts as a different partition.
Let be the set of tuples of positive integers of the form such that . If is fixed, we have the following derivation: since , we have . By the definition of , .
Since are positive integers, the range of is . Therefore, can be partitioned according to into subsets. When , the subset is:
The number of elements in this subset is clearly equal to that of , and because the values of differ, these subsets are pairwise disjoint. Therefore:
We can therefore process this using a method similar to DP: let be . Then the state transition is:
Thus, it can be solved using DP.
Similarities to and differences from optimization DP
We can see that both counting DP and optimization DP find a value (a size or an optimum) over a domain . This value is obtained by processing every element in once and then aggregating the processed values once.
For example, in the 0-1 knapsack problem, the elements of are the sets of all items in the knapsack. For a solution in , , we process once; the result is the total value of the items in . We take the maximum over all processed values to obtain the answer.
For a counting problem, the elements of are the set whose number of elements is to be computed. Its processing changes every element of to , and then aggregates these s by addition. Since every element of corresponds to one , the resulting value is the number of elements in .
When the aggregation operation is taking a maximum or minimum, we may divide into any number of parts, as long as their union is ; pairwise disjointness is not required. Counting problems do not satisfy this condition, so we need to divide into parts that are pairwise disjoint. This is the difference from optimization DP.
Example
Example
Given a positive integer , find the number of ways to express as the sum of any number of positive integers, where changing the positions counts as the same partition.
Solution 1
The elements of the set to be computed are positive-integer multisets whose sum is . However, this is clearly not easy to derive from directly.
If a multiset contains only positive integers and the sum of all elements in is , define . Consider the number of occurrences of . It may be . Thus, it can transition to . Summing over these gives a complexity of (the comes from the harmonic series caused by the range of ).
However, this is still not good enough. Consider the following example:
Substitution gives , , and . Similarly, we can obtain a general state transition:
The time complexity is now .
Solution 2
Considering that a multiset of positive integers can necessarily be obtained by the two operations “increment every element in ” and “add to an element with value ”, different operation sequences produce different results.
Thus, the transition for can be changed into a transition for operation sequences. Consider the last operation in an operation sequence that partitions into numbers (denote all such operation sequences by ). If it is operation , the number of elements does not increase, but increases by . For the final , the sum of the original (denoted by ) must be . Hence . If it is operation , the number of elements increases by one and increases by . Hence .
The time complexity remains .
Solution 3
Consider dividing into the part greater than , , and the part less than or equal to , . can be found using Solution 1, while the number of can be found by slightly modifying Solution 2: change the two operations to “increment every element in ” and “add to an element with value ”. The state transition can be written down easily.
Split into two parts, and . Enumerating one determines the other. Find the number satisfying among and the number satisfying among , multiply them, and sum over all to obtain the final result.
When computing the number of , we have , so using Solution 1 to compute takes time. Similarly, when computing the number of , , so using Solution 2 to compute also takes time. Therefore, the total time complexity is .