题目大意:有n个槽的锁,每个槽高度为1,2,3,4,但要求至少有两个槽高度差为3并且至少用三种高度的槽。
分析:网上有搜索和dp两种做法,其中dp的做法都比较复杂,现给出一个简单的dp方法。
用dp[i][j]表示第i个槽为j的1,4不相邻方法数,考虑到槽1与4,2与3是对称的,故
dp[i][1] = dp[i][4],
dp[i][2] = dp[i][3]
因此只用求dp[i][1]和dp[i][2]。不同于网上见到的做法,当考虑1,4不相邻状态时,状态转移方程很简单:
dp[i][1] = dp[i + 1][1] + dp[i + 1][2] * 2,
dp[i][2] = dp[i + 1][1] * 2 + dp[i + 1][2] * 2
求出dp之后,4^n - (dp[1][1] * 2 + dp[1][2] * 2)即为1,4相邻的方法数,而1,4相邻但槽数量小于3只能是由槽1,4构成的序列,其数量为2^n - 2,故关键代码为:
dp[n][1] = dp[n][2] = 1;
for (int i = n - 1; i >= 1; i--)
{
dp[i][1] = (dp[i + 1][2] << 1) + dp[i + 1][1];
dp[i][2] = (dp[i + 1][1] << 1) + (dp[i + 1][2] << 1);
}
ans = (1LL << (n << 1)) - ((dp[1][1] + dp[1][2]) << 1) - (1 << n) + 2;