Question: http://acm.jlu.edu.cn/joj/showproblem.php? PID = 1, 2039
Algorithm: Dynamic Planning
The analysis is as follows:
The F (n, k) function indicates the number of methods for putting K blockhouses in a map with a size of N. There are two methods to place blockhouse:
1. a blockhouse is placed at the first position in the first line.
2. No blockhouse is placed in the first position of the first line.
The map shape described in the question is very similar to a special matrix form in linear algebra. To facilitate the analysis of the recursive formula of dynamic planning, a map of n size is written into a matrix form, the position where blockhouse can be placed is represented by 1, and the rest is represented by 0:
The preceding figure shows a map with a size of 5.
If there is a blockhouse placed in the first position of the first line, then the remaining blockhouse can only be placed on the map with the remaining size of N-1, at this time the number of methods is F (n-1, k-1 ).
If no blockhouse is placed in the first position of the first line, the map is changed to the following shape after the location is removed:
Assume that the number of K blockhouses on a map of this shape is g (n, k), then we can obtain the recursive formula of F (n, k:
Similar to the analysis of F (n, k), g (n, k) can be divided into two situations: where the first line is placed with a blockhouse; the first line does not contain blockhouse. In this way, we can obtain the recursive formula of g (n, k:
For the boundary, the following conditions are available:
If f and g call each other, you can calculate f (3, 2) to verify that there is no endless loop. In fact, we can also see from the formula of the above boundary situation that calling f (n, k) will be called recursively only when n> k, while calling f (n, k) divided into three parts: f (n-1, k-1), f (n-1, k), g (n-1, k-1), the second part f (n-1, k) will be reduced until 0. The size of the other two data parts is decreasing. There will be no endless loops.
The following is the AC code:
- # Include <cstdio>
- Double f [32] [32], g [32] [32];
- Double ff (int n, int k );
- Double gg (int n, int k );
- Double ff (int n, int k ){
- If (n <k) return 0;
- If (f [n] [k]) return f [n] [k];
- Return f [n] [k] = ff (n-1, k-1) + gg (n, k );
- }
- Double gg (int n, int k ){
- If (n <= k) return 0;
- If (g [n] [k]) return g [n] [k];
- Return g [n] [k] = ff (n-1, k) + gg (n-1, k-1 );
- }
- Int main (){
- Int T, C;
- Freopen ("in.txt", "r", stdin );
- For (int I = 0; I <32; I ++ ){
- F [I] [1] = 2 * (I-1) + 1;
- G [I] [1] = 2*(I-1 );
- F [I] [I] = 1;
- }
- While (scanf ("% d", & T, & C )! = EOF ){
- Printf ("%. 0lf/n", ff (T, C ));
- }
- Return 0;
- }