P1573 题解报告

此题是经典四柱汉诺塔问题:

\(f_i\) 为所求前 \(i\) 步的最小步数,显然,当 \(i=1\) 时,\(f_i=1\);当 \(i=2\) 时,\(f_i=3\);如同经典汉诺塔一样,我们将移完盘子的任务分为三步:

  1. \(x\) 个盘从 \(a\) 柱依靠 \(b\)\(d\) 柱移到 \(c\) 柱,这个过程需要的步数为 \(f_x\)

  2. \(a\) 柱上剩下的 \(n-x\) 个盘依靠 \(b\) 柱移到 \(d\) 柱,这时移动方式相当于是一个经典汉诺塔,即这个过程需要的步数为 \(2^{(n-x)}-1\)

  3. \(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;
posted @ 2022-02-16 17:31  ㅤSmartBig  阅读(94)  评论(0)    收藏  举报