我好久沒寫部落格了啊懶惰病上線,這個歡樂的節日聽了ha最強女選手講課,於是決定翹掉地理課寫篇部落格總結一下;
內容大致是中位數,先看一下圓神講課思路(這樣我可以少闡明很多概念)
第乙個就是引例啦:
貨倉選址
我們設在倉庫左邊的所有點,到倉庫的距離之和為p,右邊的距離之和則為q,那麼我們就必須讓p+q的值盡量小。pq,同理,所以當p=q時就是就是全域性的最優解;
排序之後找中位數;
#include usingview codenamespace
std;
int n,a[100010
];int
main()
cout
<< ans <
}
第二題:七夕祭;
題目大意:n行m列,t個感興趣的攤位,
交換相鄰的兩個攤位,使得每行每列中cl感興趣的攤位數量相同,特別注意的是,每一行的第乙個位置和最後乙個位置也是相鄰,判斷是否可行並且輸出需要移動的步數;
對於判斷是否可行,對行來說,如果t無法整除n,那麼行不可能達到目標,如果可以整除,我們的目標就是如何使每行中有t/n個感興趣的攤位;列也是如此,不過兩者一樣,我們就在這裡分析一種情況吧;
我們在這裡回想起一道經典的貪心題目「均分紙牌」:m個人排成一列,每個人手裡若干張牌c【i】,交換相鄰兩個使得每個人手裡的牌的數量相同;
如果可行(總數t整除m),每個人需要得到t/,m張牌,那麼需要的紙牌數為c【i】-t/m;每次i從i+1出拿牌,同時更新i+1,那麼我們的目標就是每個a【i】=c【i】-t/m=0;
另s【i】為a【i】的字首和,
#includeusingview codenamespace
std;
intmain()
q/=n;
for(int i=1;i<=n;i++)
int ans=0
;
for(int i=1;i<=n;i++)
cout
return0;
}
回到這個題,如果第乙個位置與最後乙個位置相鄰,那麼這是乙個環形的均分紙牌;
我們可以列舉斷點k,但我們不妨分析,a[i]仍為減去t/m後的陣列,當列舉到斷點k,字首和變為s【i】減去s【k】,那麼答案為∑|s【i】-s【k】|,那麼這個答案何時最小呢,就是上道題的貨倉選址,也就是中位數的時候,所以我們不需要列舉k,只需要排序後找中位數作為s【k】;這時就是最優解;
時間複雜度o(nlogn+mlogm);
#includeusingview codenamespace
std;
#define n 100010
#define ll long long template
inline void read(t &x)
while(isdigit(ch))
x*=f;
}ll n,m,t,x,y,h[n],l[n],f[n];
inline ll calc(ll b[n],
intn)
sort(f+1,f+n+1
);
for(int i=1;i<=n;i++) ans+=abs(f[i]-f[n+1>>1
]);
return
ans;
}int
main()
for(int i=1;i<=n;i++) h[0]+=h[i];
for(int i=1;i<=m;i++) l[0]+=l[i];
if(h[0]%n==0&&l[0]%m==0
)
else
if(h[0]%n==0
)
else
if(l[0]%m==0
)
else printf("
impossible");
return0;
}
最後一道題目啦:動態中位數:
讀入序列,為奇數時,輸出已讀序列中位數;
我們可以建立兩個堆,乙個大根堆乙個小根堆,對於乙個m長度的序列,從小打到1~m/2的放在大根堆,m/2+1~m的我們放在小根堆,這樣每次的小根堆的堆頂就是答案,任何時候如果乙個堆中的序列數過多,就從堆頂取出堆頂插入另乙個堆,每次插入x和中位數比較,如果x大,就插入大根堆,否則插入小根堆;
#include #includeview code#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
template
inline void read(t &x)
while(isdigit(ch))
x*=f;
}int
t,n,m,x;
vector
g;priority_queue
,greater >q1;
priority_queue
,less >q2;
inline
void add(int
x)
if(x>q1.top()) q1.push(x);
else
q2.push(x);
while(q1.size()>q2.size())
while(q2.size()>q1.size())
}int
main()
printf(
"%d %d\n
",n,(m+1)/2
);
for(int i=0;i)
putchar('\n
');}
return0;
}
君君演算法課堂 好題分享1
tarzan 非常煩數軸因為數軸上的題總是難度非常大。不過他非常喜歡線段,因為有關線 段的題總是不難,諷刺的是在乙個數軸上有 n 個線段,tarzan 希望自己喜歡的東西和討厭的 東西不在一起,所以他要把這些線段分多次帶走,每一次帶走一組,最多能帶走 k 次。其實 就是要把這些線段分成至多 k 組,...
演算法題 慶祝61
牛家莊幼兒園為慶祝61兒童節舉辦慶祝活動,慶祝活動中有乙個節目是小朋友們圍成乙個圓圈跳舞。牛老師挑選出n個小朋友參與跳舞節目,已知每個小朋友的身高h i。為了讓舞蹈看起來和諧,牛老師需要讓跳舞的圓圈隊形中相鄰小朋友的身高差的最大值最小,牛老師犯了難,希望你能幫幫他。如樣例所示 當圓圈隊伍按照100,...
程式設計題 慶祝61
題目 牛家莊幼兒園為慶祝61兒童節舉辦慶祝活動,慶祝活動中有乙個節目是小朋友們圍成乙個圓圈跳舞。牛老師挑選出n個小朋友參與跳舞節目,已知每個小朋友的身高h i。為了讓舞蹈看起來和諧,牛老師需要讓跳舞的圓圈隊形中相鄰小朋友的身高差的最大值最小,牛老師犯了難,希望你能幫幫他。如樣例所示 當圓圈隊伍按照1...