一、試題描述
給定乙個具有n(n<50)個頂點(從1到n編號)的凸多邊形,每個頂點的權均已知。問如何把這個凸多邊形劃分成n-2個互不相交的三角形,使得這些三角形頂點的權的乘積之和最小?
輸入檔案:第一行 頂點數n
第二行n個頂點(從1到n)的權值
輸出格式:最小的和的值
各三角形組成的方式
輸入示例:5
122123245231
輸出示例:theminimumis :12214884
theformationof 3 ********:
3 4 5, 1 5 3, 1 2 3
二、試題分析
這是一道很典型的動態規劃問題。設
f[i,j]
(i)表示從頂點
i到頂點
j的凸多邊形三角剖分後所得到的最大乘積,我們可以得到下面的動態轉移方程:
f[i,j]=min(i
目標狀態為:
f[1,n]
但我們可以發現
,由於這裡為乘積之和,在輸入資料較大時有可能超過長整形甚至實形的範圍,所以我們還需用高精度計算,但這是大家的基本功,程式中就沒有寫了,請讀者自行完成。
三、參考程式
var s
:array[1..50] of integer;
f:array[1..50,1..50] of comp; d
:array[1..50,1..50] of byte; n
:integer;
procedure init;
(輸入資料)
var i
:integer;
begin
readln(n);
for i:=1 to n do read(s[i]);
end;
procedure dynamic;
(動態規劃)
var i,j,k
:integer;
begin
for i:=1 to n do
for j:=i+1 to n do f[i,j]:=maxlongint;
(賦初始值)
for i:=n-2 downto 1 do
for j:=i+2 to n do
for k:=i+1 to j-1 do
if (f[i,j]>f[i,k]+f[k,j]+s[i]*s[j]*s[k]) then
begin
f[i,j]:=f[i,k]+f[k,j]+s[i]*s[j]*s[k];
d[i,j]:=k;
(記錄父節點)
end;
end;
procedure print(i,j:integer);
(輸出每個三角形)
begin
if j=i+1 then exit;
write(',',i,' ',j,' ',d[i,j]);
out(i,d[i,j]);
out(d[i,j],j);
end;
procedure out;
(輸出資訊)
begin
assign(output,'output.txt'); rewrite(output);
writeln('the minimum is :',f[1,n]:0:0);
writeln('the formation of ',n-2,' ********:');
write(1,' ',n,' 'd[1,n]);
out(1,d[1,n]);
out(d[1,n],n);
close(output);
end;
begin
(主程式)
init;
dynamic;
out;
end.
凸多邊形三角劃分
傳送門 loj公升級版 這道題雖然是基礎的區間dp,但是還是很值得一說的。我們用dp i j 表示第i個點到第j個點劃分的最大值。注意我們只列舉了兩個端點,第三個頂點是我們列舉的那個k,之後發現k這個頂點可以把整個區間分成兩塊,我們就可以進行區間dp了。只不過這道題要使用高精度。需要自己過載一下,對...
劃分凸多邊形
時間限制 800ms 記憶體限制 65535k 提交次數 0 通過次數 0 題型 程式設計題 語言 g gcc vc 問題描述 乙個正凸n邊形,可以用n 3條互不相交的對角線將正n邊形分成n 2個三角形。現在要求讀入n邊形的n n 20 輸出不同劃分方法的總數 要求解的是劃分方法數,而不需要輸出各種...
凸多邊形區域劃分為三角形問題
rt 乙個凸多邊形區域,有n條邊,將其劃分為三角形區域,問共有多少種分割方法。1.我們從最簡單情況開始 n 3,f 3 1 2.當n 4,f 4 2 3.n邊時 我們從節點1開始考慮,要想分割成三角形區域,1不能和與它相鄰的點連線,所以1可以連線3,4,n 1 假設1連線i,則分割成的兩個區域分別為...