1. 程式人生 > >BZOJ 3229 [Sdoi2008]石子合併 GarsiaWachs演算法

BZOJ 3229 [Sdoi2008]石子合併 GarsiaWachs演算法

Description

  在一個操場上擺放著一排N堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。   試設計一個演算法,計算出將N堆石子合併成一堆的最小得分。

Input

  第一行是一個數N   以下N行每行一個數A,表示石子數目。

Output

  共一個數,即N堆石子合併成一堆的最小得分。

Sample Input

4
1
1
1
1

Sample Output

8

HINT

對於 100% 的資料,1≤N≤40000

對於 100% 的資料,1≤A≤200

Source

傳送門 原版的石子合併,N卻有整整40000……
基本的DP是O(N^3)的, 平行四邊形優化過後是O(N^2)的,但是仍然不能滿足這題的條件。 這裡要用到GarsiaWachs演算法。 步驟: 1.找到第一個a[u-1]<=a[u+1]的位置; 2.將a[u-1]和a[u]合併(加起來); 3.把合併後的結果插入到位置v,使得a[v]>=a[u]。 如此重複上述步驟,合併n-1次,得到的就是最優結果…… 其實我不太知道原理…… 證明還是網上百度吧。。。 時間複雜度O(N^2)……這是最壞情況下的,,聽說平均是O(N log N) 反正加上平衡樹就是穩定O(N log N)了,,(我沒加)
#include<bits/stdc++.h>
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int 
	N=40005,
	MAX=9000000;
int n,a[N];
int main(){
	n=read();
	for (int i=1;i<=n;i++) a[i]=read();
	a[0]=a[n+1]=MAX;
	int m=n,ans=0;
	for (int i=1;i<n;i++){
		int k;
		for (int j=1;j<=m;j++)
			if (a[j-1]<=a[j+1]){
				k=j; break;
			}
		a[k-1]+=a[k];
        for (int j=k;j<m;j++) a[j]=a[j+1];
        ans+=a[--k];
        while (k && a[k-1]<=a[k])
			swap(a[k-1],a[k]),k--;
        a[m--]=MAX;
	}
	printf("%d\n",ans);
	return 0;
}

相關推薦

BZOJ 3229 [Sdoi2008]石子合併 GarsiaWachs演算法

Description   在一個操場上擺放著一排N堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。   試設計一個演算法,計

GarsiaWachs演算法】bzoj3229: [Sdoi2008]石子合併

biu~ Description Time Limit: 3 Sec Memory Limit: 128 MB submit 在一個操場上擺放著一排N堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,

[區間DP]石子合併極其變種問題(環形,40000堆型)P1880 [NOI1995]石子合併+[Sdoi2008]石子合併/poj1738An old Stone Game

 有N堆石子,現要將石子有序的合併成一堆,規則如下: (1)每次只能移動任意相鄰的2堆石子合併,合併花費為新合成的一堆石子的數量。求將這N堆石子合併成一堆總花費,要求N<=300。 變形一:(2)每次只能移動相鄰的2堆石子合併,合併花費為新合成的一堆石子的數量。求將

演算法設計與分析習題3-3 石子合併問題直線排列最大得分

 此題有直線,圓形兩種問法。 分別有最大得分最小得分解法。簡單的dp。 直線最大得分 #include <iostream> #include <stdio.h> using namespace std; int main() {     freop

[其它-GarsiaWachs演算法]51nod 1023 石子歸併v3

基準時間限制:2 秒 空間限制:131072 KB 分值: 640 難度:8級演算法題 N堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。

【基礎演算法石子合併-版本1

此題主要是用dp求出每個範圍的最小价值,再用遞迴輸出。 時間限制: 1 Sec 記憶體限制: 64 MB 題目描述 設有n堆石子排成一排,其編號為1,2,3,…,n。每堆石子有一定的數量,例如: 13 7 8 16 21 4 18 現要將n堆石子歸併為一

BZOJ 2190: [SDOI2008]儀仗隊

pre 現在 scan bzoj for clu 判斷 time code Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 3213 Solved: 2072[Submit][Status][Discuss] Descri

BZOJ 2049: [Sdoi2008]Cave 洞穴勘測(LCT裸題)

one namespace sizeof hide update ask upd 鏈接 != 題目鏈接:BZOJ 2049: [Sdoi2008]Cave 洞穴勘測 題意: 三個操作. 1 鏈接x y 2 斷開x y 3 詢問x y是否連通 題解: LCT裸題 1 #

BZOJ-2190: [SDOI2008]儀仗隊 (歐拉函數)

stdout 根據 size com borde pro tput include return 2190: [SDOI2008]儀仗隊 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 3483 Solved: 2259[

BZOJ 1115: [POI2009]石子遊戲Kam (階梯nim)

limit solved sub log 一道 def ret cst 否則 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1138 Solved: 697[Submit][Status][Discuss] Descri

BZOJ 2049 SDOI2008 洞穴勘測 LCT板子

tor 鏈接 http main map play int mes roo 題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=2049 題意概述:給出N個點,一開始不連通,M次操作,刪邊加邊,保證圖是一個森林,詢問

【刷題】BZOJ 2190 [SDOI2008]儀仗隊

AD 100% puts IT gist logs www sample blog Description 作為體育委員,C君負責這次運動會儀仗隊的訓練。儀仗隊是由學生組成的N * N的方陣,為了保證隊伍在行進中整齊劃一,C君會跟在儀仗隊的左後方,根據其視線所及的學生人數來

【刷題】BZOJ 2049 [Sdoi2008]Cave 洞穴勘測

pty 手工 span clas 之間 十分 roo link bool Description 輝輝熱衷於洞穴勘測。某天,他按照地圖來到了一片被標記為JSZX的洞穴群地區。經過初步勘測,輝輝發現這片區域由n個洞穴(分別編號為1到n)以及若幹通道組成,並且每條通道連接了恰好

bzoj 2049 [Sdoi2008]Cave 洞穴勘測 LCT

href git blog min pro rotate www rev bzoj 題面 題目傳送門 解法 LCT模板題 有些博客講得挺好的,轉一下 博客 這個挺詳細的 時間復雜度:\(O(m\ log\ n)\),盡管常數巨大 代碼 #include <bits/s

bzoj 2049 [SDOI2008]洞穴勘測 (LCT)

hup fine swap splay har cut 題目 wap con 題目大意:維護一個森林,支持邊的斷,連,以及查詢連通性 LCT裸題 洛谷P2147傳送門 1A了,給自己鼓鼓掌 1 #include <cstdio> 2 #include &l

P1880 [NOI1995]石子合併 區間dp+拆環成鏈

思路 :一道經典的區間dp  唯一不同的時候 終點和起點相連  所以要拆環成鏈  只需要把1-n的陣列在n+1-2*n複製一遍就行了 #include<bits/stdc++.h> using namespace std; const int maxn=100

洛谷 P1880 石子合併 題解

N堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將N堆石子合併成一堆的最小代價。 例如: 1 2 3 4,有不少合併方法 1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19)

nyoj737—石子合併(一)(區間DP)

描述     有N堆石子排成一排,每堆石子有一定的數量。現要將N堆石子併成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過N-1次合併後成為一堆。求出總的代價最小值。 輸入 有多組測試資料,輸入到檔案結束

洛谷P1880 石子合併

題目描述 在一個圓形操場的四周擺放N堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。 試設計出1個演算法,計算出將N堆石子合併成1堆的最小得分和最大得分. 輸入輸出格式 輸入格式: 資料的第1行試正整數N,1

NOI1995石子合併&多種石子合併

題目描述 在一個圓形操場的四周擺放N堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。 試設計出1個演算法,計算出將N堆石子合併成1堆的最小得分和最大得分. 輸入輸出格式 輸入格式:   資料的第1行試正整數N,1≤N