zoj1155 triangle war

来源:互联网 发布:网络棋牌代理赚钱吗 编辑:程序博客网 时间:2024/06/01 09:06
  1. /**
  2. DP 
  3. 对状态编号, 18条边, 每条边可能实线, 也可能虚线, 有2^18种
  4. MaxScore(x) = max { 
  5.               StepScore(rCode, selectedEdgeNum) > 0 
  6.            ?  StepScore + MaxScore(rCode)         //选择的边成三角行 
  7.            :  RemainScore(x) -  MaxScore(rCode)   //选择的边不成三角形 
  8. }
  9. max 函数作用在所有虚线边上。 
  10. **/
  11. #include <cstdlib>
  12. #include <iostream>
  13. using namespace std;
  14. int maxScore[262144]; //2^18
  15. //给18条边编号, 边的编号见附图 
  16. const int EDGENUM[10][10] = {
  17.      /*1, 2,  3, 4,  5,  6,  7,  8,  9  10 **/
  18.       -1, 0,  1, -1, -1, -1, -1, -1, -1, -1, //1
  19.       0, -1,  2,  3,  4, -1, -1, -1, -1, -1, //2
  20.       1,  2,  -1, -1, 5, 6,  -1, -1, -1, -1, //3
  21.       -1, 3, -1, -1,  7, -1,  9, 10, -1, -1, //4
  22.       -1, 4 , 5,  7, -1,  8, -1, 11, 12, -1, //5
  23.       -1, -1,  6, -1, 8, -1, -1, -1, 13, 14, //6
  24.       -1, -1, -1,  9, -1, -1, -1, 15, -1, -1, //7
  25.       -1, -1, -1, 10, 11, -1, 15, -1, 16, -1, //8
  26.       -1, -1, -1, -1, 12, 13, -1, 16, -1, 17, //9
  27.       -1, -1, -1, -1, -1, 14, -1, -1, 17, -1, //10
  28. };
  29. const int BIT[18] = { 1, 1<<1, 1<<2, 1<<3, 1<<4, 1<<5, 1<<6, 1<<7, 1<<8,
  30.                   1<<9, 1<<10, 1<<11, 1<<12, 1<<13, 1<<14, 1<<15, 1<<16, 1<<17 };
  31.                   
  32. struct Triangle {
  33.        int e1, e2, e3;//三条边的编号 
  34. };
  35. //列举9个三角形 
  36. const Triangle triangle[9] = {
  37.                            {0, 1, 2},
  38.               {3, 4, 7},   {2, 4, 5},    {5, 6, 8},
  39. {9, 10, 15}, {7, 10, 11}, {11, 12, 16}, {8, 12, 13}, {13, 14, 17}
  40. };
  41. int StepScore(int x, int i)
  42. {
  43.     int score = 0;
  44.     for (int j=0; j<9; j++)
  45.     {
  46.         Triangle tri = triangle[j];
  47.         if ( x & BIT[tri.e1] && x & BIT[tri.e2] && x & BIT[tri.e3] )
  48.         {
  49.              if (i == tri.e1 || i == tri.e2 || i == tri.e3)
  50.                 score++;
  51.         }
  52.     }
  53.     return score;
  54. }
  55. int RemainScore(int x)
  56. {
  57.     int score = 9;
  58.     for (int j=0; j<9; j++)
  59.     {
  60.         Triangle tri = triangle[j];
  61.         if ( x & BIT[tri.e1] && x & BIT[tri.e2] && x & BIT[tri.e3] )
  62.         {
  63.                 score--;
  64.         }
  65.     }
  66.     return score;
  67. }
  68. int MaxScore(int x)
  69. {
  70.     if (maxScore[x] > -1) return maxScore[x];
  71.     if (x == 262143) return maxScore[x] = 0;
  72.     int max = -1, m;
  73.     for (int i=0; i<18; i++)
  74.     {
  75.         if (x & BIT[i]) continue;
  76.         int rCode = x | BIT[i];
  77.         int score = StepScore(rCode, i);
  78.         if (score) m = score + MaxScore(rCode);
  79.         else
  80.         {
  81.             int rScore = RemainScore(x);
  82.             m = rScore - MaxScore(rCode);
  83.         }
  84.         max >?= m;
  85.     }
  86.     return maxScore[x] = max;
  87. }
  88. int main(int argc, char *argv[])
  89. {
  90.     int kase;
  91.     cin>>kase;
  92.     memset(maxScore, -1, sizeof(maxScore));
  93.     for (int i=0; i<kase; i++)
  94.     {
  95.         if (i>0) cout<<endl;
  96.         int games, gNum, moves, a, b;
  97.         cin>>games;
  98.         for (gNum=1; gNum<=games; gNum++)
  99.         {            
  100.             cin>>moves;
  101.             int code = 0, turn = 0;//A's turn.
  102.             int scoreOfA = 0;
  103.             for (int j=0; j<moves; j++)
  104.             {
  105.                 cin>>a>>b;
  106.                 int e = EDGENUM[a-1][b-1];
  107.                 code = code | BIT[e];
  108.                 int stepScore = StepScore(code, e);
  109.                 if (stepScore)
  110.                 {
  111.                    if (turn == 0) scoreOfA += stepScore;
  112.                 } else
  113.                 {
  114.                       turn = 1 - turn;
  115.                 }
  116.             }
  117.             if (turn == 0) scoreOfA += MaxScore(code);
  118.             else scoreOfA += RemainScore(code) - MaxScore(code);
  119.             cout<<"Game "<<gNum<<": ";
  120.             if (scoreOfA > 4) cout<<"A wins."<<endl;
  121.             else cout<<"B wins."<<endl;
  122.         }
  123.     }
  124. }
原创粉丝点击