CH 5302 金字塔(區間DP)

2022-04-28 19:30:13 字數 1205 閱讀 3651

很神奇的一道題目,當時看到還以為是一道字串求回文子串的題目。但是資料範圍很小,而且只知道回文串也不好做。但是我們觀察可得,如果是深度搜尋便利,那麼它經過的子樹應該是從左到右排列有序的,於是我們想到線性dp。然後我們發現似乎可以單獨求某一段的便遍歷方式然後合併,這就是區間dp的標誌啊!於是我們考慮設 $ f[l][r] $ 表示從第 $ l $ 到第 $ r $ 個字元可以有的子樹遍歷方案(注意既然是子樹遍歷方案,那麼 $ l $ 字元和 $ r $ 的字元一致,因為它們都表示是這顆子樹的根節點 )。但是這樣我們的轉移需要保證不重不漏的計算左右情況。

這裡很重要:(可能**很好碼,但原理我們不能模糊帶過!)根據經驗我們要找乙個基準點來保證不重不漏,而常規套路就是列舉乙個分段 $ k $ (注意我們的這個 $ k $ 的字元要和兩端字元一樣!因為當前子樹需要根!)使得 $ [l,k] $ 為第一顆子樹(注意這顆子樹此時還連著根)而 $ [k,r] $ 這一段是另外的隨便什麼遍歷方式,於是我們需要保證 $ [l,k] $ 為一顆子樹(因為它現在還連著根),不能讓它劃分為連著根的多顆子樹的形式,於是我們強制連邊使 $ [l+1,k-1] $ 為一顆真正的不連邊的子樹,而強制連的邊就是 $ e(l,l+1) $ 或者說 $ e(r,r-1) $ 。於是我們需要保證 $ l+1 $ 的字元和 $ k-1 $ 的字元一致(因為它們都表示是這顆子樹的根節點)。然後我們就可轉移了!

$ f[l][r]=\sum^_ _ $

#include#include#include#include#include#include#include#include#include#include#include#include#define ll long long

#define db double

#define inf 0x7fffffff

#define rg register int

using namespace std;

const int mod=1e9;

int n;

int f[305][305];

string s;

inline int qr()

inline int solve(int l,int r)

int main()

python 金字塔 Python金字塔

托倫,函式中有幾個小錯誤和乙個邏輯問題print y to a 請注意,此函式生成乙個以z開頭的字串,但您希望將字串以相反的方向連線,而您的另乙個函式print a to y 確實停止了 1位置 例如 還要注意,您需要新增新行字元 n 以獲得一些不錯的輸出。在 我的解決方案是 def print a...

字母金字塔(類同數字金字塔)

問題描述 讓程式要求使用者輸入乙個大寫字母,使用巢狀迴圈產生像下面這樣的金字塔圖案 aaba abcba abcdba abcdecba 演算法分析 每行包括三個部分內容 若干個空格 正序排列的字母 倒序排列的字幕。使用乙個外部迴圈來處理行,在每乙個行中使用三個內部迴圈 乙個處理空格,乙個以公升序列...

數字金字塔

觀察下面的數字金字塔。寫乙個程式來查詢從最高點到底部任意處結束的路徑,使路徑經過數字的和最大。每一步可以走到左下方的點也可以到達右下方的點。7 3 8 8 1 0 2 7 4 4 4 5 2 6 5在上面的樣例中,從7 到 3 到 8 到 7 到 5 的路徑產生了最大 多組輸入資料 第乙個行包含 r...