【題目鏈結】
【演算法】
首先,有乙個很顯然的結論 : 如果要使距離和最小,必須選擇相鄰的辦公樓配對
問題就轉化為了 : 有乙個包含(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
那麼,堆和鍊錶是可以解決這個問題的
【**】
#includeusingnamespace
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放到小根堆中,...