J - Peg Game for Two

Jacquez and Alia’s parents take them on many road trips. To keep themselves occupied, they play a triangular peg game, meant for one player. In the original game, one player has an equilateral triangle containing 1515 holes (five holes per side of the triangle). Initially one hole is empty and the remaining 1414 are filled with pegs. The player moves by picking up a peg to “jump” it over an adjacent peg, landing on an empty hole adjacent to the jumped peg. Jumps must be in straight lines (horizontally or diagonally). The peg that is jumped over is removed. The goal of this game is to leave just one peg on the board. Figure 1 shows the result of a jump in this game.

\includegraphics[width=0.3\textwidth ]{example1}
Figure 1: One possible move in the original game. On the left is an initial board, where X represents a peg and O represents an empty hole. The jump moves the right peg in the second (from top) row diagonally down and to the left, over the middle peg of the third row, which is removed.

Ultimately, Jacquez and Alia have gotten bored of playing this game individually. They decide to invent a version that they could play together. In the new version, each peg has a positive point value, and they alternate turns. During a player’s turn, they must make a jump if one is available. The score for a jump is the product of the two pegs involved in the jump.

The total score of a player is the sum of the scores of their jumps. The game ends when a player has no possible jumps to make. Each player’s goal is to maximize their own total score minus their opponent’s total score (at the end of the game). For example, Jacquez would prefer to win with a score of 100100 to Alia’s score of 6060 (with a differential of 4040 ), than to win with a score of 10001000 to Alia’s score of 998998 (with a smaller differential of only 22 ). Similarly, Alia wants to win by as much as possible over Jacquez.

For this version of the game, we can display the game state by replacing each X shown above with a corresponding value for that peg, and using a value of 00 (zero) for each of the open holes. Figure 2 shows an example move.

\includegraphics[width=0.3\textwidth ]{example2}
Figure 2: One possible move in the new game, jumping the peg with value 66 over the peg with value 77 . This move is worth 67=426⋅7=42 for Jacquez (since he moves first). The values are from the first sample input.

Jacquez has had some trouble winning. Write a program to calculate the best he can do, assuming that he starts and both players play optimally.

Input

The input consists of five lines, describing the initial state of the board. The ithith (1i5)(1≤i≤5) line contains ii space separated integers, representing the pegs and holes on the ithith row. Each of these integers is between 00 and 100100 , inclusive. A value of 00 represents a hole while the rest of the values represent pegs. It is possible for two different pegs to have the same value. Of the 1515 input values it is guaranteed that exactly one is 00 , thus all input boards start with exactly one hole.

Output

Output the value of Jacquez’s score minus Alia’s score at the end of the game, assuming Jacquez starts and both players play optimally.

Sample Input 1Sample Output 1
3
1 6
1 7 8
5 0 3 4
9 3 2 1 9
21
Sample Input 2Sample Output 2
1
2 3
4 5 6
7 8 9 10
11 12 0 13 14
19
Sample Input 3Sample Output 3
100
1 17
99 3 4
0 76 33 42
12 13 14 15 16
2148

 

题意是有一种游戏(类似跳棋),但是不同的是,开始只有一个空位置,可以用一个棋子跳过另一个棋子,跳到空的位置,然后跳过的棋子从棋盘上移除,最后剩下一个棋子。但是这样只能一个人玩,为了能两个人玩,将每个棋子加权,然后两个人分别走,记分方式是当前分数加上移动的棋子与跳过的棋子之积。两个人都想赢对方更多的分,即两个人的分差最大。

问你最大分差是多少。

 

这个题的思路有点奇怪,思路是先手动打表找出每个点的前一个位置以及要跳过的位置,这样子我们就相当有了路径,然后就变成了图上的模型,由题意就可以知道,这个题是要找两条路径权的差最大,由于点数不多,可以直接爆搜,但是搜索的时候还是有很多小细节。具体搜索细节放在代码注释里了。

 

  1 #include <bits/stdc++.h>
  2 
  3 using namespace std;
  4 
  5 typedef pair<int,int> P;
  6 const int INF = 0x3f3f3f3f;
  7 
  8 int a[15];
  9 vector<P> G[15];
 10 P dfs()
 11 {
 12     int maxdif = -INF;
 13     int dp0 = 0, dp1 = 0;
 14     for (int i = 0; i < 15; i++)
 15     {
 16         if (a[i] == 0)
 17         {
 18             for (int j = 0; j < G[i].size(); j++)
 19             {
 20                 int x = G[i][j].first, y = G[i][j].second; 
 21                 if (a[x] == 0 || a[y] == 0) continue;  //不满足搜索条件
 22                 int oldx = a[x], oldy = a[y];
 23                 a[x] = 0, a[y] = 0;    //改变条件
 24                 a[i] = oldy;
 25                 P temp = dfs();    //递归暴力搜索
 26                 int t0 = temp.first, t1 = temp.second; 
 27                 if (t1 + oldx*oldy - t0 > maxdif)
 28                 {
 29                     maxdif = t1 + oldx*oldy - t0; //寻找最大值并记录
 30                     dp0 = t1 + oldx*oldy;
 31                     dp1 = t0;
 32                 }
 33                 a[x] = oldx, a[y] = oldy;  //回溯
 34                 a[i] = 0;
 35             }
 36         }
 37     }
 38     return make_pair(dp0, dp1);
 39 }
 40 void init() //手动打表,从0开始到14号
 41 {
 42     G[0].push_back(make_pair(1, 3)); //以第一个举例,可以从三号位跳过一号位到达0号位
 43     G[0].push_back(make_pair(2, 5));
 44 
 45     G[1].push_back(make_pair(3, 6));
 46     G[1].push_back(make_pair(4, 8));
 47 
 48     G[2].push_back(make_pair(4, 7));
 49     G[2].push_back(make_pair(5, 9));
 50 
 51     G[3].push_back(make_pair(4, 5));
 52     G[3].push_back(make_pair(6, 10));
 53     G[3].push_back(make_pair(7, 12));
 54     G[3].push_back(make_pair(1, 0));
 55 
 56     G[4].push_back(make_pair(7, 11));
 57     G[4].push_back(make_pair(8, 13));
 58 
 59     G[5].push_back(make_pair(4, 3));
 60     G[5].push_back(make_pair(8, 12));
 61     G[5].push_back(make_pair(9, 14));
 62     G[5].push_back(make_pair(2, 0));
 63 
 64     G[6].push_back(make_pair(3, 1));
 65     G[6].push_back(make_pair(7, 8));
 66 
 67     G[7].push_back(make_pair(4, 2));
 68     G[7].push_back(make_pair(8, 9));
 69 
 70     G[8].push_back(make_pair(7, 6));
 71     G[8].push_back(make_pair(4, 1));
 72 
 73     G[9].push_back(make_pair(5, 2));
 74     G[9].push_back(make_pair(8, 7));
 75 
 76     G[10].push_back(make_pair(6, 3));
 77     G[10].push_back(make_pair(11, 12));
 78 
 79     G[11].push_back(make_pair(7, 4));
 80     G[11].push_back(make_pair(12, 13));
 81 
 82     G[12].push_back(make_pair(7, 3));
 83     G[12].push_back(make_pair(8, 5));
 84     G[12].push_back(make_pair(11, 10));
 85     G[12].push_back(make_pair(13, 14));
 86 
 87     G[13].push_back(make_pair(8, 4));
 88     G[13].push_back(make_pair(12, 11));
 89 
 90     G[14].push_back(make_pair(9, 5));
 91     G[14].push_back(make_pair(13, 12));
 92 }
 93 int main()
 94 {
 95     init();
 96     for (int i = 0; i < 15; i++)
 97     {
 98         scanf("%d", &a[i]);
 99     }
100     P ans = dfs();
101     printf("%d\n", ans.first - ans.second);
102     return 0;
103 }

 

posted @ 2019-04-19 20:35  犹疑照颜色  阅读(363)  评论(0编辑  收藏  举报