1 条题解
-
1
我写这道题的时候主要是考虑到了两点(
绝对和LYX说我写开他就唱歌这件事无关)写这道题的时候听到周围的同学说这道题有后效性,看了看确实是这个样子,这主要是因为题目里有一句话“然而它在某个单位时间如果叫了两声,下一单位时间必须保持沉默来休息”
如果能把这句话导致的“后效性”给去除掉的话就满足我们对动态规划的要求了,这时我们可能会联想到两道题(如果熟悉的话): 1.P412. 兔子繁殖(rabbit)这道题本质上是我们最熟悉的斐波那契数列,但正是这道题给了我们启发:f[i]=f[i-1]+f[i-2];我们在写DP时总是想要从前一个状态得来,但是我们是否忘记了前一个状态之前还有一个状态呢?(这在输出答案时也是一个坑)
2.P405. 偶数个3(problem1) 这道题的题解已经发表,它的“状态转移方程“是
f[i][0]=(f[i-1][0]*x+f[i-1][1]) f[i][1]=(f[i-1][1]*x+f[i-1][0])
这给我们的重要启示是:后效性有时可以被“消除”掉。正如这道“偶数个3”,你的选择会导致数字中3的由奇数->偶数/偶数->奇数,但是这道题通过一种奇妙的方法消除了这种后效性,这就是增加下标,即:状态转移方程有时不一定只有一个!!!状态转移的数组有时也不仅仅有一个!!!
如果你考虑了以上两点,那么想必状态转移方程也不难得出了
我选择开两个相同大小的数组:f[i][0]表示t=i时喵喵两声所能得到的最大值,f[i][1]表示t=i时本次不喵喵两声(即:叫一声或不叫)的最大值
这是状态的设定,下面就是状态转移方程了:
对于f[i][0],可以从两种选择中找出: ①上上次喵喵了两声,本次再喵喵两声,此时这个值是f[i-2][0]+v[i]^2 ②上次没有喵喵两声,本次喵喵两声,此时这个值是f[i-1][1]+v[i]^2
对于f[i][1],也可以从两种选择种找出: ①上上次喵喵了两声,本次选择喵一声或不喵(因为这个得到的值v[i]可能为负),此时为 f[i-2][0]+max(v[i],0) ②显然,同理,第二种情况: f[i-1][1]+max(v[i],0)
综上,整个状态转移方程就得出来啦:
//f[i][0]=max(f[i-2][0]+v[i]^2,f[i-1][1]+v[i]^2) //f[i][1]=max(f[i-2][0]+max(v[i],0),f[i-1][1]+max(v[i],0))
那么就剩下边界(初始条件)和输出答案了!这也是易错的!!!
f[1][0]=max2(v[1]*v[1],0);//因为有平方,所以叫最好 f[1][1]=max2(v[1],0);//选择叫或不叫 f[2][0]=f[1][1]+max2(v[2]*v[2],0); f[2][1]=f[1][1]+max2(v[2],0);
注意输出时你除了要比较f[t][0],f[t][1]的大小,还需要比较一下f[t-1][0]的大小,因为这个值最后没有被调用过,也就意味着它可能比前两个值大!!!注意!!!这里会卡掉50分!!!
写了半个小时,这篇题解就到这里了!NOIP2023 RP++!
(另外,LYX快给我唱歌) 2023.11.11 22:25
- 1
信息
- ID
- 859
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 51
- 已通过
- 5
- 上传者