1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Bài toán di chuyển từ Tây sang Đông pps

10 846 3

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 163,96 KB

Nội dung

Bài toán di chuyển từ Tây sang Đông Cho một bảng A kích thước m x n, trên đó ghi các số nguyên. Một người xuất phát tại ô nào đó của cột 1, cần sang cột n (tại ô nào cũng được). Quy tắc: Từ ô A[i, j] chỉ được quyền sang một trong 3 ô A[i, j + 1]; A[i - 1, j + 1]; A[i + 1, j + 1]. Hãy tìm vị trí ô xuất phát và hành trình đi từ cột 1 sang cột n sao cho tổng các số ghi trên đường đi là lớn nhất. Gợi ý: Gọi B[i, j] là số điểm lớn nhất có thể có được khi tới ô A[i, j]. Rõ ràng đối với những ô ở cột 1 thì B[i, 1] = A[i, 1]: Với những ô (i, j) ở các cột khác. Vì chỉ những ô (i, j – 1), (i – 1, j – 1), (i + 1, j – 1) là có thể sang được ô (i, j), và khi sang ô (i, j) thì số điểm được cộng thêm A[i, j] nữa. Chúng ta cần B[i, j] là số điểm lớn nhất có thể nên B[i, j] = max(B[i, j - 1], B[i - 1, j - 1], B[i + 1, j - 1]) + A[i, j]. Ta dùng công thức truy hồi này tính tất cả các B[i, j]. Cuối cùng chọn ra B[i, n] là phần tử lớn nhất trên cột n của bảng B và từ đó truy vết tìm ra đường đi nhiều điểm nhất. Cài đặt bằng ngôn ngữ Pascal: PROGRAM tay_dong; CONST Max = 2000000000; VAR A,B,T:ARRAY[0 101,1 100] OF LONGINT; Tong:LONGINT; m,n,dongcuoi:INTEGER; PROCEDURE Nhap; VAR i,j:INTEGER; BEGIN readln(m,n); FOR i:=1 TO m DO BEGIN FOR j:=1 TO n DO read(A[i,j]); readln; END; FOR i:=1 TO n DO END; FUNCTION Min(i,j:INTEGER):INTEGER; VAR m:INTEGER; BEGIN m:=i-1; IF B[i,j-1] < B[m,j-1] THEN m:=i; IF B[i+1,j-1] < B[m,j-1] THEN m:=i+1; Min:=m; END; PROCEDURE Taobang; VAR i,j,d:INTEGER; BEGIN FOR j:=1 TO n DO BEGIN B[0,j]:=Max; B[m+1,j]:=Max; END; FOR i:=1 TO m DO B[i,1]:=A[i,1]; FOR j:=2 TO n DO FOR i:=1 TO m DO BEGIN d:=min(i,j); B[i,j]:=B[d,j-1]+A[i,j]; T[i,j]:=d; END; tong:=B[1,n]; dongcuoi:=1; FOR i:=2 TO m DO IF tong>B[i,n] THEN BEGIN tong:=B[i,n]; dongcuoi:=i; END; END; PROCEDURE TruyVet(dong,cot:INTEGER); BEGIN IF cot=0 THEN writeln(tong) ELSE BEGIN TruyVet(T[dong,cot],cot-1); write(dong,' '); END; END; BEGIN assign(Input,'input.inp'); reset(Input); assign(Output,'Output.out'); rewrite(Output); Nhap; Taobang; TruyVet(dongcuoi,n); close(Input); close(Output); END. Cài đặt bằng ngôn ngữ C++ #include <iostream> #include <fstream> using namespace std; #define MAX 100 #define MAXINT 2000000000 ifstream fi("Input.inp"); ofstream fo("Output.out"); int A[MAX+2][MAX+1],B[MAX+2][MAX+1],T[MAX+2][MAX+1],m,n,R,sum; void Enter() { fi>>m>>n; int i,j; for (i=1; i<=m; i++) { for (j=1; j<=n; j++) fi>>A[i][j]; fi.ignore(); } } int Min(int i, int j) { int m=i-1; if (B[i][j-1]<B[m][j-1]) m=i; if (B[i+1][j-1]<B[m][j-1]) m=i+1; return m; } void Optimize() { int i,j,d; for (j=1; j<=n; j++) B[0][j]=B[m+1][j]=MAXINT; for (i=1; i<=m; i++) B[i][1]=A[i][1]; for (j=2; j<=n; j++) for (i=1; i<=m; i++) { d=Min(i,j); B[i][j]=B[d][j-1]+A[i][j]; T[i][j]=d; } R=1; sum=B[1][n]; for (i=2; i<=m; i++) if (B[i][n]<sum) { sum=B[i][n]; R=i; } } void Trace(int i, int j) { if (i==0) fo<<sum<<endl; else { Trace(T[i][j],j-1); fo<<i<<" "; } } int main() { Enter(); Optimize(); Trace(R,n); fi.close(); fo.close(); return 0; } . Bài toán di chuyển từ Tây sang Đông Cho một bảng A kích thước m x n, trên đó ghi các số nguyên. Một người xuất phát tại ô nào đó của cột 1, cần sang cột n (tại ô nào cũng được). Quy tắc: Từ. Quy tắc: Từ ô A[i, j] chỉ được quyền sang một trong 3 ô A[i, j + 1]; A[i - 1, j + 1]; A[i + 1, j + 1]. Hãy tìm vị trí ô xuất phát và hành trình đi từ cột 1 sang cột n sao cho tổng các số ghi trên. các cột khác. Vì chỉ những ô (i, j – 1), (i – 1, j – 1), (i + 1, j – 1) là có thể sang được ô (i, j), và khi sang ô (i, j) thì số điểm được cộng thêm A[i, j] nữa. Chúng ta cần B[i, j] là số

Ngày đăng: 13/08/2014, 19:21

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w