區間DP 石子合併

2021-10-09 02:46:44 字數 2100 閱讀 1619

區間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 個數,分別表示...