acm競賽經典演算法
計算機與資訊科技學院
目錄第十一次課動態規劃(解決中等規模的問題) 2
第十二次課動態規劃(2) 8
第十三次課動態規劃(3) 13
第十四次課動態規劃(4) 18
第十五次課動態規劃(5) 23
第十六次課動態規劃(6) 29
第十七次課動態規劃(7) 35
第十八次課動態規劃(8) 40
用動態規劃去迴避深搜的重複性,仍然解決搜尋問題中求最值的問題。
1.數字三角形
(圖3.1-1)示出了乙個數字三角形。 請編乙個程式計算從頂至底的某處的一條路
徑,使該路徑所經過的數字的總和最大。
●每一步可沿左斜線向下或右斜線向下走;
●1<三角形行數≤100;
●三角形中的數字為整數0,1,…99;
輸入資料:
由檔案中首先讀到的是三角形的行數。
在例子中表示如下:57
3 88 1 0
2 7 4 4
4 5 2 6 5
輸出資料:
把最大總和(整數)寫入檔案。
上例為:
30圖3.1-1)
要素:狀態:到目標的最大值a[i,j];
階段:按階段進行寬搜
狀態轉移方程:a[i,j]:=max+c[i,j];
動態規劃程式如下:
var a,b,c:array[1..100,1..100]of integer;
i,j,n:integer;
procedure print(i,j:integer);
begin
if (i=n)or(j=n) then begin write('->','(',i,',',j,')');exit;end;
write('->','(',i,',',j,')');
print(i+1,b[i,j]);
end;
begin
readln(n);
for i:=1 to n do begin
for j:=1 to i do
read(c[i,j]);
readln;
end;
for i:=1 to n do
begin
a[n,i]:=c[n,i];
b[n,i]:=0;
end;
for i:=n-1 downto 1 do
for j:=1 to i do
if a[i+1,j]>a[i+1,j+1] then begin a[i,j]:=a[i+1,j]+c[i,j];b[i,j]:=j;end
else begin a[i,j]:=a[i+1,j+1]+c[i,j];b[i,j]:=j+1;end;
writeln(a[1,1]);
print(1,1);
end.
(動態規劃是處理問題的一種思想,求最值問題。可以從上到下,也可以從下向上,一般動態規劃有三重迴圈。
(1) 第一重分階段;
(2) 第二重在階段中迴圈該階段中的所有狀態;
(3) 第三重對某個狀態的值的求解
如果想記住路線,則加乙個陣列記路線。)
使用動態規劃需要滿足兩個條件:
(1) 最優子結構;
(2) 無後效性,如果有後效性,看能不能改變狀態的含義,變成無後效性。
無後效性的定義:即後面的運算不能改變前面運算結果。即當前狀態的結果只與它前面已得到結果的狀態有關係,而與後面的狀態的值沒關係。
2.網格中取數
給出乙個n行m列(共有n×m個結點)的網格,左上角座標為(1,1),右下角座標(n,m),每個網格中有乙個整數,從左下角開始只能沿著向上或向右的方向前進到下乙個網格(如從(1,1)只能走到(1,2)或(2,1))。計算並輸出從(1,1)出發,到(n,m)經過的數字的總和的最小值。
程式如下:
var a,c:array[0..101,0..101]of integer;
b:array[1..100,1..100,1..2]of -1..0;
n,m,i,j:integer;
procedure print(i,j:integer);
begin
if (b[i,j,1]=0)and(b[i,j,2]=0) then begin write('(',i,',',j,')');exit;end;
print(i+b[i,j,1],j+b[i,j,2]);
write('----->(',i,',',j,')');
end;
begin
readln(n,m);
for i:=1 to n do
for j:=1 to m do
read(c[i,j]);
a[1,1]:=c[1,1]; b[1,1,1]:=0;b[1,1,2]:=0;
for i:=2 to m do
begin
a[1,i]:=a[1,i-1]+c[1,i];
b[1,i,1]:=0;b[1,i,2]:=-1;
end;
for i:=2 to n do
begin
a[i,1]:=a[i-1,1]+c[i,1];
b[i,1,1]:=-1;b[i,1,2]:=0;
end;
for i:=2 to n do
for j:=2 to n do
begin
if a[i-1,j]>a[i,j-1] then begin a[i,j]:=a[i,j-1];b[i,j,1]:=0;b[i,j,2]:
=-1;end else begin a[i,j]:=a[i-1,j];b[i,j,1]:=-1;b[i,j,2]:
=0;end;
a[i,j]:=a[i,j]+c[i,j];
end;
writeln(a[n,m]);
print(n,m);
end.
3.網格路線問題(計數問題)。
給出乙個n行m列(共有n×m個結點)的網格,左下角座標為(1,1),右上角座標(n,m),乙個物體從左下角開始只能沿著向上或向右的方向前進到下乙個結點(如從(1,1)只能走到(1,2)或(2,1))鍵盤輸入n,m,計算並輸出從(1,1)出發,到(n,m)共有多少條路徑?
程式如下:
var a:array[0..10,0..10]of integer;
i,j,n,m:integer;
begin
readln(n,m);
for i:=1 to m do
a[1,i]:=1;
for i:=2 to n do
a[i,1]:=1;
for i:=2 to n do
for j:=2 to m do
a[i,j]:=a[i-1,j]+a[i,j-1];
writeln(a[n,m]);
end.
4.騎士遊歷:
設有乙個n*m的棋盤(2<=n<=50,2<=m<=50),在棋盤上任一點有乙個中國象棋馬,馬走的規則為:1.馬走日字 2.馬只能向右走.
任務1:當n,m 輸入之後,找出一條從左下角到右上角的路徑.
例如:輸入 n=4,m=4
輸出:路徑的格式:(1,1)->(2,3)->(4,4)
若不存在路徑,則輸出"no"
const
rule:array[1..4,1..2]of integer=((-2,-1),(-1,-2),(1,-2),(2,-1));
var a:array[1..50,1..50]of integer;
b:array[1..50,1..50,1..4]of boolean;
n,m,i,j,k,s:integer;
procedure print(i,j:integer);
vark:integer;
begin
if (i=1)and(j=1) then begin write('(',i,',',j,')'); exit; end;
for k:=1 to 4 do
if b[i,j,k] then
begin b[i,j,k]:=false;
print(i+rule[k,1],j+rule[k,2]);
write('->','(',i,',',j,')');
if (i=4)and(j=4) then writeln;
b[i,j,k]:=true;
end;
end;
begin
readln(n,m);
fillchar(a,sizeof(a),0);
a[1,1]:=1;
fillchar(b,sizeof(b),false);
for j:=1 to m do
for i:=1 to n do
for k:=1 to 4 do
if (j+rule[k,2]>0)and(j+rule[k,2]<=m)and(i+rule[k,1]>0)and(i+rule[k,1]<=n)then
begin
a[i,j]:=a[i,j]+a[i+rule[k,1],j+rule[k,2]];
青馬工程第四次培訓
今天是十一月十日,在王改紅老師的主持下,我們進行了青馬工程第四次培訓,這次培訓與前三次有所不同,開口講話的由老師變成了我們,培訓一開始,王老師就告訴我們今天的培訓改為座談會,由我們對老師提出的幾個與青馬工程和我們平時工作息息相關的問題發表意見。我們之前都好做了心理準備,但座談會一開始,同學們還是免不...
第四次作業
1 2001年5月6日,甲公司支付價款 元 含交易費用20000元和已宣告未發放現金股利140000元 購入乙公司發行的 200000股。甲公司將其劃分為可供 金融資產。2 2001年5月10日,甲公司收到乙公司發放的現金股利140000元。3 200l年6月30日,該 市價為每股52元。4 200...
第四次檢測
時間 50分鐘總分 50分 可能用到的相對原子質量 fe 56 o 16 1 選擇題 24分 1 在空氣中敞口放置的一瓶無水酒精,沒有燃燒的原因是 a 沒有與氧氣接觸b 無水酒精是液體 c 沒有達到著火點d 酒精沒有可燃性 2 燃燒 緩慢氧化的共同之處是 a 它們都發生了劇烈的化學反應 b 它們都發...