dp 石子合併問題

2021-05-27 20:38:05 字數 1766 閱讀 6202

問題描述:

在乙個圓形操場的四周擺放著n 堆石子。現要將石子有次序地合併成一堆。規定每次只能選相鄰  的2 堆石子合併成新的一堆,並將新的一堆石子數記為該次合併的得分。

程式設計任務:

試設計乙個演算法,計算出將n堆石子合併成一堆的最小得分和最大得分。

資料輸入:

包含兩行,第1 行是正整數n(1<=n<=100),表示有n堆石子。

第2行有n個數,分別表示每堆石子的個數。 

結果輸出:

輸出兩行。 

第1 行中的數是最小得分;第2 行中的數是最大得分。

樣例:4

4 4 5 9

4354

核心思想

f[i,j]=min,前i個石子合併j次的最小合併/最大合併,環

var

a:array[1..200] of longint;

n,tot:longint;

f:array[1..200,1..200] of longint;

sum:array[1..200,1..200] of longint;

procedure init;

var i,j,k:longint;

begin

tot:=0;

readln(n);

fillchar(sum,sizeof(sum),0);

for i:= 1 to n do

begin

read(a[i]);

tot:=tot+a[i]; end;

for i:= 1 to n do

for j:= i to n do

if i=j then sum[i,j]:=a[i]

else

if j>i then sum[i,j]:=sum[i,j-1]+a[j];

for i:= 2 to n do

begin

for j:= 1 to i-1 do

if i=j+1 then sum[i,j]:=tot

else

sum[i,j]:=tot-sum[j+1,i-1];

end;

end;

procedure main;

var i,j,k,p:longint;

data,ans:longint;

begin

fillchar(f,sizeof(f),100);

for i:= 1 to n do f[i,1]:=a[i];

for j:= 2 to n do

for i:= 1 to n do

for k:= 1 to j-1 do

begin

p:=(i+k-1) mod n +1 ;

data:=f[i,k]+f[p,j-k]+sum[i,(i+j-2) mod n+1];

if f[i,j]>data then f[i,j]:=data;

end;

ans:=maxlongint;

for i:= 1 to n do if f[i,n]ans then ans:=f[i,n];

writeln(ans-tot);

end;

begin

assign(input,'p35.in');reset(input);

assign(output,'p35.out');rewrite(output);

init;

main;

close(input);close(output);

end.

dp 石子合併問題

石子合併問題 有n n 100 堆石子,價值分別為a0,a1.a n 1 每次將其中的相鄰的兩堆合併,合併的代價為兩堆石子的價值和,合併後用合併之後的一堆石子代替之前的兩堆石子,價值為原來 兩堆價值之和,求最終將所有的石子合併成一堆之後的代價最小值。問題一 n堆石子排成一條直線 這個問題比較簡單,類...

石子合併問題(區間DP)

有n堆石子,要合併成一堆,規則是只能和相鄰的合併,每次合併的代價是合併出的石子堆的石子數量,求最小花費。in 4 4 4 5 9 out 43 直接貪心只能取到區域性的最佳結果。方程是很明顯的,dp i j min dp i j dp i k dp k 1 j sum j sum i s i dp陣...

dp演算法 石子合併問題

這兩天看了一下這個問題,原題是這樣的 有n堆石子,現要將石子有序的合併成一堆,規定如下 每次只能移動相鄰的2堆石子合併,合併花費為新合成的一堆石子的數量。求將這n堆石子合併成一堆的總花費最小 或最大 這個題目在第一次剛看的時候,一臉懵逼,題目看懂了,但是怎麼去求花費怎麼都沒有想明白,後來在網上看了一...