# **Tham Lam**
**Bài 3: Bus**
```cpp
#include <bits/stdc++.h>
using namespace std;
int n,m,t,k,A[100005],B[100005],d = 0,sum = 0,maxx = INT_MIN;
int main() {
cin >> n >> m;
for (int i = 1; i<= n; ++i) {
cin >> t;
cin >> k;
for (int j = 1; j <= k ; ++j) {
cin >> A[j];
d++;
if (A[j] - sum >= 0) B[d] = A[j] - sum;
else B[d] = 0;
}
sum += t;
}
sort(B+1,B+d+1);
cout << sum+B[m];
// Thằng đầu tiên tốn B[1] thời gian, thằng thứ m tốn B[m] thời gian vì đã sắp xếp
// tăng dần nên thời gian ngắn nhất để xếp m thằng vào là B[m]
return 0;
}
```
# **Tìm Kiếm Nhị Phân**
**Bài 1: Hàng cây – Cưa máy**
```cpp
#include<bits/stdc++.h>
using namespace std;
int n,a[1000001],m,l,r,res=0;
long long sum(int h)
{
long long res=0;
for (int i=1;i<=n;i++)
{
if (a[i]<=h) return res;
else res+=(a[i]-h);
}
return res;
}
int main()
{
cin>>n>>m;
for (int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+n+1,greater<int>());
l=a[n];r=a[1];
while (l<=r)
{
int mid=(l+r)/2;
if (sum(mid)<m) r=mid-1;
else
{
res=mid;
l=mid+1;
}
}
cout<<res;
}
```
# **Quy Hoạch Động**
* **Knapsack**
**Bài 3: Chia Kẹo**
- Chưa Truy Vết
```cpp
#include <bits/stdc++.h>
using namespace std;
bool F[100005];
int n,s = 0,A[105];
int main() {
memset(F,false,sizeof(F));
F[0] = true;
cin >> n;
for (int i = 1; i <= n; ++i ) {
cin >> A[i];
s += A[i];
}
for (int i = 1; i <= n; ++i)
for (int j = s; j >= A[i]; --j)
if (F[j - A[i]])
F[j] = true;
for (int i = s/2; i >= 1; i--) if (F[i]) {
cout << s - (i*2);
exit(0);
}
return 0;
}
```
* **Không Phải Knapsack**
**Bài 3: Bitcoin**
```cpp
#include <bits/stdc++.h>
using namespace std;
double F[105],A[105],x;
int n,t;
bool Fr[105];
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> t;
for (int i = 1; i <= t; ++i) {
cin >> n >> x;
for (int j = 1; j <= n; ++j) cin >> A[j];
F[0] = x;
for (int j = 1; j <= n; ++j) {
F[j] = F[j-1];
for (int k = j-1; k >= 1; --k)
F[j] = max(F[j],F[k]/A[k]*A[j]-F[k]/50);
}
cout << setprecision(5) << fixed << F[n] << "\n";
}
return 0;
}
```
# **Đồ Thị**
**Bài 5: Ông Bà Già Ngâu**
* Cách 1: Dùng danh sách kề
```cpp
#include <bits/stdc++.h>
using namespace std;
int n,m,s,t,d1[1005],d2[1005],minn = INT_MAX,kq,u,v,w;
vector<pair<int,int>> ke[1005];
bool Fr[1005];
void djs(int s, int d[]) {
for (int i = 1; i <= n; ++i) {
d[i] = INT_MAX;
Fr[i] = true;
}
d[s] = 0;
while (true) {
int u = 0, minn = INT_MAX;
for (int i = 1; i <= n; ++i)
if (Fr[i] && minn > d[i]) {
u = i;
minn = d[i];
}
Fr[u] = false;
if (u == 0) break;
for (pair<int,int> v : ke[u])
if (Fr[v.second] && v.first + d[u] < d[v.second]) {
d[v.second] = d[u] + v.first;
}
}
}
int main() {
cin >> n >> m >> s >> t;
for (int i = 1; i <= m; ++i) {
cin >> u >> v >> w;
ke[u].push_back({w,v});
ke[v].push_back({w,u});
}
djs(s,d1);
djs(t,d2);
for (int i = 1; i <= n; ++i)
if (d1[i] == d2[i] && d1[i] < minn) {
minn = d1[i];
kq = i;
}
if (kq != 0) cout << kq;
else cout << "CRY";
return 0;
}
```
* Cách 2: Dùng mảng lưu trọng số
```cpp
#include <bits/stdc++.h>
using namespace std;
int n,m,s,t,d1[10005],d2[10005],minn = INT_MAX,kq,u,v,w,A[1005][1005];
bool Fr[10005];
void djs(int s, int d[]) {
for (int i = 1; i <= n; ++i) {
d[i] = INT_MAX;
Fr[i] = true;
}
d[s] = 0;
while (true) {
int u = 0, minn = INT_MAX;
for (int i = 1; i <= n; ++i)
if (Fr[i] && minn > d[i]) {
u = i;
minn = d[i];
}
Fr[u] = false;
if (u == 0) break;
for (int v = 1; v <= n; ++v)
if (Fr[v] && u != v && A[u][v] != INT_MAX && A[u][v] + d[u] < d[v])
d[v] = A[u][v] + d[u];
}
}
int main() {
cin >> n >> m >> s >> t;
memset(A,INT_MAX,sizeof(A));
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j) if (i == j) A[i][j] = 0;
else A[i][j] = INT_MAX;
for (int i = 1; i <= m; ++i) {
cin >> u >> v >> w;
A[u][v] = A[v][u] = w;
}
djs(s,d1);
djs(t,d2);
for (int i = 1; i <= n; ++i)
if (d1[i] == d2[i] && d1[i] < minn) {
minn = d1[i];
kq = i;
}
if (kq != 0) cout << kq;
else cout << "CRY";
return 0;
}
```
**Bài 7: Hệ thống đảo cung cấp xăng**
```cpp
#include <bits/stdc++.h>
using namespace std;
int f,l,n,m,x,y,Q[100000],trace[10000],temp,temp2,d = 1,cnt = 0,A[10000],B[10000],C[10000];
vector<int> ke[10000];
bool visit[10000] = {false};
void truyvet(int v) {
temp2 = trace[v];
while (trace[temp2] != -1) {
cnt ++;
C[cnt] = temp2;
//cout << temp2 << endl;
temp2 = trace[temp2];
}
cout << cnt << "\n";
for (int i = cnt; i>=1; i--) cout << C[i] << " " ;
}
void bfs(int s) {
f = l = 1;
Q[l] = s;
trace[s] = -1;
visit[s] = true;
while (f <= l) {
temp = Q[f];
f++;
for (int v : ke[temp]) if (! visit[v]) {
visit[v] = true;
trace[v] = temp;
l++;
Q[l] = v;
if (v == y ) {
truyvet(v);
exit(0);
}
}
}
}
int power(int a) {
return a*a;
}
int main() {
cin >> n >> m >> x >> y;
for (int i = 1; i <= n; ++i) cin >> A[i] >> B[i];
for (int i = 1; i<= n-1; ++i)
for (int j = i +1; j<= n; ++j)
if ((power(A[j]-A[i]) + power(B[j]-B[i])) < power(m)){
ke[i].push_back(j);
ke[j].push_back(i);
}
bfs(x);
cout << "-1";
return 0;
}
```