1. 程式人生 > >【51Nod 1022】石子歸併 V2

【51Nod 1022】石子歸併 V2

Description

1022 石子歸併 V2
基準時間限制:1 秒 空間限制:131072 KB 分值: 160 難度:6級演算法題
N堆石子擺成一個環。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將N堆石子合併成一堆的最小代價。

例如: 1 2 3 4,有不少合併方法
1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19)
1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24)
1 2 3 4 => 1 2 7(7) => 3 7(10) => 10(20)

括號裡面為總代價可以看出,第一種方法的代價最低,現在給出n堆石子的數量,計算最小合併代價。
Input
第1行:N(2 <= N <= 1000)
第2 - N + 1:N堆石子的數量(1 <= A[i] <= 10000)
Output
輸出最小合併代價
Input示例
4
1
2
3
4
Output示例
19

Solution

普通的DP很容易就能夠想到:fi,j表示從第i堆石子合併到第j顆石子的最小代價是什麼,只要列舉間接點k就能夠輕鬆轉移。但是發現一個很重要的問題,時間高達n3,問題就在於如何優化k的列舉。
這裡就要引進一種DP優化方式:四邊形不等式優化。設a<b<c<d,若f

a,c+fb,dfb,c+fa,d則滿足四邊形不等式。
這道題設gi,j表示對應i,j最優狀態的k值,可以發現gi,j是滿足四邊形不等式的。
1、gi,1gi,2......gi,n1gi,n
2、g1,ig2,i......gn1,ign,i
稍微轉化一下就能夠弄出關於gi,j的關係式:gi,j1gi,jgi+1,j,因為所有k的列舉個數和是n,所以總時間複雜度是n2

Code

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; int f[2001][2001],n,i,j,k,x,g[2001][2001],a[1001],s[2001],ans; int main(){ scanf("%d",&n); s[0]=0; fo(i,1,n){ scanf("%d",&a[i]);s[i]=s[i-1]+a[i]; } fo(i,1,n){ s[i+n]=s[i+n-1]+a[i]; } memset(f,127,sizeof(f)); fo(i,1,2*n){ g[i][i]=i; f[i][i]=0; } fo(x,1,n){ fo(i,1,n*2-1){ j=i+x; if(j>n*2-1)break; fo(k,g[i][j-1],g[i+1][j]) if(f[i][k]+f[k+1][j]+s[j]-s[i-1]<f[i][j]){ f[i][j]=f[i][k]+f[k+1][j]+s[j]-s[i-1]; g[i][j]=k; } } } ans=0x7777777; fo(i,1,n)ans=min(ans,f[i][i+n-1]); printf("%d",ans); }

相關推薦

51Nod 1022石子歸併 V2

Description 1022 石子歸併 V2 基準時間限制:1 秒 空間限制:131072 KB 分值: 160 難度:6級演算法題 N堆石子擺成一個環。現要將石子有次序地合併成一堆。規定每次

51nod 1021石子歸併(區間dp入門)

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

51Nod 1021 石子歸併 區間DP

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

經典問題二.區間dp石子歸併 51nod 1021

51nod 1021 石子歸併(區間dp) 問題描述: N堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將N堆

CH 5301石子歸併DP

題目大意: 思路: 這道題不能合併兩堆不相鄰的石子,所以堆和佇列就肯定不行了。考慮DP。 設f[i][j]f[i][j]為合併第ii堆到第jj堆得最下代價,那麼由於肯定得將它們分成兩堆

codevs 2102石子歸併

題目描述 Description 有n堆石子排成一列,每堆石子有一個重量w[i], 每次合併可以合併相鄰的兩堆石子,一次合併的代價為兩堆石子的重量和w[i]+w[i+1]。問安排怎樣的合併順序,能夠使得總合並代價達到最小。 輸入描述 Input Descri

codevs 1048石子歸併

1048 石子歸併 時間限制: 1 s 空間限制: 128000 KB 題目等級 : 黃金 Gold 題解 檢視執行結果 題目描述 Description 有n堆石子排成一列,每堆石子有一個重量w[i], 每次合併可以合併相鄰的兩堆石子,

51nod oj 1022 石子歸併 V2 環形區間DP----四邊形不等式優化

題目傳送門:1022 四邊形不等式優化: m[i,j]=min{m[i,k]+m[k,j]}(s[i,j-1]≤k≤s[i+1,j]) 當m[i,j]=min{m[i,k]+m[k,j]}(i≤

[DP 四邊形不等式優化] 51Nod 1022 石子歸併 V2

蒟蒻不會四邊形不等式 形如 fi,j=min{fi,k+fk+1,j+wi,j}的方程 且滿足四邊形不等式和區間包含單調性 就可以用四邊形不等式優化 #include<cstdio> #

51nod oj 1021 石子歸併區間dp

題目連結:1021 每次只能合併相連的石堆-.-我們可以建一個dp dp [ i ] [ k ] 表示從i號一共K個石頭合併再一起所花費的代價-.- 轉換方程1:dp[ i ] [ k ]=min

51NOD-01089 最長回文子串 V2(Manacher算法)

lose 最長回文子串 gif () none print struct hide pac 【算法】回文樹 #include<cstdio> #include<algorithm> #include<cstring> using na

DFS石子歸併

Description 你有一堆石頭質量分別為W1,W2,W3…WN.(W<=100000)現在需要你將石頭合併為兩堆,使兩堆質量的差為最小。 Input 測試資料第一行為整數N(1<=N<=20),表示有N堆石子。第二行為N個數,為每堆石子的質量。

codevs1048石子歸併

遞推 //f[i]:到i為止的LIS的長度。 //f[i]=max{1,f[j]+1|j<i&&aj<ai} #include<iostream> #include<algorithm> using na

51NOD-01011 最大公約數GCD

style lose gif lap blog %d 51nod ret display 【算法】歐幾裏德算法 #include<cstdio> int gcd(int a,int b) {return b==0?a:gcd(b,a%b);} int mai

51NOD-01018 排序

i++ logs closed img mes close for play class 【算法】排序 #include<cstdio> #include<algorithm> using namespace std; int n,a[50010

51NOD-01019 逆序數

+= open clas tdi for string d+ display algorithm 【算法】離散化+樹狀數組(求逆序對) 【題解】經典,原理是統計在i之前插入的且值≤i的個數,然後答案就是i-getsum(i) #include<cstdio>

51NOD-01106 質數檢測

scanf nbsp return span scan printf 技術分享 for == 【算法】數學 #include<cstdio> #include<cmath> bool ok(int x) { int m=(int)sqrt

51NOD-01118 機器人走方格

for space blog () algorithm cnblogs amp return closed 【算法】DP #include<cstdio> #include<algorithm> using namespace std; cons

51NOD-01134 最長遞增子序列

子序列 can algorithm view hide 但是 open sin cst 【算法】動態規劃 【題解】經典模型:最長上升子序列(n log n) #include<cstdio> #include<algorithm> #includ

雜題集51NOD 12674個數和為0

www namespace quest color https question clas amp -a 4個數和為0 鏈接: 原題 題意: ... 這 思路: 由於(n=1000),O(n^2)的算法也可一試。