poj1769 线段树优化的dp
生活随笔
收集整理的這篇文章主要介紹了
poj1769 线段树优化的dp
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
附上這道題的鏈接:http://poj.org/problem?id=1769
題目的意思是有一個裝置可以輸出n個數(shù)的最大值, 這個裝置由m個排序器組成, 每個排序器可以將這n個數(shù)從s 到 t的數(shù)按照從小到大的順序排列, 有一個人發(fā)現(xiàn)將m個排序器中的一些排序器去掉仍然不影響功能, ?現(xiàn)在問你最少需要多少個排序器可以完成功能。 我們可以定義dp[i][j]為前i個排序器將第1個數(shù)提到j(luò)所需要的最少的排序器的數(shù)量, 那么當t[i] == j的時候 dp[i][j] = min(dp[i-1][j] , min(dp[i-1][si -- ti]) + 1) ?當ti != j的時候 dp[i][j] = dp[i-1][j], ?我們觀察狀態(tài)數(shù)有m*n個, 顯然直接求解會超時, 因此我們考慮使用線段樹來優(yōu)化 ?見挑戰(zhàn)程序設(shè)計 p207 , 代碼如下:
#include <cstdio> #include <cstring> #include <algorithm>using namespace std; const int maxn = 500000 + 100; const int inf = 0x3f3f3f3f; int n, m;struct segment{int l, r;int x; }seg[3*maxn];void build(int rt, int l, int r) {seg[rt].l = l; seg[rt].r = r;if(l == r) {int value = inf;if(l == 1) value = 0;seg[rt].x = value;return ;}int chl = 2*rt, chr = 2*rt + 1;int mid = (l + r) / 2;build(chl, l, mid);build(chr, mid+1, r);seg[rt].x = min(seg[chl].x, seg[chr].x); }int query(int rt, int l, int r) {if(seg[rt].l == l && seg[rt].r == r) {return seg[rt].x;}int mid = (seg[rt].l + seg[rt].r)/2;if(r <= mid)return query(2*rt, l, r);else if(l > mid)return query(2*rt+1, l, r);else{int v1 = query(2*rt, l, mid);int v2 = query(2*rt+1, mid+1, r);return min(v1, v2);} }void update(int rt, int i, int c) {if(seg[rt].l==seg[rt].r && seg[rt].l == i) {seg[rt].x = c;return ;}int mid = (seg[rt].l + seg[rt].r)/2;if(i <= mid)update(2*rt, i, c);elseupdate(2*rt+1, i, c);seg[rt].x = min(seg[2*rt].x, seg[2*rt+1].x); }int main() {while(scanf("%d%d", &n, &m) != EOF) {build(1, 1, n);for(int i=0; i<m; i++) {int s, t;scanf("%d%d", &s, &t);int v1 = query(1, s, t) + 1;int v2 = query(1, t, t);int v3 = min(v1, v2);update(1, t, v3);}printf("%d\n", query(1, n, n));}return 0; }?
轉(zhuǎn)載于:https://www.cnblogs.com/xingxing1024/p/5487428.html
總結(jié)
以上是生活随笔為你收集整理的poj1769 线段树优化的dp的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jquery基本操作笔记
- 下一篇: iOS学习之CoreLocation相关