'commit'
This commit is contained in:
31
GESP/Level6/2023-09-10XUANZE.md
Normal file
31
GESP/Level6/2023-09-10XUANZE.md
Normal file
@@ -0,0 +1,31 @@
|
||||
### 第9题
|
||||
动画演示构造哈夫曼树 理解哈夫曼编码
|
||||
https://www.bilibili.com/video/BV1qfHzepETR
|
||||
|
||||
https://space.bilibili.com/97391932/lists/547856?type=season
|
||||
|
||||
原始
|
||||
| $A$ | $B$ | $C$ | $D$ | $E$ | $F$ | $G$ |
|
||||
| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||
| 0.40 | 0.30 | 0.15 | 0.05 | 0.04 | 0.03 | 0.03 |
|
||||
|
||||
排序 【居然贴心到不用排序~】
|
||||
| $A$ | $B$ | $C$ | $D$ | $E$ | $F$ | $G$ |
|
||||
| ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|
||||
| 0.40 | 0.30 | 0.15 | 0.05 | 0.04 | 0.03 | 0.03 |
|
||||
|
||||
开始构建哈夫曼树过程
|
||||

|
||||
|
||||
|
||||
|
||||
### 第10题
|
||||
https://www.bilibili.com/video/BV1CLCKYuEdg
|
||||
|
||||
|
||||
### 第11题
|
||||
https://zhuanlan.zhihu.com/p/106828968
|
||||
|
||||
|
||||
### 判断题第2题
|
||||

|
||||
41
GESP/Level6/2023-09-XUEZE-7.cpp
Normal file
41
GESP/Level6/2023-09-XUEZE-7.cpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
/*
|
||||
这行代码报错的原因是:
|
||||
__data 是 ManyData 类的私有成员(private),在类外部无法直接访问。在 C++ 中,以双下划线 __ 开头的成员默认是私有的,而且这个变量确实被声明在类的 private 部分。
|
||||
要访问类的私有成员,您需要通过类的公有方法(public methods)来进行操作。
|
||||
要修复这个错误,您应该使用类提供的公有方法 at() 来访问数据。把报错的那行代码改成:
|
||||
*/
|
||||
class ManyData {
|
||||
int *__data;
|
||||
int head, tail, capacity;
|
||||
|
||||
public:
|
||||
ManyData(int cap) {
|
||||
capacity = cap;
|
||||
__data = new int[capacity];
|
||||
head = tail = 0;
|
||||
}
|
||||
void push(int val) { __data[tail++] = val; }
|
||||
int pop() { return __data[--tail]; }
|
||||
int size() { return tail - head; }
|
||||
int at(int index) {
|
||||
if (index >= 0 && index < tail - head) {
|
||||
return __data[head + index];
|
||||
}
|
||||
throw out_of_range("Index out of bounds");
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
auto myData = new ManyData(100);
|
||||
myData->push(1);
|
||||
myData->push(2);
|
||||
myData->push(3);
|
||||
myData->push(100);
|
||||
cout << myData->size() << endl;
|
||||
cout << myData->pop() << endl;
|
||||
// cout << myData.__data[0] << endl;
|
||||
cout << myData->at(0) << endl;
|
||||
return 0;
|
||||
}
|
||||
BIN
GESP/Level6/202309.pdf
Normal file
BIN
GESP/Level6/202309.pdf
Normal file
Binary file not shown.
39
GESP/Level6/20230901_bag.cpp
Normal file
39
GESP/Level6/20230901_bag.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 2010;
|
||||
|
||||
int v[N], w[N];
|
||||
int n, L;
|
||||
int f[N][N * 5]; // 需要扩大第二维
|
||||
|
||||
int main() {
|
||||
cin >> n >> L;
|
||||
int sum_v = 0;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
cin >> v[i] >> w[i];
|
||||
sum_v += v[i]; // 累计总花费上限
|
||||
}
|
||||
|
||||
// 动态规划过程
|
||||
for (int i = 1; i <= n; i++) {
|
||||
for (int j = 0; j <= sum_v; j++) { // 修正循环范围
|
||||
f[i][j] = f[i - 1][j];
|
||||
if (j >= v[i])
|
||||
f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 寻找最小花费
|
||||
int ans = -1;
|
||||
for (int j = 0; j <= sum_v; j++) { // 遍历所有可能花费
|
||||
if (f[n][j] >= L) {
|
||||
ans = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ans == -1)
|
||||
cout << "no solution" << endl;
|
||||
else
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
49
GESP/Level6/20230901_dfs.cpp
Normal file
49
GESP/Level6/20230901_dfs.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 2010;
|
||||
|
||||
/*
|
||||
5 100
|
||||
100 2000
|
||||
2 50
|
||||
4 40
|
||||
5 30
|
||||
3 20
|
||||
答案:9
|
||||
*/
|
||||
|
||||
int v[N], w[N];
|
||||
int n, L;
|
||||
int ans = INT_MAX;
|
||||
|
||||
// 走到第u个物品,已经用了c这个多的钱,使用了m这个大的容量
|
||||
void dfs(int u, int c, int m) {
|
||||
// 剪枝优化
|
||||
if (c >= ans)
|
||||
return;
|
||||
|
||||
if (m >= L) {
|
||||
if (c < ans)
|
||||
ans = c;
|
||||
return;
|
||||
}
|
||||
// 递归出口
|
||||
if (u == n + 1)
|
||||
return;
|
||||
dfs(u + 1, c + v[u], m + w[u]); // 选择当前物品
|
||||
dfs(u + 1, c, m); // 放弃当前物品
|
||||
}
|
||||
int main() {
|
||||
|
||||
cin >> n >> L;
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> v[i] >> w[i]; // 售价和容量
|
||||
|
||||
dfs(1, 0, 0);
|
||||
|
||||
if (ans < INT_MAX)
|
||||
cout << ans << endl;
|
||||
else
|
||||
cout << "no solution" << endl;
|
||||
return 0;
|
||||
}
|
||||
47
GESP/Level6/20230901_jyh.cpp
Normal file
47
GESP/Level6/20230901_jyh.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 2010;
|
||||
|
||||
int v[N], w[N];
|
||||
int n, L;
|
||||
int ans = INT_MAX;
|
||||
int memo[N][N]; // memo[u][m] 表示处理到第u个物品时,容量m的最小花费
|
||||
|
||||
void dfs(int u, int c, int m) {
|
||||
// 剪枝:当前花费已超过已知最优解
|
||||
if (c >= ans)
|
||||
return;
|
||||
|
||||
// 统一处理容量达标的情况
|
||||
m = min(m, L); // 状态压缩
|
||||
if (m >= L) {
|
||||
ans = min(ans, c); // 记录可行的解
|
||||
return;
|
||||
}
|
||||
|
||||
// 记忆化剪枝
|
||||
if (memo[u][m] != -1 && c >= memo[u][m])
|
||||
return;
|
||||
memo[u][m] = c;
|
||||
|
||||
// 递归终止条件
|
||||
if (u > n)
|
||||
return;
|
||||
|
||||
// 选当前物品
|
||||
dfs(u + 1, c + v[u], m + w[u]);
|
||||
// 不选当前物品
|
||||
dfs(u + 1, c, m);
|
||||
}
|
||||
|
||||
int main() {
|
||||
cin >> n >> L;
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> v[i] >> w[i];
|
||||
|
||||
memset(memo, -1, sizeof memo);
|
||||
dfs(1, 0, 0);
|
||||
|
||||
cout << (ans < INT_MAX ? to_string(ans) : "no solution") << endl;
|
||||
return 0;
|
||||
}
|
||||
49
GESP/Level6/20230902.cpp
Normal file
49
GESP/Level6/20230902.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
const int N = 3e5 + 10;
|
||||
int n;
|
||||
int q[N];
|
||||
int t[N];
|
||||
LL ans;
|
||||
|
||||
/*
|
||||
6
|
||||
0 1 2 3 4 5
|
||||
答案:15
|
||||
*/
|
||||
|
||||
// 归并排序,附带求顺序对的数量
|
||||
void merge_sort(int q[], int l, int r) {
|
||||
if (l >= r)
|
||||
return;
|
||||
int mid = (l + r) >> 1;
|
||||
merge_sort(q, l, mid), merge_sort(q, mid + 1, r);
|
||||
int i = l;
|
||||
int j = mid + 1;
|
||||
int k = 0;
|
||||
while (i <= mid && j <= r)
|
||||
if (q[i] <= q[j]) {
|
||||
t[k++] = q[i++];
|
||||
// 顺序对,原理:当q[i]<=q[j]时,q[i]与q[j]之后的所有数都构成顺序对
|
||||
ans += r - j + 1;
|
||||
} else
|
||||
t[k++] = q[j++];
|
||||
|
||||
while (i <= mid)
|
||||
t[k++] = q[i++];
|
||||
while (j <= r)
|
||||
t[k++] = q[j++];
|
||||
for (i = l, j = 0; i <= r; i++, j++)
|
||||
q[i] = t[j];
|
||||
}
|
||||
|
||||
int main() {
|
||||
cin >> n;
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> q[i];
|
||||
// 根据题目提示,使用归并排序,并在归并排序的过程中计算顺序对的数量
|
||||
merge_sort(q, 1, n);
|
||||
printf("%lld", ans);
|
||||
return 0;
|
||||
}
|
||||
BIN
GESP/Level6/202312.pdf
Normal file
BIN
GESP/Level6/202312.pdf
Normal file
Binary file not shown.
60
GESP/Level6/20231201_1.cpp
Normal file
60
GESP/Level6/20231201_1.cpp
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e4 + 10;
|
||||
const int INF = 0x3f3f3f3f;
|
||||
int n, m; // n个关卡,每个关卡都有一样的m个通道
|
||||
int a[N]; // 第i个通道可以让你前进a[i]关,,比如:现在第x关,选择i通道,将到达第x+a[i]关
|
||||
int b[N]; // 当你离开第s关时,将获得b[s]分的奖励
|
||||
int f[N]; // 动态规划数组,f[i]表示离开第i关时可以获得的最大分数
|
||||
int ans = -INF; // 通关时最多能够获得的分数
|
||||
|
||||
/*
|
||||
6 2
|
||||
2 3
|
||||
1 0 30 100 30 30
|
||||
答案:131
|
||||
|
||||
|
||||
6 2
|
||||
2 3
|
||||
1 0 30 100 30 -1
|
||||
答案:101
|
||||
*/
|
||||
int main() {
|
||||
cin >> n >> m; // 输入n和m
|
||||
|
||||
// 每一个关卡都有m个通道,a[i]表示第i个通道可以让你前进a[i]关
|
||||
for (int i = 1; i <= m; i++)
|
||||
cin >> a[i];
|
||||
|
||||
for (int i = 0; i < n; i++) // 关卡是从下标0开始的
|
||||
cin >> b[i]; // 通关i关时可以获得的奖励分数
|
||||
|
||||
// 动态规划
|
||||
// 状态表示:f[i]表示通关第i关时可以获得的最大分数
|
||||
// 状态转移:f[i] = max(f[i],f[i-a[j]]+b[i-a[j]])
|
||||
// 初始化:f[0] = 0
|
||||
// 答案:f[n]
|
||||
|
||||
// 因为得分可能是负数,所以初始化的时候,需要将f[i]初始化为-0x3f
|
||||
memset(f, -0x3f, sizeof f);
|
||||
f[0] = 0;
|
||||
|
||||
for (int i = 1; i < n; i++) { // 遍历每个阶段
|
||||
// 考虑当前阶段的所有决策,也就是到达这个阶段,可以有哪些决策
|
||||
// 决策:选择第j个通道,那么到达这个阶段,可以获得的最大分数就是f[i-a[j]]+b[i-a[j]]
|
||||
// 所以,f[i] = max(f[i],f[i-a[j]]+b[i-a[j]])
|
||||
for (int j = 1; j <= m; j++) {
|
||||
if (i - a[j] >= 0)
|
||||
f[i] = max(f[i], f[i - a[j]] + b[i - a[j]]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
for (int j = 1; j <= m; j++)
|
||||
if (i + a[j] >= n)
|
||||
ans = max(ans, f[i] + b[i]);
|
||||
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
59
GESP/Level6/20231201_2.cpp
Normal file
59
GESP/Level6/20231201_2.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e4 + 10;
|
||||
const int INF = 0x3f3f3f3f;
|
||||
int n, m; // n个关卡,每个关卡都有一样的m个通道
|
||||
int a[N]; // 第i个通道可以让你前进a[i]关,,比如:现在第x关,选择i通道,将到达第x+a[i]关
|
||||
int b[N]; // 当你离开第s关时,将获得b[s]分的奖励
|
||||
int f[N]; // 动态规划数组,f[i]表示离开第i关时可以获得的最大分数
|
||||
int ans = -INF; // 通关时最多能够获得的分数
|
||||
|
||||
/*
|
||||
6 2
|
||||
2 3
|
||||
1 0 30 100 30 30
|
||||
答案:131
|
||||
|
||||
|
||||
6 2
|
||||
2 3
|
||||
1 0 30 100 30 -1
|
||||
答案:101
|
||||
*/
|
||||
int main() {
|
||||
cin >> n >> m; // 输入n和m
|
||||
|
||||
// 每一个关卡都有m个通道,a[i]表示第i个通道可以让你前进a[i]关
|
||||
int mx = 0;
|
||||
for (int i = 1; i <= m; i++) {
|
||||
cin >> a[i];
|
||||
mx = max(mx, a[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < n; i++) // 关卡是从下标0开始的
|
||||
cin >> b[i]; // 通关i关时可以获得的奖励分数
|
||||
// 动态规划
|
||||
// 状态表示:f[i]表示通关第i关时可以获得的最大分数
|
||||
// 状态转移:f[i] = max(f[i],f[i-a[j]]+b[i-a[j]])
|
||||
// 初始化:f[0] = 0
|
||||
// 答案:f[n]
|
||||
|
||||
// 因为得分可能是负数,所以初始化的时候,需要将f[i]初始化为-0x3f
|
||||
memset(f, -0x3f, sizeof f);
|
||||
f[0] = 0;
|
||||
for (int i = 1; i < n + mx; i++) { // 遍历每个阶段
|
||||
// 考虑当前阶段的所有决策,也就是到达这个阶段,可以有哪些决策
|
||||
// 决策:选择第j个通道,那么到达这个阶段,可以获得的最大分数就是f[i-a[j]]+b[i-a[j]]
|
||||
// 所以,f[i] = max(f[i],f[i-a[j]]+b[i-a[j]])
|
||||
for (int j = 1; j <= m; j++) {
|
||||
if (i - a[j] >= 0)
|
||||
f[i] = max(f[i], f[i - a[j]] + b[i - a[j]]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = n - 1; i < n + mx; i++)
|
||||
ans = max(ans, f[i] + b[i]);
|
||||
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
82
GESP/Level6/20231202.cpp
Normal file
82
GESP/Level6/20231202.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 310; // 最多300个点
|
||||
const int M = 310; // 最多299条边,因为它是树,300个点,其实是299条边
|
||||
|
||||
// 链式前向星
|
||||
int e[M], h[N], idx, w[M], ne[M];
|
||||
void add(int a, int b, int c = 0) {
|
||||
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
|
||||
}
|
||||
int n;
|
||||
|
||||
set<int> a[N]; // 节点i可以管理的节点集合
|
||||
|
||||
// 树的深度优先搜索代码
|
||||
void dfs(int u) { // 以u为根的子树的节点数量
|
||||
// 遍历一下当前点的所有出边
|
||||
for (int i = h[u]; i != -1; i = ne[i]) { // i是遍历 u的每条出边
|
||||
int j = e[i]; // j是u的出边指向的节点
|
||||
// 递归处理j
|
||||
dfs(j);
|
||||
// 针j中的所有孩子记录到u中去,注意:这个合并是要在dfs之后,因为dfs是先递归到最深,然后回溯
|
||||
for (auto x : a[j])
|
||||
a[u].insert(x);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("20231202_2.in", "r", stdin);
|
||||
#endif
|
||||
|
||||
// 初始化链式前向星
|
||||
memset(h, -1, sizeof h);
|
||||
|
||||
cin >> n;
|
||||
// 构建单位的管理结构树
|
||||
for (int i = 1; i < n; i++) { // 0号是老板
|
||||
int f;
|
||||
cin >> f;
|
||||
add(f, i); // 表示i号员工的领导是f
|
||||
a[f].insert(i); // f是i的领导
|
||||
}
|
||||
|
||||
// 自己可以管理自己
|
||||
for (int i = 0; i < n; i++)
|
||||
a[i].insert(i);
|
||||
|
||||
// 递归一遍树
|
||||
dfs(0);
|
||||
|
||||
int q;
|
||||
cin >> q;
|
||||
while (q--) {
|
||||
int m;
|
||||
cin >> m;
|
||||
set<int> s; // 需要处理哪些人员集合
|
||||
for (int i = 1; i <= m; i++) {
|
||||
int x;
|
||||
cin >> x;
|
||||
s.insert(x);
|
||||
}
|
||||
|
||||
// // 从n-1到0,找到第一个包含s的集合
|
||||
for (int i = n - 1; i >= 0; i--) {
|
||||
// 检查s中的每个元素是否都在a[i]中
|
||||
bool flag = true;
|
||||
for (auto x : s) {
|
||||
if (a[i].find(x) == a[i].end()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 如果s中的所有元素都在a[i]中,则i是答案
|
||||
if (flag) {
|
||||
cout << i << endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
6
GESP/Level6/20231202_1.in
Normal file
6
GESP/Level6/20231202_1.in
Normal file
@@ -0,0 +1,6 @@
|
||||
5
|
||||
0 0 2 2
|
||||
3
|
||||
2 3 4
|
||||
3 2 3 4
|
||||
2 1 4
|
||||
8
GESP/Level6/20231202_2.in
Normal file
8
GESP/Level6/20231202_2.in
Normal file
@@ -0,0 +1,8 @@
|
||||
7
|
||||
0 1 0 2 1 2
|
||||
5
|
||||
2 4 6
|
||||
2 4 5
|
||||
3 4 5 6
|
||||
4 2 4 5 6
|
||||
2 3 4
|
||||
BIN
GESP/Level6/202403.pdf
Normal file
BIN
GESP/Level6/202403.pdf
Normal file
Binary file not shown.
1
GESP/Level6/20240301.in
Normal file
1
GESP/Level6/20240301.in
Normal file
@@ -0,0 +1 @@
|
||||
114 51 4 1
|
||||
29
GESP/Level6/20240301.md
Normal file
29
GESP/Level6/20240301.md
Normal file
@@ -0,0 +1,29 @@
|
||||
找一组数字进行模拟
|
||||
|
||||
$n=5$
|
||||
$a=3$
|
||||
$b=2$
|
||||
$c=1$
|
||||
|
||||

|
||||
|
||||
由此可以整理动态规划的信息如下:
|
||||
|
||||
- 状态表示: $f[i]$ 表示从 $i$ 到 $0$ 的方案数
|
||||
- 状态转移: $f[i] = f[i-a] + f[i-b]$
|
||||
- 初始状态: $f[n] = 1$
|
||||
|
||||
- 目标状态: 因为最后要求是小于$c$的都是可以到达的状态,所以需要从$0$到$c$的$f[i]$进行累加
|
||||
$$\sum_{i=0}^{c} f[i]$$
|
||||
|
||||
- 边界问题处理:
|
||||
- 如果$i-a$小于$0$,则$f[i-a] = f[0]$
|
||||
- 如果$i-b$小于$0$,则$f[i-b] = f[0]$
|
||||
|
||||
$Q:$ 为什么要处理边界问题,哪来的边界问题呢?
|
||||
$A:$ 通过上面的数字模拟会发现,$2$可以继续减$3$而到达$-1$,这种转换路径是有效,但结果是$-1$,用数组下标来存储显然是不合适的,所以需要处理边界问题。
|
||||
我们可以把这样的情况统统的保存汇集到$0$,这样就保证了数组下标是正的。
|
||||
|
||||
|
||||
|
||||
|
||||
26
GESP/Level6/20240301_dfs.cpp
Normal file
26
GESP/Level6/20240301_dfs.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
const int N = 200010;
|
||||
LL q[N]; // 记忆化
|
||||
LL n, c, b, a;
|
||||
|
||||
const int MOD = 1e9 + 7; // 模 1e9+7
|
||||
|
||||
LL dfs(LL x) {
|
||||
// 走到头了,此时只有一种方案
|
||||
if (x <= c)
|
||||
return 1;
|
||||
// 如果搜索过,直接返回,不再重复计算
|
||||
if (q[x])
|
||||
return q[x];
|
||||
|
||||
// 如果没有进行搜索就需要计算了
|
||||
return q[x] = (dfs(x - a) % MOD + dfs(x - b) % MOD) % MOD;
|
||||
}
|
||||
|
||||
int main() {
|
||||
cin >> n >> a >> b >> c;
|
||||
cout << dfs(n);
|
||||
return 0;
|
||||
}
|
||||
47
GESP/Level6/20240301_dp1.cpp
Normal file
47
GESP/Level6/20240301_dp1.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 2e5 + 10;
|
||||
const int MOD = 1e9 + 7;
|
||||
int n, a, b, c;
|
||||
int f[N];
|
||||
int ans;
|
||||
int main() {
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("20240301.in", "r", stdin);
|
||||
#endif
|
||||
/**
|
||||
例1:
|
||||
1 1 1 1
|
||||
答案:1
|
||||
|
||||
例2:
|
||||
114 51 4 1
|
||||
答案:176
|
||||
|
||||
例3:
|
||||
114514 191 9 810
|
||||
答案:384178446
|
||||
*/
|
||||
// 从大向小推
|
||||
cin >> n >> a >> b >> c;
|
||||
|
||||
f[n] = 1;
|
||||
|
||||
for (int i = n; i > c; i--) {
|
||||
if (i - a >= 0)
|
||||
f[i - a] = (f[i - a] + f[i]) % MOD;
|
||||
else
|
||||
f[0] = (f[i] + f[0]) % MOD;
|
||||
|
||||
if (i - b >= 0)
|
||||
f[i - b] = (f[i - b] + f[i]) % MOD;
|
||||
else
|
||||
f[0] = (f[0] + f[i]) % MOD;
|
||||
}
|
||||
for (int i = 0; i <= c; i++)
|
||||
ans = (ans + f[i]) % MOD;
|
||||
|
||||
printf("%d\n", ans);
|
||||
|
||||
return 0;
|
||||
}
|
||||
40
GESP/Level6/20240301_dp2.cpp
Normal file
40
GESP/Level6/20240301_dp2.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 2e5 + 10;
|
||||
const int MOD = 1e9 + 7;
|
||||
int n, a, b, c;
|
||||
int f[N];
|
||||
int ans;
|
||||
int main() {
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("20240301.in", "r", stdin);
|
||||
#endif
|
||||
/**
|
||||
例1:
|
||||
1 1 1 1
|
||||
答案:1
|
||||
|
||||
例2:
|
||||
114 51 4 1
|
||||
答案:176
|
||||
|
||||
例3:
|
||||
114514 191 9 810
|
||||
答案:384178446
|
||||
*/
|
||||
// 从大向小推
|
||||
cin >> n >> a >> b >> c;
|
||||
|
||||
f[n] = 1;
|
||||
|
||||
for (int i = n; i > c; i--) {
|
||||
f[max(i - a, 0)] = (f[max(i - a, 0)] + f[i]) % MOD;
|
||||
f[max(i - b, 0)] = (f[max(i - b, 0)] + f[i]) % MOD;
|
||||
}
|
||||
|
||||
for (int i = 0; i <= c; i++)
|
||||
ans = (ans + f[i]) % MOD;
|
||||
|
||||
printf("%d\n", ans);
|
||||
return 0;
|
||||
}
|
||||
33
GESP/Level6/20240302.cpp
Normal file
33
GESP/Level6/20240302.cpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef pair<int, int> PII;
|
||||
const int N = 10;
|
||||
|
||||
PII a[N];
|
||||
int ans = INT_MAX;
|
||||
|
||||
int main() {
|
||||
int n;
|
||||
cin >> n;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
cin >> a[i].first;
|
||||
for (int i = 0; i < n; i++)
|
||||
cin >> a[i].second;
|
||||
|
||||
do {
|
||||
// Q: 为什么res初始化为n?
|
||||
// A: 因为每个奶牛需要一个牛棚,所以初始化为n
|
||||
// Q:怎么想到的用全排列?
|
||||
// A: 因为题目要求的是所有奶牛的组合,所以需要枚举所有组合,而且题目的数据范围极小,N最大才是9,所以用全排列是可行的。
|
||||
int res = n, k = a[0].second; // 排序第一的牛,它的右手安全距离a[0].second
|
||||
for (int i = 1; i < n; i++) {
|
||||
res += max(k, a[i].first); // 当前牛的左手安全距离,加上1才是真正的安全距离
|
||||
k = a[i].second;
|
||||
}
|
||||
ans = min(ans, res); // 每次组合取最小值
|
||||
} while (next_permutation(a, a + n)); // 枚举所有组合
|
||||
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
BIN
GESP/Level6/202406.pdf
Normal file
BIN
GESP/Level6/202406.pdf
Normal file
Binary file not shown.
37
GESP/Level6/20240601.cpp
Normal file
37
GESP/Level6/20240601.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e5 + 10;
|
||||
int a[30];
|
||||
string s;
|
||||
int f[N]; // f[i]表示前i个字符的最大分值
|
||||
|
||||
int main() {
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("20240601.in", "r", stdin);
|
||||
#endif
|
||||
int n;
|
||||
cin >> n;
|
||||
// 连续多个abc的分值
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> a[i];
|
||||
|
||||
int m; // 字符串的长度
|
||||
cin >> m >> s; // 字符串
|
||||
|
||||
for (int i = 1; i <= m; i++) { // 枚举每个字符
|
||||
f[i] = f[i - 1]; // 从前面继承分值
|
||||
for (int j = 1; j <= n; j++) { // 枚举每个分值,看看有没有机会得到这个分值,就是1个,2个,3个abc...
|
||||
int start = i - 3 * j;
|
||||
if (start < 0)
|
||||
break;
|
||||
|
||||
if (s.substr(start, 3) == "abc") // 最后一组是abc,那么有机会获得更高分值
|
||||
f[i] = max(f[i], f[start + 1] + a[j]);
|
||||
else
|
||||
break; // 不是abc,没有继续检查的必要
|
||||
}
|
||||
}
|
||||
|
||||
cout << f[m] << endl;
|
||||
return 0;
|
||||
}
|
||||
4
GESP/Level6/20240601.in
Normal file
4
GESP/Level6/20240601.in
Normal file
@@ -0,0 +1,4 @@
|
||||
3
|
||||
3 1 2
|
||||
13
|
||||
dabcabcabcabz
|
||||
7
GESP/Level6/20240602.in
Normal file
7
GESP/Level6/20240602.in
Normal file
@@ -0,0 +1,7 @@
|
||||
6
|
||||
3 1 1 3 4
|
||||
100101
|
||||
3
|
||||
1
|
||||
3
|
||||
2
|
||||
54
GESP/Level6/20240602_1.cpp
Normal file
54
GESP/Level6/20240602_1.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e5 + 10;
|
||||
int n;
|
||||
|
||||
struct Node {
|
||||
int color;
|
||||
int ls = -1, rs = -1; // 左儿子与右儿子
|
||||
} tr[N];
|
||||
|
||||
void dfs(int u) {
|
||||
if (u == -1)
|
||||
return;
|
||||
if (tr[u].color == 0)
|
||||
tr[u].color = 1;
|
||||
else
|
||||
tr[u].color = 0;
|
||||
|
||||
dfs(tr[u].ls), dfs(tr[u].rs);
|
||||
}
|
||||
|
||||
int main() {
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("20240602.in", "r", stdin);
|
||||
#endif
|
||||
// 读入
|
||||
int n;
|
||||
cin >> n;
|
||||
for (int i = 1; i < n; i++) {
|
||||
int x;
|
||||
cin >> x;
|
||||
if (tr[x].ls == -1) // 赋值右儿子
|
||||
tr[x].ls = i + 1;
|
||||
else // 左儿子
|
||||
tr[x].rs = i + 1;
|
||||
}
|
||||
string s; // 注意:输入的是01串,不是0 1
|
||||
cin >> s;
|
||||
for (int i = 1; i <= n; i++)
|
||||
tr[i].color = s[i - 1] - '0';
|
||||
|
||||
int q;
|
||||
cin >> q;
|
||||
|
||||
while (q--) {
|
||||
int x;
|
||||
cin >> x;
|
||||
dfs(x);
|
||||
}
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
printf("%d", tr[i].color);
|
||||
return 0;
|
||||
}
|
||||
56
GESP/Level6/20240602_2.cpp
Normal file
56
GESP/Level6/20240602_2.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e5 + 10;
|
||||
int n;
|
||||
|
||||
struct Node {
|
||||
int sum = 0; // 被操作次数
|
||||
int color;
|
||||
int ls = -1, rs = -1; // 左儿子与右儿子
|
||||
} tr[N];
|
||||
|
||||
void dfs(int u, int now) {
|
||||
now += tr[u].sum;
|
||||
if (u == -1)
|
||||
return;
|
||||
|
||||
if (now & 1)
|
||||
tr[u].color ^= 1;
|
||||
|
||||
dfs(tr[u].ls, now), dfs(tr[u].rs, now);
|
||||
}
|
||||
|
||||
int main() {
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("20240602.in", "r", stdin);
|
||||
#endif
|
||||
// 读入
|
||||
int n;
|
||||
cin >> n;
|
||||
for (int i = 1; i < n; i++) {
|
||||
int x;
|
||||
cin >> x;
|
||||
if (tr[x].ls == -1) // 赋值右儿子
|
||||
tr[x].ls = i + 1;
|
||||
else // 左儿子
|
||||
tr[x].rs = i + 1;
|
||||
}
|
||||
string s; // 注意:输入的是01串,不是0 1
|
||||
cin >> s;
|
||||
for (int i = 1; i <= n; i++)
|
||||
tr[i].color = s[i - 1] - '0';
|
||||
|
||||
int q;
|
||||
cin >> q;
|
||||
|
||||
while (q--) {
|
||||
int x;
|
||||
cin >> x;
|
||||
tr[x].sum++;
|
||||
}
|
||||
dfs(1, 0);
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
printf("%d", tr[i].color);
|
||||
return 0;
|
||||
}
|
||||
57
GESP/Level6/20240602_3.cpp
Normal file
57
GESP/Level6/20240602_3.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e5 + 10;
|
||||
int n;
|
||||
int son[N][2]; // 记录每个节点的两个儿子
|
||||
int fa[N]; // 记录每个节点的父节点是哪个
|
||||
int col[N]; // 记录每个节点的颜色
|
||||
int sum[N]; // 记录每个节点被操作的次数
|
||||
|
||||
void dfs(int x, int now) {
|
||||
now += sum[x]; // 递归计算x节点被操作的次数
|
||||
if (now & 1)
|
||||
col[x] ^= 1; // 如果操作次数是奇数,则颜色取反
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (son[x][i] != -1)
|
||||
dfs(son[x][i], now);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
#ifndef ONLINE_JUDGE
|
||||
freopen("20240602.in", "r", stdin);
|
||||
#endif
|
||||
|
||||
cin >> n; // n个节点
|
||||
memset(son, -1, sizeof son); // 初始化son数组,-1表示没有儿子
|
||||
// 这个i从2开始,是因为题目中要求的意义
|
||||
for (int i = 2; i <= n; i++) {
|
||||
cin >> fa[i];
|
||||
for (int j = 0; j < 2; j++) { // 循环两次,因为每个节点有两个儿子
|
||||
if (son[fa[i]][j] == -1) {
|
||||
son[fa[i]][j] = i; // 记录父子关系
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
string s;
|
||||
cin >> s;
|
||||
// 初始颜色
|
||||
for (int i = 1; i <= n; i++)
|
||||
col[i] = s[i - 1] - '0';
|
||||
|
||||
int q;
|
||||
cin >> q;
|
||||
while (q--) {
|
||||
int x;
|
||||
cin >> x;
|
||||
sum[x] += 1; // x这个节点被操作了一次
|
||||
}
|
||||
// 从根节点开始dfs
|
||||
dfs(1, 0);
|
||||
// 输出每个节点的颜色
|
||||
for (int i = 1; i <= n; i++)
|
||||
cout << col[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
BIN
GESP/Level6/202409.pdf
Normal file
BIN
GESP/Level6/202409.pdf
Normal file
Binary file not shown.
17
GESP/Level6/20240901.cpp
Normal file
17
GESP/Level6/20240901.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e5 + 10;
|
||||
int n;
|
||||
int f[N]; // 状态表示:f[i]表示i个数最少需要多少个平方数
|
||||
|
||||
int main() {
|
||||
cin >> n;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
f[i] = i; // 初始化,i个数最少需要i个平方数,因为最坏的情况就是每个数都是1
|
||||
|
||||
for (int j = 1; j <= sqrt(i); j++) // 枚举完全平方数
|
||||
f[i] = min(f[i - j * j] + 1, f[i]); // 状态转移方程
|
||||
}
|
||||
cout << f[n] << endl;
|
||||
return 0;
|
||||
}
|
||||
40
GESP/Level6/20240902.cpp
Normal file
40
GESP/Level6/20240902.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e5 + 10;
|
||||
int m; // 算法种类数
|
||||
int n; // 题目数
|
||||
int k; // 目标掌握程度
|
||||
int b[N]; // 代表每道题目已经取得的经验值
|
||||
pair<int, int> a[N]; // 代表每道题目的frist:经验值,second:知识点
|
||||
int c[N]; // 存储每个知识点选了多少道题
|
||||
int cnt, ans, mx;
|
||||
|
||||
int main() {
|
||||
cin >> m >> n >> k; // 输入算法种类数,题目数,目标掌握程度
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> a[i].second; // 输入每道题目的知识点
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> a[i].first; // 输入学习每道题目可以获取到的经验值
|
||||
|
||||
sort(a + 1, a + n + 1); // 按可以获取到的经验值最小到大排序
|
||||
|
||||
for (int i = n; i >= 1; i--) { // 倒序枚举,就是经验值最大到小
|
||||
if (b[a[i].second] < k) { // 第a[i].second,也就是该知识点的已获得的经验值不够k
|
||||
b[a[i].second] += a[i].first; // 这道题需要做一下,经验值增加
|
||||
if (b[a[i].second] >= k)
|
||||
cnt++; // 有多少个知识点达到了k
|
||||
ans++; // 增加题数(记录使了多少个题目)
|
||||
c[a[i].second]++; // 统计每个知识点的选择题数
|
||||
mx = max(mx, c[a[i].second]); // 统计选择最多题的知识点选择了的题数
|
||||
}
|
||||
}
|
||||
|
||||
// ① 如果最终可以达标的算法数量不够m个,表示无解
|
||||
// ② 如果选择最多的题数大于题目总数的一半,表示无解
|
||||
if (cnt < m || n < mx * 2 - 1)
|
||||
cout << -1 << endl; // 输出-1
|
||||
else
|
||||
cout << max(mx * 2 - 1, ans) << endl; // 输出最大值
|
||||
return 0;
|
||||
}
|
||||
82
GESP/Level6/20240902.md
Normal file
82
GESP/Level6/20240902.md
Normal file
@@ -0,0 +1,82 @@
|
||||
## 一、算法选择
|
||||
**显然**,**对于每个知识点做能得到 <font color="red">更多经验值的题目更优</font>**。
|
||||
|
||||
所以,基本上认为是:<font color="red" size="5" bold>【贪心】</font>
|
||||
|
||||
|
||||
## 二、基本思路
|
||||
既然定位是贪心,那么 **一般的套路就排序**,然后从大到小选择。
|
||||
|
||||
用一个 $PII$ 来存储每道题的 **① 经验值**,**② 知识点**,按经验值进行排序,这样系统默认第一个元素为第一关键字,第二个元素为第二关键字,默认是从小到大排序,一会遍历的时候需要倒序进行。
|
||||
|
||||
从 $n$ 枚举到$1$,如果第 $i$ 道题的知识点还没有达到 $k$,就要做这道题:
|
||||
|
||||
- ① 数组 $b$ 保存每个知识点的 **已经取得的经验值**
|
||||
- ② 数组 $c$ 保存每个知识点的 **选择题数**
|
||||
- ③ 变量 $ans$ 保存答案,也就是一共选择了多少道题
|
||||
- ④ 变量$cnt$ 保存 **达标了的知识点数量**
|
||||
- ⑤ 变量$mx$ 保存选择题数最高的知识点选择的题数 【下面会讲解为什么要保留这个变量】
|
||||
|
||||
> **思考**:
|
||||
> **问**:为什么会想到记录上面这些变量呢?
|
||||
> **答**:因为我们不管题目最终想要计算什么,事情发生过程中,客观记录事实最重要,有啥都记录下来总没错。
|
||||
|
||||
## 三、结果判定
|
||||
|
||||
本题最难想的就是结果的判定,因为它有一个要求:**连续做两道同样知识点的题是不好的**。
|
||||
我们可以举例子思考可能的所有情况有哪些:
|
||||
|
||||
① 一共一个知识点,第一个知识点需要$50$点经验,结果相关联的题目经验值加在一起最多也不到$50$点,此时,输出$-1$。
|
||||
|
||||
② 一共两个知识点,第一个知识点需要经验值最高的前$4$道题,第二个知识点需要经验值最高的前$3$道题 ,此时,会发生什么呢?我们会发现,这时候直接输出$4+3=7$就行了。
|
||||
|
||||
③ 一共两个知识点,第一个知识点需要经验值最高的前$5$道题,第二个知识点需要经验值最高的前$3$道题 ,此时,会发生什么呢?我们会发现,这时候直接输出$8$是不行的,因为$5$道题,中间最少是$4$个空,现在只有$3$个可以用来间隔的,缺少一个。为什么与 ② 时情况不同呢?就是因为最多的太多了,需要照顾最多的,给它插好空,也就是$mx*2-1$。
|
||||
|
||||
④ 继续上面 ③的思考过程 ,那如果总的题目数量也不够$mx*2-1$,此时,输出$-1$。
|
||||
|
||||
|
||||
## 四、代码实现
|
||||
```cpp {.line-numbers}
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 1e5 + 10;
|
||||
int m; // 算法种类数
|
||||
int n; // 题目数
|
||||
int k; // 目标掌握程度
|
||||
int b[N]; // 代表每道题目已经取得的经验值
|
||||
pair<int, int> a[N]; // 代表每道题目的frist:经验值,second:知识点
|
||||
int c[N]; // 存储每个知识点选了多少道题
|
||||
int cnt, ans, mx;
|
||||
|
||||
int main() {
|
||||
cin >> m >> n >> k; // 输入算法种类数,题目数,目标掌握程度
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> a[i].second; // 输入每道题目的知识点
|
||||
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> a[i].first; // 输入学习每道题目可以获取到的经验值
|
||||
|
||||
sort(a + 1, a + n + 1); // 按可以获取到的经验值最小到大排序
|
||||
|
||||
for (int i = n; i >= 1; i--) { // 倒序枚举,就是经验值最大到小
|
||||
if (b[a[i].second] < k) { // 第a[i].second,也就是该知识点的已获得的经验值不够k
|
||||
b[a[i].second] += a[i].first; // 这道题需要做一下,经验值增加
|
||||
if (b[a[i].second] >= k)
|
||||
cnt++; // 有多少个知识点达到了k
|
||||
ans++; // 增加题数(记录使了多少个题目)
|
||||
c[a[i].second]++; // 统计每个知识点的选择题数
|
||||
mx = max(mx, c[a[i].second]); // 统计选择最多题的知识点选择了的题数
|
||||
}
|
||||
}
|
||||
|
||||
// ① 如果最终可以达标的算法数量不够m个,表示无解
|
||||
// ② 如果选择最多的题数大于题目总数的一半,表示无解
|
||||
if (cnt < m || n < mx * 2 - 1)
|
||||
cout << -1 << endl; // 输出-1
|
||||
else
|
||||
cout << max(mx * 2 - 1, ans) << endl; // 输出最大值
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
BIN
GESP/Level6/202412.pdf
Normal file
BIN
GESP/Level6/202412.pdf
Normal file
Binary file not shown.
36
GESP/Level6/20241201.cpp
Normal file
36
GESP/Level6/20241201.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
int n;
|
||||
LL s;
|
||||
string str;
|
||||
bool out;
|
||||
|
||||
int main() {
|
||||
cin >> n >> s >> str;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (str[i] == 'U') { // 第一种操作
|
||||
if (s == 1) // 根,不动
|
||||
continue;
|
||||
if (out) { // 超过1e12,向上一层
|
||||
out = false;
|
||||
continue;
|
||||
}
|
||||
s /= 2; // 变成父节点
|
||||
} else if (str[i] == 'L') { // 第二种操作
|
||||
if (s * 2 > 1e12) { // 左子结点编号超过1e12,向下一层
|
||||
out = true;
|
||||
continue;
|
||||
}
|
||||
s *= 2; // 变成左子结点
|
||||
} else if (str[i] == 'R') { // 第三种操作
|
||||
if (s * 2 + 1 > 1e12) { // 右子节点编号如果超过1E12,向下一层
|
||||
out = true;
|
||||
continue;
|
||||
}
|
||||
s = s * 2 + 1; // 变成右子节点
|
||||
}
|
||||
}
|
||||
cout << s << endl;
|
||||
return 0;
|
||||
}
|
||||
2
GESP/Level6/20241201.in
Normal file
2
GESP/Level6/20241201.in
Normal file
@@ -0,0 +1,2 @@
|
||||
3 2
|
||||
URR
|
||||
54
GESP/Level6/20241202.cpp
Normal file
54
GESP/Level6/20241202.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
const int N = 1e5 + 10;
|
||||
int n; // 运输站点数量
|
||||
int m; // 货车数量
|
||||
int x; // 两市距离
|
||||
struct Node { // 运输点
|
||||
int p; // 运输站点的位置
|
||||
int c; // 最多容纳车辆数
|
||||
} q[N];
|
||||
|
||||
bool cmp(Node x, Node y) { // 按到A市的距离从小到大排序
|
||||
return x.p < y.p;
|
||||
}
|
||||
|
||||
vector<int> na, nb; // 需要去靠近A市的车和靠近B市的车
|
||||
LL ans; // 里程合计
|
||||
|
||||
int main() {
|
||||
cin >> n >> m >> x;
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> q[i].p >> q[i].c;
|
||||
|
||||
sort(q + 1, q + n + 1, cmp); // 按距离A市的距离将运输点排序
|
||||
|
||||
for (int i = 1; i <= m; i++) { // 枚举每个货车
|
||||
int a, b;
|
||||
cin >> a >> b;
|
||||
if (a >= b) // 到A市次数不低于到B市次数
|
||||
na.push_back(a - b); // 只记录A市超过B市的次数
|
||||
else // 到A市次数低于到B市次数
|
||||
nb.push_back(b - a); // 只记录B市超过A市的次数
|
||||
|
||||
ans += 2ll * min(a, b) * x; // 相等的部分计算距离
|
||||
}
|
||||
sort(na.begin(), na.end(), greater<int>()); // 按去A市的次数从大到小排序
|
||||
sort(nb.begin(), nb.end(), greater<int>()); // 按去B市的次数从大到小排序
|
||||
int l = 1, r = n; // 最靠近A市的运输点为1,最靠近B市的运输点为n
|
||||
for (int i = 0; i < na.size(); i++) { // 枚举去A市的车
|
||||
while (q[l].c == 0)
|
||||
l++; // 没有容量就去下一个运输点
|
||||
q[l].c--; // 运输点容量减一
|
||||
ans += 2ll * q[l].p * na[i]; // 计算路程
|
||||
}
|
||||
for (int i = 0; i < nb.size(); i++) { // 枚举去B市的车
|
||||
while (q[r].c == 0)
|
||||
r--; // 没有容量就去下一个运输点
|
||||
q[r].c--; // 运输点容量减一
|
||||
ans += 2ll * (x - q[r].p) * nb[i]; // 计算路程
|
||||
}
|
||||
cout << ans << endl;
|
||||
return 0;
|
||||
}
|
||||
1
GESP/Level6/20241202.md
Normal file
1
GESP/Level6/20241202.md
Normal file
@@ -0,0 +1 @@
|
||||
贪心算法,对于去A市多于去B市的车,尽量安排在靠近A市的运输站,次数差的越多越靠近A市,对于去B市多于去A市的车,尽量安排靠近B市,对于去两市次数相等的车,安排在哪里都一样
|
||||
BIN
GESP/Level6/202503.pdf
Normal file
BIN
GESP/Level6/202503.pdf
Normal file
Binary file not shown.
52
GESP/Level6/202503T1.cpp
Normal file
52
GESP/Level6/202503T1.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 2e5 + 10;
|
||||
const int M = 4e5 + 10;
|
||||
/*
|
||||
3
|
||||
1 3
|
||||
2 3
|
||||
|
||||
答案 :
|
||||
2 2 1
|
||||
*/
|
||||
// 链式前向星
|
||||
int e[M], h[N], idx, ne[M];
|
||||
void add(int a, int b) {
|
||||
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
|
||||
}
|
||||
int cnt[2]; // 两种颜色都有多少个
|
||||
int color[N]; // 当前节点颜色,也可以理解为是奇偶性
|
||||
/*
|
||||
u 当前节点
|
||||
c 当前节点颜色 【二分图染色,也可以理解为是奇偶性】
|
||||
fa 当前节点的父节点
|
||||
*/
|
||||
void dfs(int u, int c, int fa) {
|
||||
color[u] = c; // u节点标识为c这个颜色
|
||||
cnt[c]++; // 颜色计数
|
||||
for (int i = h[u]; ~i; i = ne[i])
|
||||
if (e[i] != fa) // 不走回头路
|
||||
dfs(e[i], c ^ 1, u); // 走向下一个节点,下一个节点的颜色需要变换,同时标识父节点是u
|
||||
}
|
||||
|
||||
int main() {
|
||||
// 初始化链式前向星
|
||||
memset(h, -1, sizeof h);
|
||||
int n;
|
||||
cin >> n;
|
||||
for (int i = 1; i < n; i++) {
|
||||
int a, b;
|
||||
cin >> a >> b;
|
||||
add(a, b);
|
||||
add(b, a);
|
||||
}
|
||||
|
||||
// 深搜一次,从1号节点搜索,标识为0这个颜色,1的父节点不存在,传入0
|
||||
dfs(1, 0, 0);
|
||||
|
||||
// 输出结果
|
||||
for (int i = 1; i <= n; i++) // 每个节点都讨论一次,其实就是按颜色分两组,每组的个数输出即可
|
||||
printf("%d ", cnt[color[i]]);
|
||||
return 0;
|
||||
}
|
||||
44
GESP/Level6/202503T2.cpp
Normal file
44
GESP/Level6/202503T2.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
const int N = 4e5 + 10;
|
||||
|
||||
int n;
|
||||
LL a[N], s[N]; // 原数组,前缀和数组
|
||||
int q[N], L, R; // 滑动窗口,左端点,右端点
|
||||
LL ans; // 答案
|
||||
int main() {
|
||||
cin >> n;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
cin >> a[i];
|
||||
a[n + i] = a[i]; // 破环成链
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 2 * n; i++) // 一维前缀和
|
||||
s[i] = s[i - 1] + a[i];
|
||||
|
||||
// 滑动窗口
|
||||
L = R = 1; // 初始化滑动窗口长度为0
|
||||
ans = -1e18; // 初始化答案为-1e18
|
||||
|
||||
for (int i = 1; i <= 2 * n; i++) {
|
||||
// 维护滑动窗口,确保窗口长度不超过n
|
||||
while (L <= R && q[L] < i - n)
|
||||
L++;
|
||||
|
||||
// 计算当前位置i与窗口内最小前缀和的差,即为以i结尾的最大子段和
|
||||
LL currentSum = s[i] - s[q[L]];
|
||||
ans = max(ans, currentSum);
|
||||
|
||||
// 维护单调队列,保证队列中的前缀和是单调递增的
|
||||
// 如果新的前缀和更小,则队尾的更大值都不可能是最优解,可以删除
|
||||
while (L <= R && s[i] < s[q[R]])
|
||||
R--;
|
||||
|
||||
// 将当前位置加入队列
|
||||
q[++R] = i;
|
||||
}
|
||||
|
||||
printf("%lld\n", ans); // 输出答案
|
||||
return 0;
|
||||
}
|
||||
30
GESP/Level6/202503T2_Prepare.cpp
Normal file
30
GESP/Level6/202503T2_Prepare.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
const int N = 4e5 + 10;
|
||||
|
||||
int n;
|
||||
LL a[N], s[N];
|
||||
LL ans = -1e18;
|
||||
|
||||
int main() {
|
||||
cin >> n;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
cin >> a[i];
|
||||
a[n + i] = a[i];
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 2 * n; i++)
|
||||
s[i] = s[i - 1] + a[i];
|
||||
|
||||
// 对于每个位置i,枚举它前面n个位置,找最小前缀和
|
||||
for (int i = 1; i <= 2 * n; i++) {
|
||||
LL minPrefix = s[i - 1]; // 初始化为i-1位置的前缀和
|
||||
for (int j = max(0, i - n); j <= i - 2; j++)
|
||||
minPrefix = min(minPrefix, s[j]);
|
||||
ans = max(ans, s[i] - minPrefix);
|
||||
}
|
||||
|
||||
printf("%lld\n", ans);
|
||||
return 0;
|
||||
}
|
||||
34
GESP/Level6/666.cpp
Normal file
34
GESP/Level6/666.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
<<<<<<< HEAD
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 2010;
|
||||
int v[N], w[N];
|
||||
int n, L;
|
||||
int ans = INT_MAX;
|
||||
int f[N][N];
|
||||
|
||||
int main() {
|
||||
cin >> n >> L;
|
||||
for (int i = 1; i <= n; i++)
|
||||
cin >> v[i] >> w[i];
|
||||
for (int i = 1; i <= n; i++)
|
||||
for (int j = 0; j <= L; j++) {
|
||||
f[i][j] = f[i - 1][j];
|
||||
if (j >= v[i])
|
||||
f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
|
||||
}
|
||||
|
||||
for (int j = 0; j <= L; j++) {
|
||||
if (f[n][j] >= L) {
|
||||
ans = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ans < INT_MAX)
|
||||
cout << ans << endl;
|
||||
else
|
||||
cout << "no solution" << endl;
|
||||
return 0;
|
||||
}
|
||||
=======
|
||||
>>>>>>> 13071b821300647688be50739c7b6b190b603339
|
||||
45
GESP/Level6/P9573.cpp
Normal file
45
GESP/Level6/P9573.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 200010;
|
||||
int n, p;
|
||||
queue<int> q[N]; // 模p的余数组成的队列数组
|
||||
set<int> s; // 集合?
|
||||
|
||||
int main() {
|
||||
int T;
|
||||
cin >> T;
|
||||
while (T--) {
|
||||
cin >> n >> p;
|
||||
// 如果p太大,就不用算了,因为即使 n+ n-1 也无法构建出一个p,这个可以根据测试用例去想一个特判
|
||||
if (p > 2 * n - 1) {
|
||||
for (int i = 1; i <= n; i++)
|
||||
cout << i << " ";
|
||||
cout << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 2; i <= n; i++) // 按 模p分组
|
||||
q[i % p].push(i);
|
||||
|
||||
for (int i = 0; i < p; i++)
|
||||
if (!q[i].empty())
|
||||
s.insert(i); // 队列非空才加入, s里装的是 模p的余数
|
||||
|
||||
int x = 1;
|
||||
cout << x << " "; // 先输出一个 1
|
||||
for (int i = 2; i <= n; i++) { // 还有n-1个数字需要输出
|
||||
int f = (p - x % p) % p; // 防止x%p=0的特殊情况
|
||||
if (q[f].empty())
|
||||
s.erase(f), f = *s.begin(); // 没了就删除,f换成任意一个非空队列
|
||||
x = q[f].front();
|
||||
q[f].pop();
|
||||
cout << x << " ";
|
||||
|
||||
if (q[f].empty())
|
||||
s.erase(f);
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
50
GESP/Level6/P9573_2.cpp
Normal file
50
GESP/Level6/P9573_2.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <bits/stdc++.h>
|
||||
using namespace std;
|
||||
const int N = 200010;
|
||||
int n, p;
|
||||
queue<int> q[N]; // 模p的余数组成的队列数组
|
||||
set<int> s; // 集合?
|
||||
|
||||
int main() {
|
||||
int T;
|
||||
cin >> T;
|
||||
while (T--) {
|
||||
cin >> n >> p;
|
||||
// 如果p太大,就不用算了,因为即使 n+ n-1 也无法构建出一个p,这个可以根据测试用例去想一个特判
|
||||
if (p >= 2 * n) {
|
||||
for (int i = 1; i <= n; i++)
|
||||
cout << i << " ";
|
||||
cout << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= n; i++) // 按 模p分组
|
||||
q[i % p].push(i);
|
||||
|
||||
for (int i = 0; i < p; i++)
|
||||
if (q[i].size())
|
||||
s.insert(i); // 队列非空才加入, s里装的是 模p的余数
|
||||
|
||||
int x = 0;
|
||||
while (q[x].empty())
|
||||
x++;
|
||||
|
||||
int y = q[x].front();
|
||||
q[x].pop();
|
||||
cout << y << " ";
|
||||
|
||||
for (int i = 1; i <= n; i++) { // 还有n-1个数字需要输出
|
||||
int f = (p - x % p) % p; // 防止x%p=0的特殊情况
|
||||
if (q[f].empty())
|
||||
s.erase(f), f = *s.begin(); // 没了就删除,f换成任意一个非空队列
|
||||
x = q[f].front();
|
||||
q[f].pop();
|
||||
cout << x << " ";
|
||||
if (q[f].empty())
|
||||
s.erase(f);
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user