左右端模型:通過不斷地在序列兩端追加元素的情形
為了在即將到來的晚會上有更好的演出效果,作為 aaa 合唱隊負責人的小 a 需要將合唱隊的人根據他們的身高排出乙個隊形。假定合唱隊一共 nn 個人,第 ii 個人的身高為 h_ihi 公尺(1000 \le h_i \le 20001000≤hi≤2000),並已知任何兩個人的身高都不同。假定最終排出的隊形是 aa 個人站成一排,為了簡化問題,小 a 想出了如下排隊的方式:他讓所有的人先按任意順序站成乙個初始隊形,然後從左到右按以下原則依次將每個人插入最終棑排出的隊形中:
當 n 個人全部插入當前隊形後便獲得最終排出的隊形。
例如,有 66 個人站成乙個初始隊形,身高依次為 1850, 1900, 1700, 1650, 1800, 17501850,1900,1700,1650,1800,1750,
那麼小 a 會按以下步驟獲得最終排出的隊形:
因此,最終排出的隊形是 1750, 1650, 1700, 1850, 1900, 18001750,1650,1700,1850,1900,1800。
小 a 心中有乙個理想隊形,他想知道多少種初始隊形可以獲得理想的隊形。
請求出答案對 1965082719650827 取模的值。
第一行乙個整數 nn。
第二行 nn 個整數,表示小 a 心中的理想隊形。
輸出一行乙個整數,表示答案 \bmod 19650827mod19650827 的值。
輸入 #1複製
4
1701 1702 1703 1704
輸出 #1複製
8
對於 30\%30% 的資料,n \le 100n≤100。
對於 100\%100% 的資料,n \le 1000n≤1000,1000 \le h_i \le 20001000≤hi≤2000。
分析:
(官方題解)
如何設計狀態
那麼我們要怎麼設計狀態,我們想,每給人進入隊伍裡,只有2種可能,1種是從左邊加入,另外1種是從右邊進入,所以我們的裝態是有3個數
f[i][j][0]f[i][j][0]表示的是第ii人從左邊進來的方案數
f[i][j][1]f[i][j][1]表示的是第jj人從右邊進來的方案數
推導狀態轉移方程
從左邊進來肯定前1個人比他高,前1個人有2種情況,要麼在i+1i+1號位置,要麼在jj號位置。
同理從右邊進來肯定前1個人比他矮,前1個人有2種情況,要麼在j-1j−1號位置,要麼在ii號位置。
那麼狀態轉移方程就出來了
注:這裡的i和j均為邊界,注意i=j的時候,只初始化一邊
**:
#include using namespace std;
typedef long long ll;
//typedef __int128 lll;
#define print(i) cout << "debug: " << i << endl
#define close() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define mem(a, b) memset(a, b, sizeof(a))
const ll mod = 19650827;
const int maxn = 2e6;
const int inf = 0x3f3f3f3f;
int v[1010];
ll dp[1010][1010][2];
int main()
cout << (dp[1][n][0] + dp[1][n][1]) % mod << endl;
}
POJ 3042 區間dp 左端點右端點01
題意 在一維座標系下,給定n個草坪的座標 1 n 1000 再給定起點l 1 l 1e6 每個草坪有乙個staleness值,初始化為0。每次走一格,所有的staleness值 1,並且要從起點遍歷每乙個草坪,求staleness值的最小值。離散化處理n個點 dp i j 0 區間 i,j 已經遍歷...
分別標記區段的 飛鴿傳書 左 右端
分別標記區段的 飛鴿傳書 左 右端點座標為xleft和xright 4 分別檢查與當前掃瞄線相鄰的y 1和y 1兩條掃瞄線在區間 xleft,xright 中的畫素,從xleft開始向xright方向搜尋,若存在非邊界且未填充的畫素點,則找出這些相鄰的畫素點中最右邊的乙個,並將其作為種子點壓入棧中,...
線性dp 區間dp
1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...