hihocoder编程练习赛75
题目1 : 工作城市分配
描述
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
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 2200; 6 7 struct Node{ 8 int b, s; 9 }node[N]; 10 11 bool cmp(const Node a, const Node b){ 12 return (a.b-a.s) > (b.b-b.s); 13 } 14 15 int main() 16 { 17 int n; 18 cin>>n; 19 for(int i = 0; i < 2*n; i++){ 20 cin>>node[i].b>>node[i].s; 21 } 22 sort(node, node+2*n, cmp); 23 int ans = 0; 24 for(int i = 0; i < 2*n; i++){ 25 if(i < n)ans += node[i].b; 26 else ans += node[i].s; 27 } 28 cout<<ans<<endl; 29 30 return 0; 31 }
题目2 : 工作城市分配2
描述
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
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int N = 500; 6 7 struct Node{ 8 int b, s, n; 9 }node[N]; 10 11 // dp[i][j][k] 表示前i个人,j个分配到北京,k个分配到上海,i-j-k个分配到纽约的最大满意度 12 int dp[305][105][105]; 13 14 int main() 15 { 16 int n; 17 cin>>n; 18 for(int i = 1; i <= 3*n; i++){ 19 cin>>node[i].b>>node[i].s>>node[i].n; 20 } 21 memset(dp, 0, sizeof(dp)); 22 dp[1][1][0] = node[1].b; 23 dp[1][0][1] = node[1].s; 24 dp[1][0][0] = node[1].n; 25 for(int i = 1; i <= 3*n; i++){ 26 for(int j = 0; j <= n; j++){ 27 for(int k = 0; k <= n; k++){ 28 if(i-j-k>n || i-j-k<0)continue; 29 if(j+1<=n)dp[i+1][j+1][k] = max(dp[i+1][j+1][k], dp[i][j][k]+node[i+1].b); 30 if(k+1<=n)dp[i+1][j][k+1] = max(dp[i+1][j][k+1], dp[i][j][k]+node[i+1].s); 31 if(i-j-k+1<=n)dp[i+1][j][k] = max(dp[i+1][j][k], dp[i][j][k]+node[i+1].n); 32 } 33 } 34 } 35 cout<<dp[3*n][n][n]<<endl; 36 37 return 0; 38 }
题目3 : 顺子组合
描述
你有一个包含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
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int book[110000]; 6 7 bool check(int n){ 8 for(int i = 0; i <= n; i++){ 9 while(book[i]){ 10 int len = 0; 11 for(int j = i; j <= n; j++){ 12 len++; 13 book[j]--; 14 if(book[j+1] <= book[j])break; 15 } 16 if(len < 3)return false; 17 } 18 } 19 return true; 20 } 21 22 int main() 23 { 24 int T, n, a; 25 cin>>T; 26 while(T--){ 27 cin>>n; 28 int len = -1; 29 memset(book, 0, sizeof(book)); 30 for(int i = 0; i < n; i++){ 31 cin>>a; 32 book[a]++; 33 len = max(len, a); 34 } 35 if(check(len))cout<<"YES"<<endl; 36 else cout<<"NO"<<endl; 37 } 38 39 return 0; 40 }
题目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
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int sk[210000], top, fg[210000]; 6 7 int main() 8 { 9 int n, a, b; 10 cin>>n; 11 string op; 12 top = -1; 13 memset(fg, 0, sizeof(fg)); 14 while(n--){ 15 cin>>op; 16 if(op=="push"){ 17 cin>>a; 18 sk[++top] = a; 19 }else if(op=="inc"){ 20 cin>>a>>b; 21 fg[a-1] += b; 22 }else if(op=="pop"){ 23 cout<<sk[top]+fg[top]<<endl; 24 fg[top-1] += fg[top]; 25 fg[top] = 0; 26 top--; 27 } 28 } 29 30 return 0; 31 }