石子合併 (區間DP)
在一個園形操場的四周擺放N堆石子(N≤100),現要將石子有次序地合併成一堆。規定
每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。
編一程式,由檔案讀入堆數N及每堆的石子數(≤20),
①選擇一種合併石子的方案,使得做N-1次合併,得分的總和最小;
②選擇一種合併石子的方案,使得做N-1次合併,得分的總和最大。
例如,所示的4堆石子,每堆石子數(從最上面的一堆數起,順時針數)依
次為4594。則3次合併得分總和最小的方案:8+13+22=43
得分最大的方案為:14+18+22=54
</pre><pre name="code" class="cpp">#include<iostream> #include<stdio.h> #include<math.h> #include<string.h> #include<algorithm> using namespace std; #define N 105 //定義二維陣列m[i][j]來記錄i到j的合併過成中最少石子數目 int solve_min(int *p,int n) { int i,j,k,r,sum; int m[N][N]; memset(m,-1,sizeof(m)); for(i=1; i<=n; i++) //當一個單獨合併時,m[i][i]設為0,表示沒有石子 m[i][i]=0; for(i=1; i<n; i++) //當相鄰的兩堆石子合併時,此時的m很容易可以看出是兩者之和 m[i][i+1]=p[i]+p[i+1]; for(r=3; r<=n; r++) //當相鄰的3堆以及到最後的n堆時,執行以下迴圈 { for(i=1; i<=n-r+1; i++) { j=i+r-1; sum=0; for(k=i; k<=j; k++) //當i到j堆石子合併時最後裡面的石子數求和得sum sum+=p[k]; m[i][j]=m[i+1][j]+sum; // 此時m[i][j]為i~j堆石子間以m[i][i]+m[i+1][j]+sum結果,這是其中一種可能,不一定是最優 for(k=i+1; k<j; k++) { int t=m[i][k]+m[k+1][j]+sum; if(t<m[i][j]) m[i][j]=t; } } } return m[1][n]; } int solve_max(int *p,int n) { int i,j,k,r,sum; int m[N][N]; memset(m,-1,sizeof(m)); for(i=1; i<=n; i++) m[i][i]=0; for(i=1; i<n; i++) m[i][i+1]=p[i]+p[i+1]; for(r=3; r<=n; r++) { for(i=1; i<=n-r+1; i++) { j=i+r-1; sum=0; for(k=i; k<=j; k++) sum+=p[k]; m[i][j]=m[i+1][j]+sum; for(k=i+1; k<j; k++) { int t=m[i][k]+m[k+1][j]+sum; if(t>m[i][j]) m[i][j]=t; } } } return m[1][n]; } int main() { int i,j,k,n,stone[N]; while(scanf("%d",&n)!=-1) { for(i=1; i<=n; i++) { scanf("%d",&stone[i]); } int mmin=solve_min(stone,n); int mmax=solve_max(stone,n); for(j=1; j<n; j++) { int t=stone[1]; for(k=1; k<n; k++) { stone[k]=stone[k+1]; } stone[n]=t; int tmin=solve_min(stone,n); int tmax=solve_max(stone,n); if(tmin<mmin) mmin=tmin; if(tmax>mmax) mmax=tmax; } printf("%d\n%d\n",mmin,mmax); } return 0; }
相關推薦
[NOI1995]石子合併(區間DP)
題目連結: [NOI1995]石子合併 思路: 區間DP經典例題,可以把前n-1堆石子一個個移到第n個後面,那樣環就變成了線,即現在有2*n-1堆石子需要合併。 程式碼: #include <iostream> #include
石子合併 (區間DP)
一.試題在一個園形操場的四周擺放N堆石子(N≤100),現要將石子有次序地合併成一堆。規定每次只能選相鄰的兩堆合併成新的一堆,並將新的一堆的石子數,記為該次合併的得分。編一程式,由檔案讀入堆數N及每堆的石子數(≤20),①選擇一種合併石子的方案,使得做N-1次合併,得分
nyoj737—石子合併(一)(區間DP)
描述 有N堆石子排成一排,每堆石子有一定的數量。現要將N堆石子併成為一堆。合併的過程只能每次將相鄰的兩堆石子堆成一堆,每次合併花費的代價為這兩堆石子的和,經過N-1次合併後成為一堆。求出總的代價最小值。 輸入 有多組測試資料,輸入到檔案結束
【區間dp*2】洛谷 P1880 [NOI1995]石子合併 (推導過程) +尼克的任務(還沒寫)
emmmmm給自己設定了一個習慣界限。其實每次看到他們在做啥啥啥而我都大三都現在了 就會感覺很內傷-、- 不過演算法還是要寫的吧 別寫太多而已... 為了防止腦袋空空 也為了防止一天不知道幹什麼 ================================== &
石子合併問題 (區間dp)
石子合併問題是最經典的DP問題。首先它有如下3種題型:(1)有N堆石子,現要將石子有序的合併成一堆,規定如下:每次只能移動任意的2堆石子合併,合併花費為新合成的一堆石子的數量。求將這N堆石子合併成一堆
NYOJ題目737石子合併(一)(區間dp)
石子合併(一) 時間限制:1000 ms | 記憶體限制:65535 KB 難度:3 描述 有N堆石子排成一排,每堆石子有一定的數量。現要將N堆石子併成為一堆。合併的過程只能每次將
51Nod - 1021 石子歸並(區間DP)
put -c ring 輸出 define .org max print left 【題目描述】 N堆石子擺成一條線。現要將石子有次序地合並成一堆。規定每次只能選相鄰的2堆石子合並成新的一堆,並將新的一堆石子數記為該次合並的代價。計算將N堆石子合並成一堆的最小代價。
nyoj 737 石子合並(區間DP)
using lac padding gin height space outline style 每次 737-石子合並(一) 內存限制:64MB 時間限制:1000ms 特判: No通過數:28 提交數:35 難度:3 題目描
【51nod 1021】石子歸併(區間dp入門)
1021 石子歸併 基準時間限制:1 秒 空間限制:131072 KB 分值: 20 難度:3級演算法題 收藏 關注 N堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能選相鄰的2堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的代價。計算將N堆石子合併成一堆的最小代價。
石子歸併(區間dp & 四邊形不等式優化)
基準時間限制:1 秒 空間限制:131072 KB 分值: 20 難度:3級演算法題 收藏 取消關注 N堆石子擺成一條線。現要將石子有次序地合併成一堆。規定每次只能
LightOJ - 1422 Halloween Costumes (區間DP)
wan things strong cas book article printf ase con Description Gappu has a very busy weekend ahead of him. Because, next weekend is Ha
POJ 1141 Brackets Sequence (區間DP)
ive bsp rip mes character har typedef som memset Description Let us define a regular brackets sequence in the following way: 1.
Brackets Sequence POJ - 1141 (區間dp)
gif == urn ++ char img ems utc pre Brackets Sequence POJ - 1141 題意:給一個括號序列,問最少添加多少個括號似的原序列匹配,並輸出新序列。 用dp[i][j]表示i到j最少添加幾個括號,flag[i][j]表
Brackets POJ - 2955 (區間dp)
pla clu for eof %d img rac end racket Brackets POJ - 2955 題意:給一個括號序列,問最多有多少個括號是可以配對的。 1 #include<cstdio> 2 #include<algori
Food Delivery ZOJ - 3469 (區間dp)
位置 turn pro pan return isp ive != truct Food Delivery ZOJ - 3469 題意:快遞員送外賣,n個客戶,起始位置為x,速度為v,每個客戶單位時間不滿意度增加hi,問最少增加多少不滿意度。 每一個客戶可能是從左側送到
CSUOJ-1980 不堪重負的數(區間dp)
inline 滿二叉樹 -a ems ext div des button problems 1980: 不堪重負的樹 Submit Page Summary Time Limit: 1 Sec Memory Limit: 128 Mb Subm
POJ 1991 Turning in Homework(區間DP)
clu sin highlight sort stream ret spa 作業 ref 題目鏈接 Turning in Homework 考慮區間DP f[i][j][0]為只考慮區間[i, j]且最後在a[i]位置交作業的答案。 f[i][j][1]為只考慮區間[
hdu6212 祖瑪(區間DP)
tro 位置 表示 中間 ron i+1 strong 就會 題意 題意 有一個長度為n的01串,我們可以在某個地方插入一個0或者1,那麽如果有連續顏色相同的>=3個,那麽這段就會消去,兩邊的合攏。問將所有01串消去,最少需要插入多少個。(n<=200)
括號匹配問題(區間dp)
最小值 很好 nbsp 需要 簡單的 棧模擬 pri tex 什麽 簡單的檢查括號是否配對正確使用的是棧模擬,這個不必再說,現在將這個問題改變一下:如果給出一個括號序列,問需要把他補全成合法最少需要多少步? 這是一個區間dp問題,我們可以利用區間dp來解決,直接看代碼吧!
修長城 (區間DP)
urn ret 世紀 log width hide 時間 main gif Time Limit: 1000 ms Memory Limit: 256 MB Description 大家都知道,長城在自然條件下會被侵蝕,因此,我們需要修復。現在是21世紀,