小明非常喜欢上课,现在小明的课表有一些课,他可以通过课表选择上哪些课。
上课会有奖励,每门课上课时间长短不同奖励也会不一样,存在上课时间更长,奖励更少的情况。每一门课上课的总时长为整数。不同时长的奖励,题目数据中会给出。
对于每一门课,小明只可以上一次,现在小明一共有m分钟的时间可以安排上课,但是小明想要得到最大的奖励,聪明的你可以帮助小明解决这个问题吗?
输入第一行,输入两个数n和m,表示课程的数目以及小明需要上课的时间 接下来包括n行,每行m个数,第i个数表示对于每门课上i分钟的奖励 (i从1开始,每门课程只可以上一次) 对于10%的数据,1<= n<= 4,1<=m<=4 对于50%的数据,1<= n<= 100,1<=m<=100 对于100%的数据,1<= n<=100,1<=m<=100 1<=奖励值<=1000输出
输出一个数,表示最大的奖励值。输入样例
2 3 3 2 1 3 2 1输出样例
6代码
#include2. 切木头 [二分]using namespace std; int n, m, dp[105][105], credit[105][105]; int main() { cin >> n >> m; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) cin >> credit[i][j]; for (int i = 1; i <= n; ++i) { // 课程 i for (int s = 1; s <= m; ++s) { dp[i][s] = dp[i - 1][s]; // 不上课程 i for (int j = 1; j <= s; ++j) { dp[i][s] = max(dp[i][s], credit[i][j] + dp[i - 1][s - j]); } } } cout << dp[n][m]; return 0; }
有n个木棍,长度不等,现在要将他们切成同等长度的木棍m个,并且每段的长度都为整数。问这m根木棍最长能有多长?
如果分不出来,输出0。
输入第一行2个数:n, m中间用空格分隔(1 <= n <= 100000, 1 <= m <= 10^9) 后面n行:每行1个数,对应木棍的长度(1 <= Li <= 10^9)。输出
输出一个整数,对应木棍的长度。输入样例
3 10 15 25 12输出样例
5代码
#include3. 最多分成多少块 [贪心]using namespace std; int n, m, nums[100005]; bool check(int x) { int ans = 0; for (int i = 0; i < n; ++i) ans += (nums[i] / x); return ans >= m; } int main() { cin >> n >> m; for (int i = 0; i < n; ++i) cin >> nums[i]; int lo = 1, hi = 1000000005; while (lo < hi) { int mi = lo + ((hi - lo) >> 1); check(mi) ? lo = mi + 1 : hi = mi; } cout << --lo; return 0; }
小b有个长度为n的数组a,她想将这个数组排序。
然而小b很懒,她觉得对整个数组排序太累了,因此她请你将a分成一些块,使得她只需要对每一块分别排序,就能将整个数组排序。
请问你最多能把a分成多少块。
保证a为0…n-1的一个排列。
样例解释:
将a分成2块或者更多块,都无法得到所需的结果。
例如,分成 [4, 3], [2, 1, 0] ,排序得到的结果是 [3, 4, 0, 1, 2],这不是有序的数组。
第一行一个数n; 第二行n个数表示a[i],以空格隔开。 n<=10输出
输出一个数表示划分块的数量输入样例
5 4 3 2 1 0输出样例
5代码
#include4. 躲猫猫 [DFS]using namespace std; int n, nums[100005]; int main() { cin >> n; for (int i = 0; i < n; ++i) cin >> nums[i]; int ans = 0; for (int i = 0, maxNumber = -1; i < n; ++i) { maxNumber = max(maxNumber, nums[i]); if (maxNumber == i) ans++; } cout << ans; return 0; }
在一个8*8的二维平面内,你初始时刻处于M点,每一个移动轮次你可以向8联通的方向走1格,也可以呆在原地保持不动。你需要移动到逃生点A,并且安全待到你的下一移动轮次才能逃生。
方格内还有很多猫,用S表示。每一移动轮次你先移动,在你移动结束后,所有的猫都会同时向下移动一格(在二维平面最下方一行时,如果猫向下移动视为移出平面,不再出现)。所有猫移动完成之后,视为结束这一移动轮次。
问最终你能否从M点移动到A点逃生。可以的话输出Win,否则输出Lost。
输入输入共8行,每行的字符包括'A' 'M' 'S' '.',其中M表示起始位置,A表示终点位置,S表示猫,.表示空地,可以随便走。输出
输出共1行,如果可以从M点移动到A点。输出Win,否则输出Lost。输入样例
.......A ........ ........ ........ ........ ........ SS...... M.......输出样例
Lost代码
#include5. 争渡 [动态规划]using namespace std; const vector > DIR{{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; int xt, yt; bool isCat[8][8]; bool dfs(int xi, int yi, int time) { if (xi < 0 || yi < 0 || xi == 8 || yi == 8) return false; // 边界判断 if (time > 0 && xi - time + 1 > 0 && isCat[xi - time + 1][yi]) return false; // 被猫捕获(前序状态) if (xi - time > 0 && isCat[xi - time][yi]) return false; // 被猫捕获(当前状态) if ((xi == xt && yi == yt) || time == 8) return true; // 所有猫均移除边界, 总有一条路径到达终点 return any_of(DIR.begin(), DIR.end(), [&](const pair dir) { return dfs(xi + dir.first, yi + dir.second, time + 1); }); } int main() { int xi, yi; string s; for (int i = 0; i < 8; ++i) { cin >> s; for (int j = 0; j < 8; ++j) { switch (s[j]) { // 太久没用过 switch 了, 心血来潮用一下 case 'S': isCat[i][j] = true; break; case 'M': xi = i, yi = j; break; case 'A': xt = i, yt = j; break; } } } cout << (dfs(xi, yi, 0) ? "Win" : "Lost"); return 0; }
人生如逆水行舟,不进则退。你一生中有 n n n个阶段,每个阶段有一个状态下限 L i L_i Li,也有一个状态上限 R i R_i Ri,你想规划你的一生中各阶段的状态值,使得你的状态在 n n n个阶段中始终在变好(严格递增)。请你计算有多少种不同的人生规划。由于答案较大,只需输出答案对998244353998244353取余的结果
数据范围: 1 ≤ n ≤ 200 , 1 ≤ L i ≤ R i ≤ 104 1≤n≤200,1≤L_i≤R_i≤104 1≤n≤200,1≤Li≤Ri≤104
输入第一行一个整数n,表示人生的阶段数。 接下来n行,每行两个整数Li, Ri,表示这个阶段的状态值的下限和上限。输出
输出仅一行,表示方案数mod 998244353的结果。输入样例
4 1 6 3 5 1 4 4 6输出样例
4代码
#includeusing namespace std; using ull = unsigned long long; ull dp[205][10005]; int lim[205][2]; int main() { auto &lim_ = lim; auto &dp_ = dp; int n; cin >> n; for (int i = 1; i <= n; ++i) cin >> lim[i][0] >> lim[i][1]; dp[0][0] = 1ll; // 边界条件 for (int i = 1, L, R; i <= n; ++i) { L = lim[i][0], R = lim[i][1]; ull sum = 0; for (int j = 0; j < L; ++j) sum += dp[i - 1][j] % 998244353; for (int j = L; j <= R; ++j) { dp[i][j] = sum; sum += dp[i - 1][j] % 998244353; } } ull ans = 0; for (int j = lim[n][0]; j <= lim[n][1]; ++j) { ans += dp[n][j] % 998244353; } cout << ans % 998244353; return 0; }
题单来源:QQ群200162761。



