區間dp的經典例題,有三種題型
本篇部落格借鑑了了兩位大佬的部落格。
部落格1、部落格2
問題:
n堆石子,現要將石子有序的合併成一堆。每次只能移動任意的2堆石子合併,合併花費為新合成的一堆石子的數量。求將這n堆石子合併成一堆的總花費最小(或最大)。
思路:
貪心,每次把最小的兩堆合併即可,可以使用stl中的優先佇列來實現。
**:
#include
#include
#define ll long long
using
namespace std;
intmain()
while
(q.size()
>1)
cout << sum << endl;
}return0;
}
問題:
有n堆石子,現要將石子有序的合併成一堆,每次只能移動相鄰的2堆石子合併,花費為新合成的一堆石子的數量,求將這n堆石子合併成一堆的總花費最小(或最大)。
思路:
運用區間dp的思想。設dp[i][j]表示第i到第j堆石子合併的最優值,sum[i][j]表示第i到第j堆石子的總數量。那麼就有狀態轉移公式:
**:
#include
using
namespace std;
#define ll long long
#define inf 0x7fffffff
#define inf 0x3f3f3f3f
//const int n = 1e6 + 10;
const
double pi=
acos(-
1.0)
;const
int mod =
1e9+7;
//ll a[n],vis[n],num[n],p[n];
const
int maxn=
301;
int n,a[maxn]
;int dp[maxn]
[maxn]
;//dp[i][j]表示從第i堆到第j堆合併的代價
int sum[maxn]
[maxn]
;//表示石頭的數量
intmain()
}}cout << dp[1]
[n]<< endl;
return0;
}
問題:
有n堆石子環形排列,現要將石子有序的合併成一堆,規定如下:每次只能移動相鄰的2堆石子合併,合併花費為新合成的一堆石子的數量。求將這n堆石子合併成一堆的總花費最小(或最大)。
思路:
狀態轉移方程。
石子合併 (區間DP
問題描述 在乙個操場上擺放著一行共n堆的石子。現要將石子有序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆石子數記為該次合併的得分。請編輯計算出將n堆石子合併成一堆的最小得分和將n堆石子合併成一堆的最大得分。輸入檔案 輸入第一行為n n 1000 表示有n堆石子,第二行為n個用空...
石子合併 區間dp
有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。假設dp 1 4 表示將區間1 4的石子合併所花費的代價。dp 1 4 可以劃分為dp 1 1 dp 2...
石子合併 (區間DP)
題目鏈結 描述 有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。輸入第一行有乙個整數n,表示有n堆石子。接下來的一行有n 0 n 200 個數,分別表示...