CTSC 2007 資料備份

2022-05-05 02:21:12 字數 1587 閱讀 8506

【題目鏈結】

【演算法】

首先,有乙個很顯然的結論 : 如果要使距離和最小,必須選擇相鄰的辦公樓配對

問題就轉化為了 : 有乙個包含(n-1)個數的序列,在這(n-1)個數中選k個,相鄰的數不能選,使得和最小

考慮這個序列中最小的元素,我們發現,如果選這個數,那麼與它相鄰的兩個數都不能選,如果不選,那麼與它相鄰的兩個數都要選

因此, 我們可以選出序列中最小的元素di,將di-1和di+1刪除,將di-1+di+1-di加入,問題就轉化為了在現在的序列中找到(k-1)個數,相鄰的數不能選,使得和最小,這樣,如果沒有選di-1+di+1-di這個數,說明選di是最優策略,否則說明不是最優策略,

答案正好將di減去,加上了di-1+di+1

那麼,堆和鍊錶是可以解決這個問題的

【**】

#includeusing

namespace

std;

#define maxn 200010

const

long

long inf =1e10;

inti,n,k;

intpre[maxn],nxt[maxn];

long

long

s[maxn],d[maxn];

bool

visited[maxn];

long

long

ans,val;

struct

info

tmp;

class

heap

inline

void up(int

x)

}inline

void down(int

x)

}inline

void

insert(info x)

inline

void

del()

inline info

get()

} h;

intmain()

); }

d[0] = d[n] =inf;

for (i = 1; i <= k; i++)

ans +=tmp.d;

h.del();

visited[pre[tmp.pos]] = true

; visited[nxt[tmp.pos]] = true

; d[tmp.pos] = d[pre[tmp.pos]] + d[nxt[tmp.pos]] -tmp.d;

nxt[pre[pre[tmp.pos]]] =tmp.pos;

pre[tmp.pos] =pre[pre[tmp.pos]];

pre[nxt[nxt[tmp.pos]]] =tmp.pos;

nxt[tmp.pos] =nxt[nxt[tmp.pos]];

h.insert((info));

}printf(

"%lld\n

",ans);

return0;

}

BZOJ1150 CTSC2007 資料備份

堆 題目傳送門 顯然,這題用貪心轉化一下題意就是給你 n 1 個數,選 k 個不相鄰的數權值和最小。假設最小值是 a x 那麼選完 a x 之後 a 和 a 就不能選了。如果 a 和 a 只選了某乙個,顯然把這個換成 a x 更優。所以最優解要麼有 a x 沒有 a 和 a 要麼同時有 a 和 a ...

BZOJ1150 CTSC2007 資料備份

你在一家 it 公司為大型寫字樓或辦公樓的計算機資料做備份。然而資料備份的工作是枯燥乏味的,因此你想設計乙個系統讓不同的辦公樓彼此之間互相備份,而你則坐在家中盡享計算機遊戲的樂趣。已知辦公樓都位於同一條街上。你決定給這些辦公樓配對 兩個一組 每一對辦公樓可以通過在這兩個建築物之間鋪設網路電纜使得它們...

APIO CTSC 2007 資料備份

嘟嘟嘟 這竟然是一道貪心題,然而我在不看題解之前一直以為是dp。首先最優的配對一定是相鄰兩個建築物配對,所以我們求出差分陣列,就變成了在n 1個數中選出不相鄰的k個數,使這k個數的和最小。貪心是在回事呢?首先把所有點放在乙個小根堆中,然後如果取出乙個點ai,就把ai 1 ai 1 ai放到小根堆中,...