开始看到这道题知道要用dp,但这个六边形的确很恶心,每次坐标的偏移量无法用二维数组完整表现出来,后经过看多方题解,明白了可以取八个方向中的六个,解决了构图的问题,至于状态转移是很明显的。dp[s][i][j]表示经过s步到达坐标为[i][j]的位置的路径数:
则dp[s][i][j] = dp[s-1][i-1][j-1]+dp[s-1][i][j-1]+dp[s-1][i+1][j]+dp[s-1][i+1][j+1]+dp[s-1][i][j+1]+d[s-1][i-1][j];
然后进行扫描就可得到dp[n][sta_r][sta_c]就是为每次要求的答案(sta_r,sta_c为假设的中心坐标,这里设定为sta_r=15,sta_c = 15);
第一道真正意义的dp,纪念一下O(∩_∩)O
#include < iostream >
#include < cstring >
using namespace std;
int dp[ 17 ][ 30 ][ 30 ],sta_r = 15 ,sta_c = 15 ;
int move[ 6 ][ 2 ] = {{ - 1 , - 1 },{ 0 , - 1 },{ 1 , 0 },{ 1 , 1 },{ 0 , 1 },{ - 1 , 0 }};
int main()
{
int t,n,i,r,c,k;
cin >> t;
memset(dp, 0 , sizeof (dp));
dp[ 0 ][sta_r][sta_c] = 1 ;
for (i = 1 ;i < 15 ; ++ i)
{
for (r = 0 ;r < 30 ; ++ r)
{
for (c = 0 ;c < 30 ; ++ c)
{
for (k = 0 ;k < 6 ; ++ k)
{
int cur_row = r + move[k][ 0 ];
int cur_col = c + move[k][ 1 ];
dp[i][r][c] += dp[i - 1 ][cur_row][cur_col];
}
}
}
}
while (t -- )
{
cin >> n;
cout << dp[n][sta_r][sta_c] << endl;
}
return 0 ;
}