題目大意
給定我們乙個陣列,對於位置x你每次可以執行兩種操作。
1.向右移動乙個單位,x = x + 1
2.向左移動乙個單位,x = x - 1
但是有規定,你一共可以執行 k 次操作,且這 k 次操作種操作2做多只能執行 z 次 , 且操作2不能被連續執行。
分析解法一 : 動態規劃方法
一開始思考用貪心的思路去解決,但是沒有想到合適的貪心策略,於是作罷。後來開始往dp方面想。
狀態表示:
$f(i , q) $表示當前位置 i 並且使用了 q 次左移的最大價值
狀態計算:
對於當前位置 i , 如果我們當前使用 q 次想左邊移動的機會。那麼
\(f(i , q) = max(f(i , q) , f(i-1,q - j) + s + a[i])\)
那麼對於公式種的j 和 s是怎麼回事呢
j 表示在最多右移q次的情況下當前移動了j次 \(0\le j \le q\)
由於我們只能向左移不超過1次,那麼我們一定是在位置 i / i - 1 之間不停搖擺
對於q - j :
假設我們當前為\(f(i , 3)\)
那麼其一定可以由以下三種情況轉移過來
\(f(i-1 , q - j)\)表示在位置 i 有q次機會左移的情況從第i - 1種狀態的第q - j 種轉移過來
一開始公式中的\(s = j * (a[i] + a[i-1])\) 表示向左移動 j 次所能獲得的收益
注意事項
ac **
c++ code
const int n = 100005;
int test;
int dp[n][6];
void slove()
} cout << ans + a[1] << endl;// 因為一開始站在 a[1]
}
解法二:貪心方法
貪心策略
對於乙個貪心問題,最重要的莫過於貪心策略的選擇,即每次只貪婪的選擇當下對自己最有利的情況。
我們需要求出對於每乙個位置不停的向左再向右移動所能夠獲取的最大價值。
code
void slove2()
cout << ans << endl;
}
線性dp 區間dp
1 尼克的任務 額一道挺水的題,愣是做了幾個小時 動態規劃大致的思路還是找乙個轉移 換個詞就是影響 我們可以明顯看出本題的規則 空暇時,一遇到任務必須挑乙個接 求1 n時間內最大空暇時間 所以將任務排序是必要的,兩個關鍵字 再來想象一下當我做到第i 個任務時,我在 st i st i t i 1 時...
DP基礎(線性DP)總結
前言 雖然確實有點基礎.但凡事得腳踏實地地做,基礎不牢,地動山搖,嗯!dp方程 dp i max 複雜度 o n 2 法一 資料結構無腦暴力優化 以a i 為陣列下標,從1到a i 訪問最大值,再加一,進行更新 法二 設h k 表示dp值為k的最長上公升子串行的最小值 有點貪心在裡面 顯然h k h...
線性DP 餅乾
第一次做這種處理方法的dp,這道題我們是先在乙個大的可行方案集合中確定乙個小的子集,這個子集也滿足這個方案。我們根據排序不等式 可以自己查一下,證明過程很簡單。可以知道,如果乙個序列式g ig i gi 是公升序的。a ia i ai 是降序的。那麼我們ai gi a i g i ai gi 的和一...