P1573 题解报告
此题是经典四柱汉诺塔问题:
设 \(f_i\) 为所求前 \(i\) 步的最小步数,显然,当 \(i=1\) 时,\(f_i=1\);当 \(i=2\) 时,\(f_i=3\);如同经典汉诺塔一样,我们将移完盘子的任务分为三步:
-
将 \(x\) 个盘从 \(a\) 柱依靠 \(b\),\(d\) 柱移到 \(c\) 柱,这个过程需要的步数为 \(f_x\);
-
将 \(a\) 柱上剩下的 \(n-x\) 个盘依靠 \(b\) 柱移到 \(d\) 柱,这时移动方式相当于是一个经典汉诺塔,即这个过程需要的步数为 \(2^{(n-x)}-1\);
-
将 \(c\) 柱上的 \(x\) 个盘依靠 \(a\),\(b\) 柱移到 \(d\) 柱上,这个过程需要的步数为\(f_x\);
故完成任务所需要的步数即状态转移方程式为:\(f_i=\min(f_i,2\times f_x+2^{i-x}-1)\)
code:
dp[1]=1;
dp[2]=3;
for(int i=3;i<=n;i++)
{
for(int x=1;x<i;x++)
{
dp[i]=min(dp[i],2*dp[x]+pow(2,i-x)-1%1000007);
//cout<<x<<' '<<dp[i]<<'\n';
}
}
但显然不满足题目要求,此程序在 \(n=64\) 时就挂了。所以我们追求更高效的做法(起码是 \(\sqrt{n}\) 或 \(\log n\) 级别)
先用超时程序打一个表
1,3,5,9,13,17,25,33,41,49
观察这一列数:
\(1 = 2^0+0\)
\(3 = 2^1+1\)
\(5 = 2^1+3\)
\(9 = 2^2+5\)
\(13 = 2^2+9\)
\(17 = 2^2+13\)
\(25 = 2^3 +17\)
\(33 = 2^3+25\)
\(\dots\)
发现这个规律后可水过此题:
int k=1,d=1;
while(n>k)
{
n-=k;
ans=(ans+k*d)%mod;
k++;
d=(d+d)%mod;
}
ans=(ans+n*d)%mod;

浙公网安备 33010602011771号