社團四連測之第一測 Monkey

2021-09-03 08:29:28 字數 1776 閱讀 3950

目錄題目

解題思路 **

題目描述

有q只猴子要從第一棵樹到第n棵樹去,第i只猴子一次跳躍的最遠距離為ki。如果它在第x棵樹,那它最遠可以跳到第x+ki棵樹。如果第j棵樹的高度比第i棵樹高或相等,那麼它從第i棵樹直接跳到第j棵樹,它的勞累值會增加1。所有猴子一開始在第一棵樹,請問每只猴子要跳到第n棵樹花費的勞累值最小。

輸入

第一行乙個整數n,表示有n棵樹。(2<=n<=1000000),接下來第二行給出n個正整數d1,d2,……,dn(1<=di<=10^9),其中di表示第i棵樹的高度。第三行給出了乙個整數q(1<=q<=25),接下來q行,給出了每只猴子一次跳躍的最遠距離ki(1<=ki<=n-1)。

輸出

輸出q行,每行乙個整數,表示乙隻猴子的最小的勞累值。

樣例輸入

9

4 6 3 6 3 7 2 6 522

5

樣例輸出

2

1

可以看到,這裡所有的題都是dp,所以,這裡就只考慮dp怎麼實現正解。

可以看到,令dp[i] 是為到第i棵樹時前面最小的疲勞值,轉移方程可以很快地得到:dp[i] = min (dp[k] + (h[k] <= h[i]));

這裡的h[k] <= h[i] 也就是說如果第k棵樹比第i棵樹相等的話就會加1(詳見題目)。

然後k的取值也是i - k[i] <= k < i,也就是往前列舉。或許會有人說了,這樣的時間複雜度不就是 o (

別慌別慌,這不是就到主題了嗎——用單調棧、佇列來優化dp。

我們可以用單調上公升的佇列來儲存從i - k[i] ~ i 之間的最小值,把它賦給dp[i],再把dp[i]放到合適的位置,不就萬事大吉了嗎!

當然,這裡還有乙個小問題,將dp[i]放到合適的位置時,如果dp[i]大於了隊尾,那麼就直接放到它後面就行了;如果是小於,就一直到比它還小的元素後面;

可是如果是等於呢?

仔細想想可以想到,越高的樹是越有潛力的,在後面的作用更大。所以如果是隊尾的高度小於了該高度,那麼也直接踢掉,否則就加到後面去。

#include #include #include using namespace std;

#define maxn 1000000

#define inf 0x3f3f3f3f

int n, d[maxn + 5], q, k[maxn + 5], dp[maxn + 5];

deque d;

void clear ()

void read (int &x)

}void print (int x)

if (x / 10)

print (x / 10);

putchar (x % 10 + 48);

}int main ()

}int x = d.front ();

dp[j] = dp[x];

if (d[j] >= d[x])

dp[j] ++;

while (!d.empty ())

}d.push_back (j);

}print (dp[n]);

putchar ('\n');}}

退役四連測題解(一)

有q只猴子要從第一棵樹到第n棵樹去,第i只猴子一次跳躍的最遠距離為ki。如果它在第x棵樹,那它最遠可以跳到第x ki棵樹。如果第j棵樹的高度比第i棵樹高或相等,那麼它從第i棵樹直接跳到第j棵樹,它的勞累值會增加1。所有猴子一開始在第一棵樹,請問每只猴子要跳到第n棵樹花費的勞累值最小。第一行乙個整數n...

BZOJ NOI十連測 第一測 T1

思路 首先考慮t 1的情況,t等於1,那麼所有位置的顏色相同,我們不用考慮概率的問題,那麼,k d x在模d下都相等,我們考慮預處理乙個陣列s i j 代表d為i,起始位置為j的等差數列的和,這個可以證明,當模小於等於sqrt n 的時候可以完美解決,時間複雜度為n 1.5,對於d大於sqrt n ...

校內八連測 第一試

這場比賽。t1 給出乙個長度為n的序列,將序列分成若干段,使得每一段都為不公升或者不降的序列。求所分成最小的段數。直接上貪心好吧。好無聊這道題。t2 乙個長度為n的序列,一開始為1,2,3 n,有兩種操作。保證n為偶數 1 x是將整個序列都往右移x距離。比如1 2 就把1 2 3 4 5 6 變成5...