貪心 均分紙牌

2021-09-10 09:38:37 字數 1410 閱讀 8241

題目鏈結

題目描述

有n堆紙牌,編號分別為 1,2,…,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。

移牌規則為:在編號為1堆上取的紙牌,只能移到編號為2的堆上;在編號為n的堆上取的紙牌,只能移到編號為n−1的堆上;其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。

現在要求找出一種移動方法,用最少的移動次數使每堆上紙牌數都一樣多。

例如n=4,4堆紙牌數分別為:

①9②8③17④6

移動3次可達到目的:

從 ③ 取4張牌放到 ④ (9,8,13,10)-> 從 ③ 取3張牌放到 ②(9,11,10,10)-> 從 ② 取1張牌放到①(10,10,10,10)。

輸入兩行

第一行為:n(n 堆紙牌,1≤n≤100)

第二行為:a1​,a2​,…,an​ (n堆紙牌,每堆紙牌初始數,1≤ai​≤10000)

輸出

一行:即所有堆均達到相等時的最少移動次數。

輸入樣例

4

9 8 17 6

輸出樣例

3
分析

這是乙個比較典型的貪心

首先我們求出目標狀態每堆牌的數量s,然後用s更新每堆牌。如樣例,s = 10,更新後為-1,-2,7,-4。

然後,我們用乙個很巧妙的思路,我們可以認為第一堆上有-1張牌,第二堆上有-2張牌,一次類推。每次我們把當前位置上的牌數移動到下乙個位置,直到某個位置牌數為0。

也就是說,用乙個陣列 q[110] 存下更新後的序列,每次進行q[ i + 1] += q[ i ]; q[ i ] = 0;的操作。

這裡還可以加上乙個小優化,針對特殊情況開始或者結尾有很多個0,我們把頭指標指向序列中第乙個不為0的數,尾指標指向序列中最後乙個不為0的數。這樣做可能對絕大多數情況起不了什麼結果,但對於特殊情況就可以提速不少。

就是這樣。

**

#includeusing namespace std;

int a[107];

int s, ans;

int main()

s /= n;

for (int i = 1; i <= n; i++)

int i = 1, j = n;

while (a[i] == 0 && i < n) i++;

while (a[j] == 0 && j > 1) j--;

while (i < j)

cout << ans;

return 0;

}

貪心 均分紙牌

時間限制 1 sec 記憶體限制 64 mb 提交 164 解決 95 提交 狀態 討論版 有n堆紙牌,編號分別為1,2,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為1堆上取的紙牌,只能移到編號為2的堆上 在編號為n的堆上取的紙牌,只能移到編...

均分紙牌(貪心)

有n堆紙牌,編號分別為1,2,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為1的堆上取的紙牌,只能移到編號為2的堆上 在編號為n的堆上取的紙牌,只能移到編號為n 1的堆上 其他堆上取的紙牌,可以移到相鄰左邊或右邊的堆上。現在要求找出一種移動方法...

codevs均分紙牌 貪心演算法

題目描述 description 有 n 堆紙牌,編號分別為 1,2,n。每堆上有若干張,但紙牌總數必為 n 的倍數。可以在任一堆上取若於張紙牌,然後移動。移牌規則為 在編號為 1 堆上取的紙牌,只能移到編號為 2 的堆上 在編號為 n 的堆上取的紙牌,只能移到編號為 n 1 的堆上 其他堆上取的紙...