2020校招8.17日腾讯技术笔试题5

题目:
由于工作业绩优秀,公司给小Q放了n天的假,身为工作狂的小Q打算在假期中工作、锻炼和休息。他有个奇怪的习惯:不会连续两天工作或锻炼。只有当公司营业时,小Q才能去工作,只有当健身房营业时,小Q才能去健身,小Q一天只能干一件事。给出假期中公司,健身房的营业情况,求小Q最少需要休息几天?
输入:
输入描述第ー行一个数表示放假天数
第二行n个数句个数为0或者1,第i个数表示公司在第i天是否营业
第三行n个数每个数为0或者1,第i个数表示健身房在第i天是否营业
(1为营业0为不营业)
输出:
表示小Q休息的最少天数

 

 

动态规划的题:类似维特比算法,在三行n列的矩阵中找到最优路径。就是路径的限制和评价标准变化了。

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <vector>
 4 #include <string>
 5 #include <stack>
 6 using namespace std;
 7 int dp[3][100000] = { 100000 };
 8 int work[100000];
 9 int keep[100000];
10
11//greater<int>()
12int main()
13{
14    int n;
15    cin >> n;
16    for (int i = 0; i < n; i++)
17    {
18        cin >> work[i];
19    }
20    for (int i = 0; i < n; i++)
21    {
22        cin >> keep[i];
23    }

      // 初始化矩阵的数值
24    //第一天如果休息,休息天数为1
25    dp[0][0] = 1;
26    //如果可以工作,休息天数为0
27    if (work[0] == 1)
28        dp[1][0] = 0;
29    //如果可以健身,休息天数为0
30    if (keep[0] == 1)
31        dp[2][0] = 0;

      // 一共放了n天假,每天有三个选择,也就是组成3*n的矩阵。
32    for (int i = 1; i < n; i++)
33    {
          // 如果公司开门,可以上班
34        if (work[i] == 1)
35        {
              // 如果昨天可以去健身
36            if (keep[i - 1] == 1)
37                //dp[1][i] = min(前一天休息,前一天健身);
                  // 因为不能连着两天工作或者健身,所以只需要考虑前一天休息或健身的情况
38                dp[1][i] = min(dp[0][i - 1], dp[2][i - 1]);
39            else
                  // 如果昨天不能去健身,那就只用考虑昨天休息的情况,由于今天在工作,所以今天的                                    
                  // 休息天数等于昨天休息的休息天数
40                dp[1][i] = dp[0][i - 1];
41        }
          // 如果不能去工作,就给这一天的最少休息天数赋值为n,因为是求最少休息天数,肯定不会大于               
          // n,所以赋值为n不会影响。
42        else
43            dp[1][i] = n;

          // 如果可以健身
44        if (keep[i] == 1)
45        {
46            if (work[i - 1] == 1)
47                //dp[2][i] = min(前一天休息,前一天工作);
48                dp[2][i] = min(dp[0][i - 1], dp[1][i - 1]);
49            else
50                dp[2][i] = dp[0][i - 1];
51        }
52        else
53            dp[2][i] = n;

          // 今天休息的情况
54        //dp[0][i] = min(前一天工作,前一天健身,前一天休息);
55        int min_num= dp[0][i - 1]; // 先把如果昨天休息的最少休息天数记录下来
          // 因为今天是休息,昨天健身或者工作都是可以的 
56        if (work[i - 1] == 1)
57        {
58            min_num = min(dp[1][i - 1], min_num);
59        }
60        if (keep[i - 1]==1)
61        {
62            min_num = min(dp[2][i - 1], min_num);
63        }
64        // 如果昨天健身和工作都不可以,直接在昨天休息的休息天数上面加一
65        dp[0][i] = min_num + 1;
66    }
67    int goal = min(dp[0][n-1], dp[1][n-1]);
68    goal = min(dp[2][n-1], goal);
69    cout << goal;
70
71}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值