Problem description Alice and Bob always love to play games, so does this time. It is their favorite stone-taken game. However, this time they does not compete but co-operate to finish this task. Suppose there is a stack of N stones. Each turn, Alice can only take away stones in number POW of 2, say 1, 2, 4, 8, 16 ,... Bob can only take away stones in number POW of 3, say 1, 3, 9, 27, 81 ,... They takes stones alternately, and Lady first. Notice in each turn, Alice/Bob have to take away at least one stone, unless the stack is empty. Now, the question is, what is the least number of operation for taking away all the stones. Input Multiple test cases. First line, there is an integer T (1 ≤ T ≤ 20), indicating the number of test cases. For each test case, there is a number N (1 ≤ n ≤10000), occupying a line, indicating the total number of the stones. OuputFor each test case, output a line. It is an integer number k, indicating the least number of operation in need to finish the task. Sample Input 512345 Sample output 11212 Source Xtu onlinejudge When I saw this question last year, I had no idea about dynamic planning. I don't know how to think about it. I felt a fear of dynamic planning. To solve this problem again, I still cannot find a recursive equation. I still need to practice more dynamic planning and have some inspiration. After reading other people's ideas, I finally understood it, http://blog.csdn.net/libin56842/article/details/26287101 with their own style to write it again; Here we use two-dimensional DP, and DP [I] [0]: the minimum number of steps for Alice to take the I stone (Alice is the first hand ); DP [I] [1]: Minimum number of steps Bob uses to take an I stone; Alice takes the stones first. If Alice does not finish taking the stones at a time, Bob continues to take the stones. What we want to get is the minimum number of steps used, so we can get the state relationship; Min (DP [I] [0], DP [I-j] [1] + 1); j is the number of Alice's retrieved parts, and Bob needs to add 1 to the number of retrieved parts; The following code is used: # Include <cstdio> # include <cstring> # define min (a, B) a <B? A: bconst int maxn = 10005; const int max = 0x3f3f3f3f; int DP [maxn] [2]; int main () {int t, n, I, j; DP [0] [0] = DP [0] [1] = 0; DP [1] [0] = DP [1] [1] = DP [2] [0] = 1; // you can obtain the DP [2] [1] = 2 at a time; // Bob needs to obtain the for (I = 3; I <maxn; I ++) twice) // here we will start from 3 {DP [I] [0] = DP [I] [1] = max; // The initial value is assigned to the maximum value for (j = 1; j <= I; j * = 2) // each time Alice obtains 2 j dp [I] [0] = min (DP [I] [0], DP [I-j] [1] + 1); // compare the direct minimum value for (j = 1; j <= I; j * = 3) // Bob's DP [I] [1] = min (DP [I] [1], DP [I-j] [0] + 1 );} scanf ("% d", & T); While (t --) {scanf ("% d", & N); printf ("% d \ n ", DP [N] [0]); // here Alice is the first operator} return 0 ;}
|