微软2016校园招聘在线笔试 [Recruitment]

 

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

描述

A company plans to recruit some new employees. There are N candidates (indexed from 1 to N) have taken the recruitment examination. After the examination, the well-estimated ability value as well as the expected salary per year of each candidate is collected by the Human Resource Department.

Now the company need to choose their new employees according to these data. To maximize the company's benefits, some principles should be followed:

1. There should be exactly X males and Y females.

2. The sum of salaries per year of the chosen candidates should not exceed the given budget B.

3. The sum of ability values of the chosen candidates should be maximum, without breaking the previous principles. Based on this, the sum of the salary per year should be minimum.

4. If there are multiple answers, choose the lexicographically smallest one. In other words, you should minimize the smallest index of the chosen candidates; If there are still multiple answers, then minimize the second smallest index; If still multiple answers, then minimize the third smallest one; ...

Your task is to help the company choose the new employees from those candidates.

输入

The first line contains four integers N, X, Y, and B, separated by a single space. The meanings of all these variables are showed in the description above. 1 <= N <= 100, 0 <= X <= N, 0 <= Y <= N, 1 <= X + Y <= N, 1 <= B <= 1000.

Then follows N lines. The i-th line contains the data of the i-th candidate: a character G, and two integers V and S, separated by a single space. G indicates the gender (either "M" for male, or "F" for female), V is the well-estimated ability value and S is the expected salary per year of this candidate. 1 <= V <= 10000, 0 <= S <= 10.

We assure that there is always at least one possible answer.

输出

On the first line, output the sum of ability values and the sum of salaries per year of the chosen candidates, separated by a single space.

On the second line, output the indexes of the chosen candidates in ascending order, separated by a single space.

样例输入
4 1 1 10
F 2 3
M 7 6
M 3 2
F 9 9
样例输出
9 9
1 2

思路,动态规划,男女分别求出在某个salary i,选择j个男/女的最小花费(转移方程比较简单就不写了,可以滚动数组求),最后枚举男的salary i和女的salary j 找最大值即可。剩下的就是细节,保证找出满足题目要求的最优解。应该不会超时。

代码没有提交验证,只是写了自己的思路。

  1 #include <vector>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <iostream>
  6 #include <algorithm>
  7 using namespace std;
  8 typedef long long  ll;
  9 
 10 #define inf 0x7fffffff
 11 
 12 #define read freopen("in.txt","r",stdin)
 13 
 14 #define N 111
 15 #define B 1111
 16 int dp[2][2][N][B];
 17 int tr[2][N][B];
 18 int ss[N];
 19 vector<int>v1,v2;
 20 int main()
 21 {
 22     //read;
 23     int n,x,y,b;
 24     while (~scanf("%d%d%d%d\n",&n,&x,&y,&b))
 25     {
 26         memset(dp,-1,sizeof(dp));
 27         for (int i = 0; i < 2; ++i)
 28             for (int j = 0; j < 2; ++j)
 29                 dp[i][j][0][0] = 0;
 30         char g;
 31         int v,s;
 32         int c1 = 0,c2 = 0;
 33         for (int i = 1; i <= n; ++i)
 34         {
 35             scanf("%c%d%d\n",&g,&v,&s);
 36             ss[i] = s;
 37             int c,f,r;
 38             if (g == 'M')
 39             {
 40                 c1++;
 41                 r = 0;
 42                 c = c1;
 43             }
 44             else
 45             {
 46                 c2++;
 47                 r = 1;
 48                 c = c2;
 49             }
 50             f = c%2;
 51             for (int j = 1; j <= c; ++j)
 52                 for (int k = 0; k <= b; ++k)
 53                 {
 54                     dp[r][f][j][k] = dp[r][1-f][j][k];
 55                     if (k >= s && ~dp[r][1-f][j-1][k-s] && dp[r][1-f][j-1][k-s] + v > dp[r][f][j][k])
 56                     {
 57                         dp[r][f][j][k] = dp[r][1-f][j-1][k-s] + v;
 58                         tr[r][j][k] = i;
 59                     }
 60                 }
 61         }
 62         int ans = 0,cost = inf;
 63         for (int i = 0; i <= b; ++i)
 64             for (int j = 0; j <= b -i ; ++j)
 65                 {
 66                     if (dp[0][c1%2][x][i] == -1 || dp[1][c2%2][y][j] == -1)
 67                         continue;
 68                     int ta =dp[0][c1%2][x][i] + dp[1][c2%2][y][j];
 69                     int tb = i + j;
 70                     if (ans < ta || (ans == ta && tb < cost))
 71                     {
 72                         ans = ta,cost = tb;
 73                         v1.clear();
 74                         int t1 = x, t2 = i;
 75                         while (tr[0][t1][t2])
 76                         {
 77                             v1.push_back(tr[0][t1][t2]);
 78                             t1--;
 79                             t2 -= ss[tr[0][t1][t2]];
 80                         }
 81                         t1 = y, t2 = j;
 82                         while( tr[1][t1][t2])
 83                         {
 84                             v1.push_back(tr[1][t1][t2]);
 85                             t1--;
 86                             t2 -= ss[tr[1][t1][t2]];
 87                         }
 88                         sort(v1.begin(),v1.end());
 89                     }
 90                     else if (ans == ta && cost == tb)
 91                     {
 92                         v2.clear();
 93                         int t1 = x, t2 = i;
 94                         while (tr[0][t1][t2])
 95                         {
 96                             v2.push_back(tr[0][t1][t2]);
 97                             t1--;
 98                             t2 -= ss[tr[0][t1][t2]];
 99                         }
100                         t1 = y, t2 = j;
101                         while( tr[1][t1][t2])
102                         {
103                             v2.push_back(tr[0][t1][t2]);
104                             t1--;
105                             t2 -= ss[tr[1][t1][t2]];
106                         }
107                         sort(v2.begin(),v2.end());
108                         bool flag = false;
109                         for (size_t i = 0; i < v1.size(); ++i)
110                             if (v1[i] > v2[i])
111                             {
112                                 flag = true;
113                                 break;
114                             }
115                         if (flag)
116                         {
117                             v1.clear();
118                             for (size_t i = 0; i < v2.size(); ++i)
119                                 v1.push_back(v2[i]);
120                         }
121                     }
122                 }
123         printf("%d %d\n",ans,cost);
124         for (size_t i = 0; i < v1.size(); ++i)
125         {
126             if (i)
127                 printf(" ");
128             printf("%d",v1[i]);
129         }
130         printf("\n");
131 
132     }
133     return 0;
134 }
View Code

 

另外求C题[Islands Travel]思路……,不会做……。以下:

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

描述

There are N islands on a planet whose coordinates are (X1, Y1), (X2, Y2), (X3, Y3) ..., (XN, YN). You starts at the 1st island (X1, Y1) and your destination is the n-th island (XN, YN). Travelling between i-th and j-th islands will cost you min{|Xi-Xj|, |Yi-Yj|} (|a| denotes the absolute value of a. min{a, b} denotes the smaller value between a and b) gold coins. You want to know what is the minimum cost to travel from the 1st island to the n-th island.

输入

Line 1: an integer N.

Line 2~N+1: each line contains two integers Xi and Yi.

 

For 40% data, N<=1000,0<=Xi,Yi<=100000.

For 100% data, N<=100000,0<=Xi,Yi<=1000000000.

输出

Output the minimum cost.

样例输入
3
2 2
1 7
7 6
样例输出
2

 

posted @ 2015-04-07 17:21  McFlurry  阅读(686)  评论(0编辑  收藏  举报