問題描述:
在乙個圓形操場的四周擺放著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堆石子合併成一堆的總花費最小 或最大 這個題目在第一次剛看的時候,一臉懵逼,題目看懂了,但是怎麼去求花費怎麼都沒有想明白,後來在網上看了一...