Triangle War--POJ 1085

1、题目类型:博弈、DP。

2、解题思路:(1)构建18条边、9个三角形分别由那三条边组成;(2)模拟输入的残局,并记录A、B获得三角形的差值,中间利用player保持A、B主动权的变换;(3)DP递归剩余情况,寻找player到最后的单步最有情况;(4)判断最终的最大差值MAX,正负即A、B博弈的结果。

3、注意事项:注意构造三角形三边是对应的16进制表示;DP递归过程中注意dp[]的更新。

4、参考博客:http://blog.csdn.net/bobten2008/archive/2009/08/25/4484005.aspx

5、实现方法:

  
    
#include < iostream >
#include
< algorithm >
using namespace std;
#define MIN -10

int line[ 18 ][ 2 ] = {
{
1 , 2 },{ 1 , 3 },{ 2 , 3 },
{
2 , 4 },{ 2 , 5 },{ 3 , 5 },
{
3 , 6 },{ 4 , 5 },{ 5 , 6 },
{
4 , 7 },{ 4 , 8 },{ 5 , 8 },
{
5 , 9 },{ 6 , 9 },{ 6 , 10 },
{
7 , 8 },{ 8 , 9 },{ 9 , 10 }
};

int tri[ 9 ][ 3 ] = {
{
0x01 , 0x02 , 0x04 },
{
0x04 , 0x10 , 0x20 },
{
0x08 , 0x10 , 0x80 },
{
0x20 , 0x40 , 0x100 },
{
0x200 , 0x400 , 0x8000 },
{
0x80 , 0x400 , 0x800 },
{
0x800 , 0x1000 , 0x10000 },
{
0x100 , 0x1000 , 0x2000 },
{
0x2000 , 0x4000 , 0x20000 }
};

int dp[ 600000 ],pow[ 18 ];
int m,player,state,x,y;

// 寻找当前状况下,是否可以构成三角形
int Cal( int pos, int state)
{
int i,j,flag,t, get = 0 ;
for (i = 0 ;i < 9 ;i ++ )
{
flag
= 0 ;t = 3 ;
for (j = 0 ;j < 3 ;j ++ )
{
if (pow[pos] & tri[i][j])
t
= j;
else if (state & tri[i][j])
flag
++ ;
}
if (t == 3 )
continue ;
if (flag == 2 )
++ get ;
}
return get ;
}

int DP( int state)
{
if (dp[state] != MIN)
return dp[state];
int i,t,MAX = MIN;
for (i = 0 ;i < 18 ;i ++ )
{
if ( ! (state & pow[i]))
{
t
= Cal(i,state);
t
+= (t > 0 ? 1 : - 1 ) * DP(state | pow[i]);
MAX
= (t > MAX ? t:MAX);
}
}
dp[state]
= MAX;
return MAX;
}

void Solve( int ca)
{
int i,j,t,cnt = 0 ;
cin
>> m;
player
= 1 ;
state
= 0 ;
for (i = 0 ;i < m;i ++ )
{
cin
>> x >> y;
for (j = 0 ;j < 18 ;j ++ )
{
if (x == line[j][ 0 ] && y == line[j][ 1 ])
{
t
= Cal(j,state);
state
|= pow[j];
break ;
}
}
if (t)
cnt
+= player * t;
else
player
*=- 1 ;
}
cout
<< " Game " << ca << " : " << ((cnt + player * DP(state)) > 0 ? ' A ' : ' B ' ) << " wins. " << endl;
}

int main()
{
int i,T,tmp = 1 ;
cin
>> T;
for (i = 0 ;i < 18 ;i ++ )
{
pow[i]
= tmp;
tmp
*= 2 ;
}
fill(dp,dp
+ 600000 , - 10 );
dp[
0x3FFFF ] = 0 ;
for (i = 1 ;i <= T;i ++ )
{
Solve(i);
}
return 0 ;
}

 

你可能感兴趣的:(poj)