時間限制: 1 sec 記憶體限制: 128 mb
貝西要用幹草包堆出一座金字塔。幹草包會從傳送帶上陸續運來,依次出現 n 包,每包乾草可
以看做是乙個二維平面上的乙個長方形,第 i 包乾草的寬度是 w i ,長度統一為 1。
金字塔的修建有幾個規定,首先,為了建築穩定,塔一定要形成類似「金」字的樣子,即塔的上
層寬度不能超過下層寬度,而且每層的幹草包必須緊靠在一起,不能出現縫隙。其次,由於乾草是陸
續送來的,所以先送來的乾草放在較低層。貝西會選擇最先送來的幾包乾草,堆在地上作為第一層,
然後再把緊接著送來的幾包幹草包放在第二層,再鋪建第三層……重複這個過程,一直到所有的乾草
全部用完。最後,貝西不喜歡浪費,所有幹草包一定要用上,不能棄置不用。貝西的目標是建一座最
高的金字塔,在遵循上述規定的前提下,她可以任意決定在金字塔的每一層布置多少連續的幹草包。
請你來幫助她完成這個任務吧。
• 第一行:單個整數 n,1 ≤ n ≤ 100000
• 第二行到第 n + 1 行:第 i + 1 行有乙個整數 w i ,1 ≤ w i ≤ 10000
• 單個整數:表示可以建成的最高高度31
232將 1 和 2 放在第一層,將 3 放在第二層
題解:
首先因為這道題從下到上會有後效性,所以可以想到從上到下堆,f[i]表示後i個乾草能夠達到的最大高度。
於是很容易想到暴力,每次j向後列舉就可以了,但是n≤100000,o(n^2)肯定會超時,所以考慮優化。
定義sum[i]為字首和,g[i]表示後i個堆到f[i]高度時(實際上就是達到最大高度時)最後一層的最小寬度。
sum[i]和f[i]都是遞增的,g[i]相對於上乙個狀態也是遞增的。因此我們只需要找到使g[i]變化量最小的值就可以了。
為什麼是最小值?很顯然,把後i個乾草堆想象成乙個面積為sum[i]的金字塔,那麼要使f[i]盡可能的大,g[i]就要盡可能的小。
接下來是怎麼找,很顯然g[i]相對與g[j]的變化量為s=sum[i]-sum[j]-g[j]=sum[i]-(sum[j]+g[j]),要使s最大,sum[j]+g[j]要最小,顯然sum[j]+g[j]與i沒有關係,所以考慮使用優先佇列儲存sum[j]+g[j]的值,每次取小於sum[i]的最大值就可以了。
因為sum[i]是遞增的,所以當存在另乙個比sum[i]小的更大的值時,前面的就可以出隊了。
ac**如下:
#include#include#include
#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
int n,f[100001],a[100001],sum[100001],g[100001],s[100001
];int q[100001
],head,tail;
intmain()
for(i=1;i<=n;i++)
q[tail++]=0
;
for(i=1;i<=n;i++)
cout
}
USACO 乾草金字塔
貝西要用幹草包堆出一座金字塔。幹草包會從傳送帶上陸續運來,依次出現 n 包,每包乾草可 以看做是乙個二維平面上的乙個長方形,第 i 包乾草的寬度是 w i 長度統一為 1。金字塔的修建有幾個規定,首先,為了建築穩定,塔一定要形成類似 金 字的樣子,即塔的上 層寬度不能超過下層寬度,而且每層的幹草包必...
python 金字塔 Python金字塔
托倫,函式中有幾個小錯誤和乙個邏輯問題print y to a 請注意,此函式生成乙個以z開頭的字串,但您希望將字串以相反的方向連線,而您的另乙個函式print a to y 確實停止了 1位置 例如 還要注意,您需要新增新行字元 n 以獲得一些不錯的輸出。在 我的解決方案是 def print a...
字母金字塔(類同數字金字塔)
問題描述 讓程式要求使用者輸入乙個大寫字母,使用巢狀迴圈產生像下面這樣的金字塔圖案 aaba abcba abcdba abcdecba 演算法分析 每行包括三個部分內容 若干個空格 正序排列的字母 倒序排列的字幕。使用乙個外部迴圈來處理行,在每乙個行中使用三個內部迴圈 乙個處理空格,乙個以公升序列...