洛谷 P1031 均分紙牌 (貪心思想)

2021-09-01 00:14:34 字數 1490 閱讀 1303

均分紙牌  題目鏈結

這道題是一道貪心問題(也有不用貪心方法寫的)。

解題思路:

顯然我們要先求和,把牌堆的平均值求出。

題目上說,每次只能向左右兩邊移動一次(第一堆,最後一堆除外),最少要多少次。

我們不如從一組例項來講吧:

上述十個數字,平均值為10.

我們,這樣看:

第乙個數字等於10,忽略。

第二個數字小於10。第三個數字小於10。恰好第四個大於10。第四個或許能給第

二、第三個牌堆分一些牌。但是只能讓其中乙個達到平均值。所以,我們不慌,繼續往後看,第五個數字是21,多出來許多牌,他能給第

二、第三堆牌一些。

那我們要從第四堆中拿出四張,第五堆拿出一張來,給第二第三堆。為了保證步數少。我們從第五堆拿出一張放入第四,第四拿出五張放入第三。第三拿出三張,放入第二。第二第三第四就都達到了平均值。

然後從第五堆往後看,第五堆多出了十張,然而前面都達到了平均值,這多出來的牌,只能往後面放。

我們從第五堆拿出十張放入第六堆,第六拿出1張,放入第七堆。第七堆拿出3張,放入第八堆。第八堆拿出1張,放入第九堆。

第十堆,等於10,忽略。

下面是我的實現**。

/*

name: p1031 均分紙牌

author: justno

date: 15/11/18 19:44

description:

用時: 13ms / 記憶體: 780kb

*/#include #include using namespace std;

int main()

w=c/n;//平均值

more=less=0;

/* more:當前大於w的牌堆多出來的牌數

less:當前小於w的牌堆缺的牌數

*/ k=1000;

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

if (more>=less&&more!=0&&less!=0)

else

}

} printf ("%d\n",s);

return 0;

}

下面是相同思想的更簡單的實現方法:

#include #include using namespace std;

int main()

; scanf ("%d",&n);

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

w=c/n;

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

a[i]-=w;

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

printf ("%d\n",s);

return 0;

}

這是這個作者的:

他是第乙個題解。

洛谷 P1031 均分紙牌(貪心)

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

洛谷 P1031 均分紙牌

p1031 均分紙牌 這道題告訴我們,對於實在想不出演算法的題,可以大膽按照直覺用貪心,而且在考試中永遠不要試著去證明貪心演算法,因為非常難證,會浪費大量時間。這就是你們都不去證的理由?這道題貪心演算法就是,計算牌的平均數,然後除了最後一堆以外,每堆都通過把多餘牌移到下一堆或從下一堆取牌來使其達到平...

洛谷 P1031均分紙牌

恰似又更了四章 我現在只能期待他不在什麼工作日突然來乙個十篇得大爆更了 我現在要更一篇水題了 希望不會被不小心看到的大佬們嫌棄 題目描述 有n堆紙牌,編號分別為 1,2,n。每堆上有若干張,但紙牌總數必為n的倍數。可以在任一堆上取若干張紙牌,然後移動。移牌規則為 在編號為1堆上取的紙牌,只能移到編號...