Nyoj832 merge game (status compression DP)
Merge game question links
N stones: Give you an n * n matrix. A [I] [j] indicates the gold coins merged from the I and j. After the stones are mergedJDisappear. Calculate the maximum number of gold coins obtained after merging all stones.
Analysis:
1. Data range given in the questionN (1 <= n <= 10)That is to say, we can use a binary string to represent the merged state. 1 indicates that the merged state is not merged, and 0 indicates that the merged state disappears. For example, (1001) 2nd and 3 of the four stones are merged.
2. Use d [x] to store the maximum number of gold coins that are merged to the x State. For example, d [1001] indicates the maximum number of gold coins obtained after merging 2 and 3.
3. We start searching from the starting status (for example, 4 stones: 1111), and enumerate the states (1110,110 1, 1011,011 1) after merging 1 stones ), continue to the next state, 1110 in the next state: (0110,101 0, 1100), 1101-> (1100,100 1, 0101), 1011-> (1010,100 1, 0011 ), 0111-> (0110,010 1, 0011), continue to the next State ........... Recursively calculates the next state.
1110 there are three merge methods, which can be combined by the last stone in 1111 and any of the first three stones.Note:You will find that 1110,110, 1011,011, and are in the next state.DuplicateSo you can search for and tag without doing any extra work.
# Include
# Include
# Include
# Include
Using namespace std; int n, a [15] [15], d [10000]; int dp (int x) {if (d [x]! =-1) return d [x]; // You must mark the status you have searched !! If this parameter is not specified, int Mx = 0; if (x = 0) return 0; for (int I = 0; I <n; I ++) {int mx = 0; if (x & (1 <I) // enumerate all the stones that can be merged, the I + 1 {int tem = x-(1 <I ); // merged state, for (int j = 0; j <n; j ++) {if (tem & (1 <j )) // enumerate all the stones that can be merged with the I + 1 stone and obtain the largest mx = max (a [1 + j] [I + 1], mx );} mx = max (Mx, dp (tem) + mx) ;}} d [x] = Mx; return d [x] ;}int main () {while (scanf ("% d", & n )! = EOF) {for (int I = 1; I <= n; I ++) for (int j = 1; j <= n; j ++) scanf ("% d", & a [I] [j]); memset (d,-1, sizeof (d )); int ans = dp (1 <n)-1); printf ("% d \ n", ans);} return 0 ;}