hihocoder 编程挑战赛75
题目1
内存限制:256MB
描述
H公司在北京和上海两个城市各有一间办公室。该公司最近新招募了2N名员工,小Hi负责把这2N名员工分配到北京和上海各N名。
于是小Hi调查了新员工对于北京和上海的意愿,我们用Bi和Si表示。Bi代表如果分配第i名员工去北京,他的满意指数;Si代表如果分配去上海,他的满意指数。
小Hi想知道如何分配才能使2N名员工的满意指数之和最高。
输入
第一行包含一个整数N。
以下2N行每行包含两个整数Bi和Si。
1 ≤ N ≤ 1000
0 ≤ Bi, Si ≤ 100000
输出
一个整数代表最高可能的满意指数之和。
测试样例
样例输入
2
100 50
80 80
50 100
10 30
样例输出
310
题解
#include <bits/stdc++.h> using namespace std; #define MAXN (1010) static int B[2 * MAXN], S[2 * MAXN]; int sat[MAXN][MAXN]; int main() { int n; while (cin >> n) { memset(B, 0, sizeof(B)); memset(S, 0, sizeof(S)); for (int i = 1; i <= 2 * n; i++) { cin >> B[i] >> S[i]; } memset(sat, 0, sizeof(sat)); for (int i = 1; i <= n; i++) { sat[i][0] = sat[i - 1][0] + B[i]; sat[0][i] = sat[0][i - 1] + S[i]; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { sat[i][j] = max(sat[i][j - 1] + S[i + j], sat[i - 1][j] + B[i + j]); } } cout << sat[n][n] << endl; } return 0; }
题目2
内存限制:256MB
描述
H公司在北京、上海和纽约三个城市各有一间办公室。该公司最近新招募了3N名员工,小Hi负责把这3N名员工分配到北京、上海和纽约各N名。
于是小Hi调查了新员工对于北京、上海和纽约的意愿,我们用Bi、Si和Ni表示。Bi代表如果分配第i名员工去北京,他的满意指数;Si代表如果分配去上海的满意指数;Ni代表如果分配去纽约的满意指数。
小Hi想知道如何分配才能使3N名员工的满意指数之和最高。
输入
第一行包含一个整数N。
以下3N行每行包含两个整数Bi、Si和Ni。
1 ≤ N ≤ 100
0 ≤ Bi, Si, Ni ≤ 100000
输出
一个整数代表最高可能的满意指数之和。
样例
样例输入
2
100 50 100
80 80 100
50 100 100
10 30 100
80 40 30
20 70 50
样例输出
550
#include <bits/stdc++.h> using namespace std; #define MAXN (1010) static int B[2 * MAXN], S[2 * MAXN]; int sat[MAXN][MAXN]; int main() { int n; while (cin >> n) { memset(B, 0, sizeof(B)); memset(S, 0, sizeof(S)); for (int i = 1; i <= 2 * n; i++) { cin >> B[i] >> S[i]; } memset(sat, 0, sizeof(sat)); for (int i = 1; i <= n; i++) { sat[i][0] = sat[i - 1][0] + B[i]; sat[0][i] = sat[0][i - 1] + S[i]; } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { sat[i][j] = max(sat[i][j - 1] + S[i + j], sat[i - 1][j] + B[i + j]); } } cout << sat[n][n] << endl; } return 0; }
题目3
hihocoder #1818 : 顺子组合
问题来源URL
http://hihocoder.com/problemset/problem/1818
描述
你有一个包含N个整数的数组:A1, A2, ... AN。我们将3个或3个以上数值连续的整数序列称作顺子,例如[1, 2, 3]、[5, 6, 7, 8]和[10, 11, 12, 13, 14, 15, 16]都是顺子。
请你判断A数组是否能拆分成若干个顺子的组合。要求每个整数Ai恰好只属于其中一个顺子。
输入
第一行包含一个整数T代表测试数据的组数。
每组数据第一行包含一个整数N。
每组数据第二行包含N个整数A1, A2, ... AN。
1 ≤ T ≤ 10
1 ≤ N ≤ 10000
0 ≤ Ai ≤ 100000
输出
对于每组数据输出YES或者NO代表是否能拆分成顺子组合。
测试样例
样例输入
2
7
4 1 3 2 5 4 6
8
4 1 3 2 5 4 6 6
样例输出
YES
NO
题解
顺子是扑克牌的一种排列顺序,指的是花色不一定相同的牌是一个连续的序列,该序列的长度还大于等于3。题目中的要求是让牌的划分序列每个的连续长度>=3。事实上,这个要求跟每个序列的长度都在3-5是等价的。如果能够满足3-5,则必然能满足>=3,因为3-5包含于>=3的情况;反过来,>=3的序列必然可以拆成3-5的序列。由于这个原因,我们找到了这个题的对应题目,http://codeforces.com/gym/101775/problem/J。
解决这道题,可以是按照如下思路:
怎么把顺子合成一个序列,而不是拆分?显然,合成是非常简单的,顺子是一个表示个数的1序列,长度>=3,合成的话就是区间累加了。把它用差分序列表示的话,就是1,0,0,(至少有2个0)-1。最后得到的序列的差分,肯定是差分序列的叠加了。所以我们可以把它们累加起来,判断最后的和是否是等于0,并结合其他条件判定是多个顺子的组合。
代码
#include<stdio.h> #include<bits/stdc++.h> using namespace std; #define MAXN 100010 int arr[MAXN]; int differ[MAXN]; int main() { int N, T; cin >> T; int a; for (int i = 0; i < T; i++) { cin >> N; memset(arr, 0, sizeof(arr)); memset(differ, 0, sizeof(differ)); int maxn = 0; for (int j = 0; j < N; j++) { cin >> a; maxn = max(a, maxn); arr[a]++; } for (int j = 0; j <= MAXN; j++) { differ[j + 1] = arr[j + 1] - arr[j]; } differ[0] = arr[0]; int t = 0; int sum = 0; for (int j = 0; j <= maxn; j++) { if (differ[j] > 0) sum += differ[j]; if (j + 3 <= maxn + 1) { if (differ[j + 3] < 0) { sum += differ[j + 3]; differ[j + 3] = 0; } if (sum < 0) break; } } #if 0 for (int i = 0; i <= maxn; i++) { printf(" %d", differ[i]); } printf("\n"); #endif if (sum != 0) { cout << "NO\n"; } else { cout << "YES\n"; } } return 0; }
测试
3
3
0 1 2
1
10
7
0 1 2 3 9 10 11
7
0 1 2 3 5 6 8
>>Output:
YES
YES
NO
题目4
描述
请你实现一个加强版的栈,支持以下操作:
push x: 向栈顶加入一个整数x
pop: 从栈顶弹出一个整数,并且输出该整数
inc k x: 将处于栈底的前k个整数加x。
输入
第一行包含一个整数N,代表操作的数量。
以下N行每行一条操作。
1 ≤ N ≤ 200000, 0 ≤ x ≤ 100000, 1 ≤ k ≤ 当前栈的大小
输出
对于每一个pop操作,输出弹出的整数数值。
测试样例
样例输入
6
push 1
inc 1 2
push 2
inc 2 2
pop
pop
样例输出
4
5
题解
即使想用线段树也显得多余,因为在栈的操作中其实有一个很简单的特性就是每次只能pop一个,再加上问题中的条件是前k个增加值,所以并不会有需要利用线段树减少复杂度的情况。
代码
#include<stdio.h> #include<bits/stdc++.h> using namespace std; #define MAXN 100010 int arr[MAXN]; int differ[MAXN]; int main() { int N, T; cin >> T; int a; for (int i = 0; i < T; i++) { cin >> N; memset(arr, 0, sizeof(arr)); memset(differ, 0, sizeof(differ)); int maxn = 0; for (int j = 0; j < N; j++) { cin >> a; maxn = max(a, maxn); arr[a]++; } for (int j = 0; j <= MAXN; j++) { differ[j + 1] = arr[j + 1] - arr[j]; } differ[0] = arr[0]; int t = 0; int sum = 0; for (int j = 0; j <= maxn; j++) { if (differ[j] > 0) sum += differ[j]; if (j + 3 <= maxn + 1) { if (differ[j + 3] < 0) { sum += differ[j + 3]; differ[j + 3] = 0; } if (sum < 0) break; } } #if 0 for (int i = 0; i <= maxn; i++) { printf(" %d", differ[i]); } printf("\n"); #endif if (sum != 0) { cout << "NO\n"; } else { cout << "YES\n"; } } return 0; }
参考
http://codeforces.com/gym/101775/problem/J Straight Master
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通