寫出轉移方程即可。
貢獻值計算有通用方法:記錄每乙個顏色上乙個位置,這個顏色只在上個位置到當前位置有貢獻,為1,這個可以通過線段樹做到。同樣,dp值也可以用線段樹查詢,所以我們把他們同時丟到一顆線段樹裡面就行了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#define up(i,a,b) for(int i=a;i#define dw(i,a,b) for(int i=a;i>b;i--)
#define upd(i,a,b) for(int i=a;i<=b;i++)
#define dwd(i,a,b) for(int i=a;i>=b;i--)
//#define local
typedef
long
long ll;
const
double esp =
1e-6
;const
double pi =
acos(-
1.0)
;const
int inf =
0x3f3f3f3f
;const
int inf =
1e9;
using
namespace std;
intread()
while
(ch >=
'0'&& ch <=
'9')
return x * f;
}typedef pair<
int,
int> pir;
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lrt root<<1
#define rrt root<<1|1
const
int n =
3e4+
5100
;int pre[n]
;int pos[n]
;int n, k;
int a[n]
;ll maxx[n<<2]
;ll lazy[n<<2]
;ll dp[n][55
];void
pushup
(int root)
void
build
(int l,
int r,
int root,
int dep)
int mid=
(l + r)
>>1;
build
(lson,dep)
;build
(rson,dep)
;pushup
(root);}
void
pushdown
(int root)
}void
update
(int l,
int r,
int root,
int lf,
int rt, ll val)
pushdown
(root)
;int mid =
(l + r)
>>1;
if(lf <= mid)
update
(lson, lf, rt, val);if
(rt > mid)
update
(rson, lf, rt, val)
;pushup
(root);}
ll querry
(int l,
int r,
int root,
int lf,
int rt)
pushdown
(root)
;int mid =
(l + r)
>>1;
ll ans =0;
if(lf <= mid)ans =
max(ans,
querry
(lson, lf, rt));
if(rt > mid)ans =
max(ans,
querry
(rson, lf, rt));
return ans;
}int
main()
upd(j,
1,k)
} cout << dp[n]
[k]<< endl;
return0;
}
CF833B 線段樹優化DP
將乙個長為 n 的序列分成 k 段,每段貢獻為其中不同數字的個數,求最大貢獻和。此處感謝 gxy001 聚銠的精彩講解 先考慮暴力dp,可以想到乙個時空複雜度 o n 2k 的方法,即記錄前i個數字分成了j段。我們現在來思考幾個問題來優化這個操作 對於乙個數字,它對那些地方實際有貢獻?每次分割出乙個...
cf474e Pillars 線段樹優化dp
有n個柱子,每個柱子有乙個高度hi h i,每個柱子可以跳到它後面高度與它相差大於d的柱子 即 h i hj d hi hj d 求最多可以跳多少個柱子an si m ax a nsj 1 hi h j d且 ja ns i ma x an sj 1 h i hj d且 j 因此建立一棵線段樹,節點...
線段樹優化dp
等離子炮有n個操作訊號,第i個操作訊號的強度為b i 總體強度為各操作訊號的強度之和。由於有些訊號太弱了了 強度 0 水寶寶想把它們刪除。但是水寶寶自己不會刪除訊號,所以他找來了同船的隊友幫忙。有 m位隊友,第ii 位隊友只會刪除編號在 l i 和 r i 之間的訊號,且每刪除乙個訊號,花費 c i...