洛谷 P11247 [GESP202409 六级] 算法学习-普及/提高-
题目描述
小杨计划学习 mmm 种算法,为此他找了 nnn 道题目来帮助自己学习,每道题目最多学习一次。
小杨对于 mmm 种算法的初始掌握程度均为 000。第 iii 道题目有对应的知识点 aia_iai,即学习第 iii 道题目可以令小杨对第 aia_iai 种算法的掌握程度提高 bib_ibi。小杨的学习目标是对于 mmm 种算法的掌握程度均至少为 kkk。
小杨认为连续学习两道相同知识点的题目是不好的,小杨想请你编写程序帮他计算出他最少需要学习多少道题目才能使得他在完成学习目标的同时避免连续学习两道相同知识点的题目。
输入格式
第一行三个正整数 m,n,km, n, km,n,k,代表算法种类数,题目数和目标掌握程度。
第二行 nnn 个正整数 a1,a2,...,ana_1, a_2, ..., a_na1,a2,...,an,代表每道题目的知识点。
第二行 nnn 个正整数 b1,b2,...,bnb_1, b_2, ..., b_nb1,b2,...,bn,代表每道题目提升的掌握程度。
输出格式
输出一个整数,代表小杨最少需要学习题目的数量,如果不存在满足条件的方案,输出 -1。
输入输出样例 #1
输入 #1
3 5 10
1 1 2 3 3
9 1 10 10 1
输出 #1
4
输入输出样例 #2
输入 #2
2 4 10
1 1 1 2
1 2 7 10
输出 #2
-1
说明/提示
样例 1 解释
一种最优学习顺序为第一道题,第三道题,第四道题,第二道题。
数据规模与约定
子任务编号 | 数据点占比 | mmm | nnn | bib_ibi | kkk |
---|---|---|---|---|---|
111 | 30%30\%30% | 222 | ≤9\leq 9≤9 | ≤10\leq 10≤10 | ≤10\leq 10≤10 |
222 | 30%30\%30% | ≤9\leq 9≤9 | ≤9\leq 9≤9 | ≤10\leq 10≤10 | ≤10\leq 10≤10 |
333 | 40%40\%40% | ≤105\leq 10^5≤105 | ≤105\leq 10^5≤105 | ≤105\leq 10^5≤105 | ≤105\leq 10^5≤105 |
对于全部数据,保证有 1≤m,n,bi,k≤1051 \leq m, n, b_i, k \leq 10^51≤m,n,bi,k≤105,1≤ai≤m1 \leq a_i \leq m1≤ai≤m。
solution
贪心算法,先单独统计每种知识点最低需要学几道题,然后判断是否满足最多的那个超过半数至少为 2
代码
#include <iostream>
#include "bit"
#include "vector"
#include "unordered_set"
#include "set"
#include "queue"
#include "algorithm"
#include "bitset"using namespace std;const int N = 1e5 + 1;
int n, m, k, a[N], b[N];
vector<int> c[N];int main() {cin >> n >> m >> k;for (int i = 0; i < m; i++) cin >> a[i];for (int i = 0; i < m; i++) cin >> b[i];for (int i = 0; i < m; i++) c[a[i]].push_back(b[i]);int M = 0, sum = 0;for (int i = 1; i <= n; i++) {std::sort(c[i].begin(), c[i].end(), greater<>());int s = 0, j = 0;while (true){s += c[i][j++];if(s >= k) break;if(j == c[i].size()){cout << -1;return 0;}}// cout << j << endl;sum += j;M = max(M, j);}if(M > (m + 1) / 2) cout << -1;else cout << sum;
}