HydroOJ 每日一題 003

2022-09-09 15:57:30 字數 2391 閱讀 8640

\[\large\texttt

\]hydrooj 每日將從 hydrooj 主題庫及各大域中選出一題附以詳解在此處分享給各位使用者。

[coci2016-2017 contest#7 t6] kl**ir

題目傳送門

首先讀懂題意,我們發現,對於當前正在彈奏的一段樂曲,有以下兩種情況:

第二種情況比較簡單,對於第二種情況,那麼有:

\[dp_i=dp_+\frac+\frac\times(dp_i-dp_1+1)+\frac\times(dp_i+1)

\]\[\rightarrow dp_i=n\times dp_

\]其中,第乙個 \(\frac\) 表示第 \(i\) 個音符直接彈奏正確的期望,\(\frac\times(dp_i-dp_1+1)\) 表示這個音符彈奏錯誤,但與第乙個音符相同的期望,\(\frac\times(dp_i+1)\) 表示這個音符彈奏錯誤,同時與第乙個音符不同的期望。

樣例三對應的就是這種情況。

3

31 2 3

3

927

接下來討論第一種情況。

前字尾顯然可以用 kmp 預處理處理。

設已經彈奏了 \(1\to i\),現在要彈奏第 \(i+1\) 個音符。列舉當前彈奏音符 \(j\)。彈錯時,需要找到最長的已經彈對的字首,記為 \(k_j\),於是有:

\[dp_=dp_i+\frac+\frac\times\sum\limits_^n(dp_-dp_+1)(j\neq a_)

\]\[\rightarrow dp_=dp_i+n+\sum\limits_^n(dp_-dp_)(j\neq a_)

\]其中 \(\frac\times\sum\limits_^n(dp_-dp_+1)(j\neq a_)\) 表示彈錯了,但已經彈對字首 \(1\to k\),接著從 \(k+1\) 彈到 \(n+1\) 的期望。兩層迴圈跑一下就完了。時間複雜度 \(\mathcal(n\times m^2)\),實測可過(大概是機子跑得快的原因)。

dp[1] = n;

f(i, 1, m)

}dp[i + 1] = (s + n + dp[i]) % mod;

}

雖然可過,但理論上還是蠻卡的。接下來我們考慮優化。

我們記當前為第 \(i\) 個音符,下乙個音符是 \(j\) 時,最終跳到的位置為 \(f_\),那麼 \(f_\) 和 \(f_\) 只有在 \(j=a_\) 時是不同的。因此對於 \(dp_\) 可以直接繼承 \(dp_}\) 的答案,再額外計算 \(j=a_\) 的貢獻即可。從上面方法中,可以看出 \(j=a_\) 的貢獻就是 \(n^\)。

綜上可得:

\[dp_i=dp_+n^i

\]時間複雜度 \(\mathcal(m)\),算是十分優秀了。

#include #define reg register

#define ll long long

#define _min(x, y) ((x) < (y) ? (x) : (y))

#define _max(x, y) ((x) > (y) ? (x) : (y))

#define min(x, y) ((x) > (y) and ((x) = (y)))

#define max(x, y) ((x) < (y) and ((x) = (y)))

#define f(i, a, b) for (reg int i = (a); i <= (b); ++i)

#define pf(i, a, b) for (reg int i = (a); i >= (b); --i)

#define for(i, x) for (reg int i = head[(x)]; i; i = net[(i)])

using namespace std;

bool beginning;

inline int read();

const int n = 1e6 + 5, mod = 1e9 + 7;

int n, m, a[n], fail[n];

inline void init()

}bool ending;

int main()

init();

int t = n;

f(i, 1, m)

return 0;

}inline int read()

while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();

return f ? x : -x;

}

macesuted 提供優化思路。/bx

LeetCode每日一題 003 盛最多水的容器

想法一 盛水最多,即左右兩邊中間區域的矩形面積最大,稱左側為a邊,右側為b邊。比較直觀的解法是,固定某一邊 如a邊 依次比較b邊選取哪乙個所框住區域面積最大。因此,可以比較選取不同a邊所能框住面積的最大值,從而得到所有可能情況的最大值,及窮舉法。可通過雙層迴圈求解。想法二 在想法一基礎上,思考固定a...

每日一題 1

題目詳情 peter喜歡玩數字遊戲,但數獨這樣的遊戲對他來說太簡單了,於是他準備玩乙個難的遊戲。遊戲規則是在乙個n n的 裡填數,規則 對於每個輸入的n,從左上角開始,總是以對角線為起點,先橫著填,再豎著填。這裡給了一些樣例,請在樣例中找到規律並把這個n n的 列印出來吧。輸入描述 多組測試資料 資...

每日一題2018 3 21

leetcode 2 模擬十進位制運算考察單鏈表基本操作。題無難點,個人基礎需要提高。definition for singly linked list.struct listnode class solution while p while q if shi val s next null ret...