Hướng dẫn giải của [Ninh Bình - TS10 - 2024] Bài 4: Dãy số
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Tác giả:
Subtask 1: ~n = 10~ và dãy ban đầu là một dãy không giảm.
Đáp số chính là tổng tất cả các phần tử trong dãy ~a~, và in ra tất cả các phần tử trong dãy đó.
ĐPT: ~O~(~n~)
Subtask 2 + 3: ~11 \le n \le 10^3~
Ta sẽ duyệt tất cả các cặp phần tử trong mảng rồi kiểm tra xem:
- Liệu đây có phải là dãy không giảm hay không?
- Nếu có, ta sẽ
maximize
biến kết quả.
Sau đó, ta sẽ duyệt lại các cặp theo một lần nữa để xem đâu là các cặp số mà tổng tất cả phần tử nằm giữa chúng đúng bằng biến kết quả và là dãy con không giảm.
ĐPT: ~O~(~n^2~)
Subtask 4: ~(10^3 < n \leq 10^5)~
Nhận xét: Do các phần tử mảng ~a~ đều là số nguyên dương, ta có thể sử dụng thuật toán hai con trỏ để tối ưu việc tìm kiếm các cặp thỏa mãn.
Phần ý tưởng còn lại đều dựa vào subtask trên.
ĐPT: ~O~(~n~)
Code mẫu:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 9;
int n, a[N];
namespace sub1 {
bool valid() {
return n <= 10;
}
void solve() {
int sum = 0;
for (int i = 1; i <= n; i++) {
sum += a[i];
}
cout << sum << "\n";
for (int i = 1; i <= n; i++) {
cout << a[i] << " ";
}
exit(0);
}
}
namespace sub3 {
bool valid() {
return n <= (int)1e3;
}
void solve() {
int mx = 0;
for (int i = 1; i <= n; i++) {
int res = a[i];
for (int j = i + 1; j <= n; j++) {
if (a[j] < a[j - 1]) {
break;
}
res += a[j];
}
mx = max(mx, res);
}
cout << mx << "\n";
for (int i = 1; i <= n; i++) {
int res = a[i];
for (int j = i + 1; j <= n; j++) {
if (a[j] < a[j - 1]) {
break;
}
res += a[j];
}
if (res != mx) continue;
cout << a[i] << " ";
for (int j = i + 1; j <= n; j++) {
if (a[j] < a[j - 1]) {
break;
}
cout << a[j] << " ";
}
cout << "\n";
}
exit(0);
}
}
namespace sub4 {
int pfs[N];
void solve() {
for (int i = 1; i <= n; i++) {
pfs[i] = pfs[i - 1] + a[i];
}
int ans = 0;
int l = 1;
while (l <= n) {
int r = l;
while (r < n and a[r] <= a[r + 1]) ++r;
ans = max(ans, pfs[r] - pfs[l - 1]);
l = r + 1;
}
cout << ans << "\n";
l = 1;
vector<pair<int, int>> v;
while (l <= n) {
int r = l;
while (r < n and a[r] <= a[r + 1]) ++r;
if (pfs[r] - pfs[l - 1] == ans) {
v.push_back(make_pair(l, r));
}
l = r + 1;
}
for (pair<int, int> i: v) {
for (int j = i.first; j <= i.second; j++) {
cout << a[j] << " ";
}
cout << "\n";
}
}
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
if (sub1::valid()) sub1::solve();
if (sub3::valid()) sub3::solve();
sub4::solve();
return 0;
}
// <33
Bình luận