hihocoder编程练习赛75

题目1 : 工作城市分配

时间限制:10000ms
单点时限:1000ms
内存限制: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
 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 }
View Code

题目2 : 工作城市分配2

时间限制:10000ms
单点时限:1000ms
内存限制: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
 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 }
View Code

题目3 : 顺子组合

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

你有一个包含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 }
View Code

题目4 : 栈的加强版

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

请你实现一个加强版的栈,支持以下操作:

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 }
View Code

 

转载于:https://www.cnblogs.com/Penn000/p/9601239.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值