1 条题解

  • 1
    @ 2023-11-11 22:26:02

    我写这道题的时候主要是考虑到了两点(绝对和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

    • @ 2023-11-12 9:47:35

      LYX:我不背这个锅!!你找出题人唱歌罢。

    • @ 2023-11-14 21:28:10

      我不会告诉你那首歌不止给你听了😕

    • @ 2023-11-14 21:35:19

      @你怎么能这样👀️

  • 1

信息

ID
859
时间
1000ms
内存
256MiB
难度
9
标签
递交数
51
已通过
5
上传者