题目:
由于工作业绩优秀,公司给小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}