题目描述:
这道题目也是利用动态规划+贪心,基本思想是能去工作就去工作,能去健身就去健身,万般无奈后采取休息。只要是分清楚每种情况的条件,这道题目就没有那么难了。
一、对能否去休息的判断有三种情况 :
1、第i天都关门。
2、昨天锻炼,今天公司关门健身房开门。
3、昨天工作,今天公司开门,健身房关门。
二、对能否工作的判断就简单了,只要昨天未工作,今天只要公司开门就去工作。
三、对能否去健身判断,分两种情况
1、昨天休息,只有公司未开门健身房开门去健身。
2、昨天工作,健身房开门去健身。
对以上的各个情况分别用数组dp记录,dp[i][0]表示第i天最少休息天数,dp[i][1]表示第i天工作的状态,0表示不去工作,1表示工作,dp[i][2]表示第i天健身状态,0表示不去健身,1表示去健身,分别将上述条件实现。
C++代码为:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int loveWorking(vector<int>& company,vector<int>& gymnasium){
int len = company.size();
vector<vector<int>> dp(len,vector<int>(3));
if(company[0] == 1){
dp[0][1] = 1;
}else if(company[0] == 0 && gymnasium[0] == 1){
dp[0][2] = 1;
}else if(company[0] == 0 && gymnasium[0] == 0){
dp[0][0] = 1;
}
for(int i=1; i<len; i++){
//判断休息 1、i天都关门,2、昨天锻炼,今天公司关门健身房开门,3、昨天工作,今天公司开门,健身房关门
if((company[i] == 0 && gymnasium[i] == 0) ||
(dp[i-1][2] == 1 && company[i] == 0 && gymnasium[i] == 1) ||
(dp[i-1][1] == 1 && company[i] == 1 && gymnasium[i] == 0))
{
dp[i][0] = dp[i-1][0] + 1;
}
// 判断去工作和锻炼,只要昨天未工作,今天只要公司开门就去工作
if(dp[i-1][1] == 0 && company[i] == 1){
dp[i][1] = 1;
}
// 判断去健身 分两种 1、昨天休息,只有公司未开门健身房开门去健身,2、昨天工作,健身房开门去健身。
if((dp[i-1][1] == 0 && dp[i-1][2] == 0 && company[i] == 0 && gymnasium[i] == 1) ||
(dp[i-1][1] == 1 && gymnasium[i] == 1)){
dp[i][2] = 1;
}
}
return dp[len-1][0];
}
int main(){
int n;
cin >> n;
vector<int> company(n);
vector<int> gymnasium(n);
for(int i=0; i<n;i++){
cin >> company[i];
}
for(int i=0; i<n; i++) {
cin >> gymnasium[i];
}
int res = loveWorking(company,gymnasium);
cout << res << endl;
return 0;
}