【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很容易就能夠想到:
這裡就要引進一種DP優化方式:四邊形不等式優化。設a<b<c<d,若
這道題設
1、
2、
稍微轉化一下就能夠弄出關於
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-0】1089 最長回文子串 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-0】1011 最大公約數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-0】1018 排序
i++ logs closed img mes close for play class 【算法】排序 #include<cstdio> #include<algorithm> using namespace std; int n,a[50010
【51NOD-0】1019 逆序數
+= open clas tdi for string d+ display algorithm 【算法】離散化+樹狀數組(求逆序對) 【題解】經典,原理是統計在i之前插入的且值≤i的個數,然後答案就是i-getsum(i) #include<cstdio>
【51NOD-0】1106 質數檢測
scanf nbsp return span scan printf 技術分享 for == 【算法】數學 #include<cstdio> #include<cmath> bool ok(int x) { int m=(int)sqrt
【51NOD-0】1118 機器人走方格
for space blog () algorithm cnblogs amp return closed 【算法】DP #include<cstdio> #include<algorithm> using namespace std; cons
【51NOD-0】1134 最長遞增子序列
子序列 can algorithm view hide 但是 open sin cst 【算法】動態規劃 【題解】經典模型:最長上升子序列(n log n) #include<cstdio> #include<algorithm> #includ
【雜題集】【51NOD 1267】4個數和為0
www namespace quest color https question clas amp -a 4個數和為0 鏈接: 原題 題意: ... 這 思路: 由於(n=1000),O(n^2)的算法也可一試。