石子歸併最簡單的情況是一排石子,典型的區間dp問題。dp[i][j]的含義是區間[i,j]合併之後的最大或最小花費
轉移方程:dp[i][j]=max/min(dp[i][j],dp[i][k]+dp[k+1][j]+val(i,j))
對於區間[i,j],它可以由區間[i,k]和區間[k+1,j]合併而來,合併時,要加上整個區間的花費,花費可以使用字首和記錄。
#includeusing namespace std;
typedef long long ll;
const int inf=1e9+7;
const int maxn=105;
int sum[maxn];
int dp1[maxn][maxn];//最大花費
int dp2[maxn][maxn];//最小花費
int main()
for(int i=1;i洛谷的這題是環形的,比一排的情況要複雜一點點。
思路:為了方便,可以直接把字首和陣列開兩倍,這樣就可以用段來表示環。跟前面的方法一樣,不同的是最後不是dp[1][n]了,即起點可以是環內任意一點,如果起點為i,那麼終點就是i+n-1。列舉求一下極值。
#includeusing namespace std;
typedef long long ll;
const int inf=1e9+7;
const int maxn=205;
int num[maxn];
int sum[maxn];
int dp1[maxn][maxn];//最大花費
int dp2[maxn][maxn];//最小花費
int main()
for(int i=n+1;i<=2*n;i++)
for(int i=1;i}
}int ansmin=inf,ansmax=0;
for(int i=1;i<=n;i++)
printf("%d\n%d\n",ansmin,ansmax);
return 0;
}
p1880 石子合併
先從線性的開始吧。有n堆石子排成一排,每堆石子有一定的數量。現要將n堆石子並成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過n 1次合併後成為一堆。求出總的代價最小值。樣例 輸入 3 1 2 3 7 13 7 8 16 21 4 18 輸出 9 239 ...
P1880石子合併
傳送 這是乙個年代久遠的區間dp 好像以前培訓的時候講了,但是現在才想起來去a 區間dp常用狀態 f i j 以i為左端點,j為右端點的最優解 第一層迴圈列舉區間長度,第二層迴圈列舉起點,第三層列舉中間的斷點 貌似寫到這裡這個題就寫完了 特點 問題能轉換為兩兩合併的問題 such as 能量項鍊,石...
洛谷P1880 石子合併
描述 在乙個園形操場的四周擺放n堆石子,現要將石子有次序地合併成一堆.規定每次只能選相鄰的2堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。試設計出1個演算法,計算出將n堆石子合併成1堆的最小得分和最大得分.輸入格式 資料的第1行試正整數n,1 n 100,表示有n堆石子.第2行有n個數...