Tống Bá Quang Anh BTL Toán rời rạc docx BÀI TẬP LỚN MÔN TOÁN RỜI RẠC Sinh viên thực hiện Tống Bá Quang Anh Lớp TIN13A2 I Tự luận Bài 1 Một xâu nhị phân được gọi là Palindrome nếu ta đảo ngược xâu đó sẽ cho kết quả là chính nó Ví dụ các xâu 101101101, 1111, 01010 là Palindrome Hãy đếm số xâu Palindrome có độ dài n Lời giải Xâu nhị phân có độ dài n có trường hợp 2
Trang 1BÀI TẬP LỚN MÔN: TOÁN RỜI RẠC
Sinh viên thực hiện:Tống Bá Quang Anh
Lớp:TIN13A2
I Tự luận
Bài 1 Một xâu nhị phân được gọi là Palindrome nếu ta đảo ngược xâu đó sẽ cho kết quả
là chính nó Ví dụ các xâu 101101101, 1111, 01010 là Palindrome Hãy đếm số xâu Palindrome có độ dài n
Lời giải:
Xâu nhị phân có độ dài n có2𝑛trường hợp
𝑎
1𝑎
2… 𝑎
𝑛
Xâu được gọi là Palindrome nếu đảo ngược xâu đó ta sẽ được kết quả chính nó nên ta
1𝑎
2… 𝑎𝑛
2 −1 𝑎𝑛 2
𝑎𝑛
2 −1……𝑎
2𝑎
1
TH1: n là số chẵn
Xâu nhị phân sẽ có2 trường hợp xảy ra
𝑛 2
TH2: n là số lẻ
Xâu nhị phân sẽ có2 trường hợp xảy ra
𝑛+1 2
Bài 2 Nam có 8 tờ tiền loại 1, 2, 3, 4, 5, 6, 7, 8 nghìn đồng Nam cho Hoa rút ngẫu nhiên
5 tờ của mình Hãy chứng minh, Hoa bao giờ cũng có ít nhất hai tờ tiền có tổng giá trị là
9 nghìn đồng
Lời giải:
Giả sử Hoa không có 2 tờ tiền có tổng giá trị là 9 nghìn đồng
Gọi a1, a2, , a8 lần lượt là giá trị của các loại tiền
Khi đó, ta có:
Trang 2a1 + a2≠9
a2 + a3≠9
a3 + a4≠9
a4 + a5≠9
a5 + a6≠9 a6 + a7≠9 a7 + a8≠9 a8 + a1≠9 Cộng 2 vế của các bất đẳng thức trên ta được:
2.(a1+a2+a3+a4+a5+a6+a7+a8)≠72
Mà: 2.(a1+a2+a3+a4+a5+a6+a7+a8)=2.(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8) = 72
=> Giả thiết ban đầu là sai Vậy bài toán đã cho được chứng minh
Bài 3 Tìm số nghiệm nguyên không âm của phương trình: x1 + x2 + x3 + x4 = 20, thỏa
màn điều kiện: x1 ≤ 3; x2 ≥2; x3 >4
Lời giải: Phương trình: x1 + x2 + x3 + x4 = 20 (1)
Vì các nghiệm của phương trình là các nghiệm nguyên không âm nên ta có thể viết lại điều kiện bài toán như sau: x1 ≤ 3; x2 ≥2; x3 ≥5 (*)
Xét các điều kiện:
+) x2 ≥2; x3 ≥5 (**)
+) x1 ≥4; x2 ≥2; x3 ≥5 (***)
Gọi p,q,r lần lượt là các số nghiệm nguyên không âm của phương trình (1) thỏa mãn các điều kiện (*), (**), (***)
Ta có: p = q-r
- Tính q:
Đặt X1 = x1; X2 = x2 - 2; X3 = x3 - 5; X4 = x4, phương trình (1) trở thành:
X1 + X2 + X3 + X4 = 13 (2)
Số nghiệm nguyên không âm của phương trình (2) bằng số nghiệm của phương trình (1) thỏa mãn điều kiện (**)
Mà số nghiệm của phương trình (2) là:
Trang 3= = = = 560.
𝐶
𝑛+𝑘−1
𝑛−1
𝐶
4+13−1
4−1
𝐶
16
3 16!
13!.3!
- Tìm r:
Đặt X1 = x1 - 4; X2 = x2 - 2 ; X3 = x3 - 5; X4 = x4, phương trình (1) trở thành:
X1 + X2 + X3 + X4 = 9 (3)
Số nghiệm nguyên không âm của phương trình (2) bằng số nghiệm của phương trình (1) thỏa mãn điều kiện (***)
Mà số nghiệm của phương trình (2) là:
𝐶
𝑛+𝑘−1
𝑛−1
𝐶
4+9−1
4−1
𝐶
12
3 12!
9!.3!
⇨ p = q – r = 560 – 220 = 340
Vậy số nghiệm nguyên không âm của phương trình (1) thỏa mãn điều kiện (*) là 340
Bài 4 Trong một cuộc hội thảo khoa học, một số nhà khoa học bắt tay nhau Hãy chứng
minh số người bắt tay với một số lẻ người khác là một số chẵn
Lời giải:
- Gọi A là tổng số cái bắt tay của các người dự họp
- Gọi B là tổng số cái bắt tay của các người bắt tay một số chẵn lần
- Gọi C là tổng số cái bắt tay của các người bắt tay một số lẻ lần
- A = B + C
=> A chẵn, vì mỗi cái bắt tay được thực hiện bởi 2 người
B hiển nhiên chẵn theo cách gọi ở trên
=> Vậy C chẵn (Vì A chẵn, B chẵn, A = B + C) Mặt khác C là tổng của các sổ lẻ, vậy số người bắt tay 1 số lẻ lần là 1 số chẵn
Trang 4Bài 5.Cho đồ thị được biểu diễn bằng hình dưới đây:
a) Viết thứ tự các đỉnh được thăm của đồ thị theo thuật toán BFS, DFS
b) Tìm đường đi ngắn nhất từ đỉnh 0 đến các đỉnh còn lại của đồ thị bằng
thuật toán Dijkstra
c) Tìm cây khung nhỏ nhất của đồ thị trên bằng thuật toán Kruskal
d) Tìm cây khung nhỏ nhất của đồ thị trên bằng thuật toán Prim
Lời giải:
a) Thăm đỉnh theo BFS: 0,1,7,2,8,3,5,6,4
Thăm đỉnh theo DFS: 0,1,2,8,6,7,5,4,3
b) Đường đi ngắn nhất từ đỉnh 0 đến các đỉnh còn lại của đồ thị thuật toán Dijkstra
Đường đi ngắn nhất từ đỉnh 0 đến các đỉnh còn lại của đồ thị thuật toán Dijkstra: {(0,1);(1,2);(2,3);(5,4);(6,5);(7,6);(0,7);(2,8)}
=> DDNN = 4+8+7+10+2+4+8+2 = 45
Trang 5c) Cây khung nhỏ nhất bằng thuật toán Kruskal
+) Bước 1: Sắp xếp các cạnh theo trọng số tăng dần:
(6,7); (5,6); (2,8); (0,1); (2,5); (6,8); (7,8); (2,3); (0,7); (1,2); (3,4); (4,5)
+) Bước 2: Đặt cây khung cần tìm là T = ∅
(*) Bổ sung: (6,7); (5,6); (2,8); (0,1); (2,5) (*) Loại (6,8); (7,8) vì tạo ra chu trình con (*) Bổ sung (2,3); (0,7)
(*) Loại (1,2) vì tạo ra chu trình con (*) Bổ sung (3,4)
(*) Loại (4,5) vì tạo ra chu trình con Thuật toán kết thúc vì đã bổ sung 8 cạnh vào cây khung T
+) Bước 3: Kết luận:
Danh sách cạnh cây khung T: { (6,7); (5,6); (2,8); (0,1); (2,5); (2,3); (0,7); (3,4) } CKNN = 1 + 2 + 2 + 4 + 4 + 7 + 8 + 9 = 37
Cây khung T:
Trang 6d) Cây khung nhỏ nhất bằng thuật toán Prim
Khởi
tạo
[0,0]* [4,0]* [ ,0]∞ [ ,0]∞ [ ,0]∞ [ ,0]∞ [ ,0]∞ [8,0] [ ,0]∞ 0
B1 - - [8,1] [ ,0]∞ [ ,0]∞ [ ,0]∞ [ ,0]∞ [8,0]* [ ,0]∞ 0,1
Cặp cạnh {(0,1); (5,2); (2,3); (3,4); (6,5); (7,6); (0,7); (6,8)}
CKNN = 4+4+7+9+2+1+8+6 = 41
=> Cây khung nhỏ nhất bằng thuật toán Prim là:
Trang 7II Lập trình
Bài 1 Lập trình cài đặt thuật toán duyệt đồ thị theo chiều rộng (BFS).
Code (C++) :
#include <iostream>
#include <fstream>
#include <queue>
using namespace std;
int n; //so dinh cua do thi
int matrix[1001][1001]; //ma tran ke
bool visited[1001]; //kiem tra cac dinh da duoc duyet chua - bd cac dinh chua duoc duyet la
"false"
void Init()
{
ifstream file("matrixts.txt", ios::in);
file>>n;
Trang 8for(int i=1; i<=n; i++)
{
for(int j=1; j<=n; j++) {
file>>matrix[i][j]; }
visited[i] = false;
}
}
void BFS(int u)
{
cout<<"BFS{"<< u << "}: "; queue<int> Q;
Q.push(u);
visited[u] = true;
while(!Q.empty())
{
int s = Q.front();
cout<< s << " ";
Q.pop();
for(int t = 1; t<=n; t++) {
Trang 9if(visited[t] == false && matrix[s][t] == 1)
{
Q.push(t);
visited[t] = true;
} }
}
cout<< endl;
}
int main()
{
int k;
Init();
cout<<"Chon dinh bat dau duyet: ";
cin>>k;
BFS(k);
return 0;
}
● Hình ảnh test chạy code:
Trang 10Bài 2 Lập trình cài đặt thuật toán duyệt đồ thị theo chiều sâu (DFS).
Code (C++) :
#include<iostream>
#include<fstream>
#include<stack>
using namespace std;
int n; // so dinh cua do thi
int matrix[1001][1001];
bool visited[1001];
void Init()
Trang 11ifstream file("matrix.txt", ios::in); file >> n;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++) {
file >> matrix[i][j];
}
visited[i] = false;
}
}
void DFS(int u)
{
cout << "DFS(" << u << "): "; stack<int> st;
st.push(u);
visited[u] = true;
cout << u << " ";
while(!st.empty())
{
int v = st.top();
Trang 12for(int t = 1; t <= n; t++)
{
if(visited[t] == false && matrix[v][t] == 1) {
cout << t << " ";
visited[t] = true;
st.push(v);
st.push(t);
break;
}
}
}
}
int main()
{
int s; // dinh bat dau
Init();
cout << "Chon dinh bat dau: ";
cin >> s;
DFS(s);
return 0;
Trang 13● Hình ảnh test chạy code:
Bài 3 Lập trình cài đặt thuật toán tìm cây khung nhỏ nhất của đồ thị theo thuật
toán Prim
Trang 14Bài 5 Lập trình cài đặt thuật toán nhánh cận giải bài toán cái túi.
#include <iostream>
using namespace std;
int a[100], x[100];
int n;
int w;
int tong;
int temp;
void Try(int t);
int main(){
temp=0;
tong=0;
cout<<"Nhap so luong mon hang: ";
cin>>n;
for(int i=0; i<n; i++)
{
cout<<"Nhap khoi luong mon hang thu ["<<i+1<<"]: "; cin>>x[i];
}
cout<<"Nhap khoi luong balo co the chua: ";
cin>>w;
Try(0);
return 0;
}
void Try(int t)
{
if(t>=n)
{
for(int i=0; i<n; i++)
tong+=(a[i]*x[i]);
Trang 15if(tong > temp && tong<=w) {
temp=tong;
system("cls");
temp=tong;
cout<<"Cac mon hang duoc chon la: "<<endl;
for(int i=0; i<n; i++) {
if(a[i]==1) {
cout<<"mon hang"<<i<<": "<<x[i]<<endl; }
} }
tong=0;
}
else
for(int j=0; j<=1; j++) {
a[t]=j;
t++;
Try(t);
t ;
a[t]=0;
} }
Bài 6 Lập trình cài đặt thuật toán nhánh cận giải bài toán người du lịch
#include<iostream>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
Trang 16int n,c[100][100],x[100],chuaxet[100],kq[100]; int MIN=0;
int a=1;
void Init(){
cout<<"\n Nhap n="; cin>>n;
cout<<"\n Nhap chi phi \n";
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(i!=j){
cout<<"c["<<i<<"]["<<j<<"]="; cin>>c[i][j]; }
else c[i][j]=0;
}
x[1]=1;
for(int i=2;i<=n;i++) chuaxet[i]=1;
}
void Result(){
cout<<"\n T1->";
for(int i=2;i<=n;i++) cout<<"T"<<kq[i]<<"->"; cout<<"T1";
cout<<"\n Tong chi phi la: "<<MIN;
}
void Work(){
int S=0;
for(int i=1;i<=n-1;i++){
S=S+c[x[i]][x[i+1]];
}
S=S+c[x[n]][1];
if(S<MIN||a==1){ a=0;
MIN=S;
for(int i=1;i<=n;i++) kq[i]=x[i];
}
}
void Try(int i){
for(int j=2;j<=n;j++){
if(chuaxet[j]){
x[i]=j; chuaxet[j]=0;
if(i==n) Work();
else Try(i+1);
chuaxet[j]=1;
} } }
main(){
Init();
Try(2);
Result();
return 0;
Trang 17}