[蓝桥杯][算法提高VIP]合并石子(区间dp+平行四边形优化)
生活随笔
收集整理的這篇文章主要介紹了
[蓝桥杯][算法提高VIP]合并石子(区间dp+平行四边形优化)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目描述
在一條直線上有n堆石子,每堆有一定的數量,每次可以將兩堆相鄰的石子合并,合并后放在兩堆的中間位置,合并的費用為兩堆石子的總數。求把所有石子合并成一堆的最小花費。
輸入
輸入第一行包含一個整數n,表示石子的堆數。
接下來一行,包含n個整數,按順序給出每堆石子的大小 。
輸出
輸出一個整數,表示合并的最小花費。
樣例輸入
5
1 2 3 4 5
樣例輸出
33
思路:藍橋杯官網好像放寬時間限制了,不加平行四邊形優化也可以過,但是dotcpp網站上不行。這算是一個區間dp的入門題目,平行四邊形優化可以自行百度一下,用的不多。。
代碼如下:
區間dp+平行四邊形優化代碼
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #define inf 0x3f3f3f3f using namespace std;const int maxx=1e3+100; int dp[maxx][maxx]; int sum[maxx]; int s[maxx][maxx]; int n; int a[maxx];void DP(int l,int r) {sum[0]=a[0];for(int i=1;i<n;i++){sum[i]=sum[i-1]+a[i];s[i][i]=i;}for(int i=0;i<n;i++){for(int j=0;j<n;j++){if(i==j) dp[i][j]=0;else dp[i][j]=inf;}}for(int len=2;len<=n;len++)//長度 {for(int i=0;i<=n-len+1;i++)//起點 {int j=i+len-1;//終點 for(int k=s[i][j-1];k<=s[i+1][j];k++)//間隔點 {//dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);if(dp[i][j]>dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]){dp[i][j]=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];s[i][j]=k;} }}} } int main() {scanf("%d",&n);for(int i=0;i<n;i++) scanf("%d",&a[i]);DP(0,n);printf("%d\n",dp[0][n-1]); }努力加油a啊,(o)/~
總結
以上是生活随笔為你收集整理的[蓝桥杯][算法提高VIP]合并石子(区间dp+平行四边形优化)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WIN10永久激活工具 HWIDGEN[
- 下一篇: [蓝桥杯][基础练习VIP]分解质因数