☆乘法遊戲
背景 background
太原成成中學第2次模擬賽 第四道
描述 description
乘法遊戲是在一行牌上進行的。每一張牌包括了乙個正整數。在每乙個移動中,玩家拿出一張牌,得分是用它的數字乘以它左邊和右邊的數,所以不允許拿第1張和最後1張牌。最後一次移動後,這裡只剩下兩張牌。
你的目標是使得分的和最小。
例如,如果數是10 1 50 20 5,依次拿1、20、50,總分是 10*1*50+50*20*5+10*50*5=8000
而拿50、20、1,總分是1*50*20+1*20*5+10*1*5=1150。
輸入格式 input format
輸入檔案的第一行包括牌數(3<=n<=100),第二行包括n個1-100的整數,用空格分開。
輸出格式 output format
輸出檔案只有乙個數字:最小得分
樣例輸入 sample input [複製資料]
樣例輸出 sample output [複製資料]
時間限制 time limitation
各個測試點1s
var
n:longint;
a:array[1..100]of longint;
f:array[1..100,1..100]of longint;
procedure init;
begin
assign(input,'ty1014.in');
assign(output,'ty1014.out');
reset(input); rewrite(output);
end;
procedure terminate;
begin
close(input); close(output);
halt;
end;
function dp(s,t:longint):longint;
var i:longint;
now:longint;
begin
if s+1=t then exit(0);
//if s>t then exit(0);
if f[s,t]<>maxlongint then exit(f[s,t]);
dp:=10000000;
for i:=s+1 to t-1 do
begin
if dp>dp(s,i)+dp(i,t)+a[i]*a[s]*a[t] then
dp:=dp(s,i)+dp(i,t)+a[i]*a[s]*a[t];
end;
f[s,t]:=dp;
end;
procedure main;
var i,j,k:longint;
begin
readln(n);
for i:=1 to n do read(a[i]);
//fillchar(f,sizeof(f),0);
for i:=1 to n do
for j:=1 to n do
f[i,j]:=maxlongint;
writeln(dp(1,n));
end;
begin
init;
main;
terminate;
end.
區間DP 記憶化搜尋 乘法遊戲
乘法遊戲是在一行牌上進行的。每一張牌包括了乙個正整數。在每乙個移動中,玩家拿出一張牌,得分是用它的數字乘以它左邊和右邊的數,所以不允許拿第1張和最後1張牌。最後一次移動後,這裡只剩下兩張牌。你的目標是使得分的和最小。例如,如果數是10 1 50 20 5,依次拿1 20 50,總分是 10 1 50...
區間 線性dp 數字遊戲
丁丁最近沉迷於乙個數字遊戲之中。這個遊戲看似簡單,但丁丁在研究了許多天之後卻發覺原來在簡單的規則下想要贏得這個遊戲並不那麼容易。遊戲是這樣的,在你面前有一圈整數 一共 n 個 你要按順序將其分為 m 個部分,各部分內的數字相加,相加所得的 m 個結果對 10 取模後再相乘,最終得到乙個數 k 遊戲的...
區間dp 石子合併 矩陣鏈乘法
有n堆石子圍成乙個圈,每一堆石子可以和相鄰的一堆合併得到新的一堆,所得的分數是新的一堆的數量。所有的石子合併成一堆後,最大的分數,最小的分數是多少。這是乙個環,需要拆分成鏈,把這n堆,複製一遍,變成2n堆。dp的時候還是得保證長度為n。dp min i j 表示合併i j這個區間所得到的最小的分數。...