1. 程式人生 > >CF1016C Vasya And The Mushrooms 題解

CF1016C Vasya And The Mushrooms 題解

agg 有趣 ase iar oom 就是 每次 lov dsi

這道題一眼就是一個DP(大霧),但題目中有一句很有趣的話

“He wants to visit all the cells exactly once and maximize the total weight of the collected mushrooms.”

也就是每個格子必須且只能經過一次,而且只有兩派格子,所以是不是一目了然的只有兩種行走路線。

技術分享圖片 技術分享圖片

其實不然,你還可以這麽走

技術分享圖片或者,這麽走技術分享圖片

也就是把前兩種行走方式結合一下

技術分享圖片 技術分享圖片

不過也沒有變得不可做,因為一定是先用第一種行走方式,再接第二種;不可能存在先走第二種,再第一種的情況(都已經拐回去了,還走啥啊)。所以枚舉一下從何時開始更換行走方式即可。這兩種行走方式

吃到的蘑菇都可以先預處理出來。

a1是第一行的蘑菇生長率,a2是第二行的

因為觀察到無論從何時改變行走方式,都可以看成是在走完一個整列後再改變,所以所有的數組都是以列數作為下標的。

首先預處理蛇形行走方式:

兩行兩行處理,每次走一個U型,要註意蘑菇不是從第1秒開始長的(其實是時間是從 0 s 開始記的,不過一樣哈)

init_b(){
    //b[i]表示蛇形在取完第i列的格子的蘑菇後的 
    //第一個格子為第1s(但不吃蘑菇)
    //這個格子蘑菇數為(i-1)*a 
    int s=0;
    for(int i=1;i<=n;i+=2){
        s+=a1[i]*(i*2
-2); s+=a2[i]*(i*2-1); b[i]=s; s+=a2[i+1]*(i*2); s+=a1[i+1]*(i*2+1); b[i+1]=s; //走了一個U型 ↓→↑ }//走了一個S型 }

再預處理環形行走方式:

技術分享圖片這樣的一條路可以看成是技術分享圖片的一條路加上藍色的兩個格子的蘑菇。

不過原來路上的每只蘑菇都多生長了 1 s,所以要加一個“後綴和”。

init_S(){
    //S[i]表示從第i列(從左往右數)以及右邊的半圈的蘑菇生長率之和 
    int s=0;
    for(int
i=n;i>=1;i--) s+=a1[i]+a2[i],S[n-i+1]=s; }

如果是從上繞到下,上面的格子生長時間是1s,下面的格子生長時間是後面的兩列格子數+上面的一個格子=(l*2+1),l 是後面的長度;

CF1016C Vasya And The Mushrooms 題解