腾讯校园招聘笔试 2019-8-17 第五题

自己是真滴菜啊,跟着师兄做校招笔试被虐的体无完肤。在这里记录一下几道题的解法吧。

由于业绩优秀,公司给小Q放了n天的假。身为工作狂的小Q打算在假期中工作、锻炼或者休息。他有一个奇怪的习惯,:不会连续两天工作或锻炼。只有当公司营业时,小Q才能去工作,只有当健身房营业时,小Q才能去健身,小Q每天只能干一件事。给出假期中的公司,健身房营业情况,求小Q最少需要休息几天。

输入描述:

第一行一个整数n(1<=n<=100000)表示放假天数;第二行n个数 每个数为0或者1,第i个数表示公司在第i天是否营业。第三行n个数,每个数为0或者1,第i个数表示那沈芳在第i填是否营业。 1为营业,0为不营业。

比如 

4

1 1 0 0 

0 1 1 0

思路:这道题是有状态的动态规划。因为有一个限制条件,就是不会连续两天工作或者锻炼,所以是有状态的转移。

那么我设置一个dp[3][n],其中第一行dp[0][i]表示第i天休息的时候,i天之内最少休息的天数;dp[1][i]表示第i天工作的时候,i天之内最少休息的天数.dp[2][i]表示第i天健身的时候,i天之内最少休息的天数。

递推关系是:对于第i天,如果今天可以工作,今天工作条件下最少休息的天数  = min(昨天健身条件下最少休息天数,昨天休息条件下最少休息天数);这里面,因为今天工作的条件下就限制了昨天不能是工作,所以这里面只有两个相比较;同样道理,今天健身条件下最少休息天数 = min(昨天工作条件下最少休息天数,昨天休息条件下最少休息天数)。但是对于今天休息的情况,就不一样了,因为今天休息,昨天干什么都行,所以是:今天休息条件下最少的休息天数 = 1 + min(昨天健身条件下最少休息天数,昨天休息条件下最少休息天数,昨天工作条件下最少休息天数)。

 

所以代码如下所示:

int mymin(int a, int b, int c){
	int ret = a;
	if (b < ret) ret = b;
	if (c < ret) ret = c;
	return ret;
}
int main(){
	
	int n;
	cin >> n;
	int canwork[10005] = {0};
	int canfitness[10005] = { 0 };
	for (int i = 0; i < n; i++){
		cin >> canwork[i];
	}
	for (int i = 0; i < n; i++){
		cin >> canfitness[i];
	}

	//dp[0][i]表示第i天休息的最少的休息天数,dp[1][i]表示第i天工作最少的休息天数,dp[2][i]表示第i天健身最少的休息天数
	int dp[3][10005];
	memset(dp, 0, sizeof(dp));
	/*边界条件:*/
	dp[0][0] = 1;
	if (canwork[0]) dp[1][0] = 0;
	if (canfitness[0]) dp[2][0] = 0;
	

	for (int i = 1; i < n; i++){
		/*讨论今天能不能工作下的情况*/
		if (canwork[i]){
			if (canfitness[i - 1]){//上一天能健身,说明今天要取上一天健身或者休息的中较小的
				dp[1][i] = min(dp[0][i - 1], dp[2][i - 1]);
			}
			else{//昨天不能健身,但是今天还要工作,说明昨天只是休息了
				dp[1][i] = dp[0][i - 1];
			}
			
		}
		else{//今天不能工作,不符合定义,设置为最大值n
			dp[1][i] = n;
		}
		/*讨论今天能不能健身的情况*/
		if (canfitness[i]){
			if (canwork[i - 1]){
				dp[2][i] = min(dp[0][i - 1], dp[1][i - 1]);
			}
			else{
				dp[2][i] = dp[0][i - 1];
			}
		}
		else
		{
			dp[2][i] = n;
		}

		/*讨论今天休息的情况,无论昨天干了什么都能休息*/

		dp[0][i] = mymin(dp[0][i - 1], dp[1][i - 1], dp[2][i - 1]) + 1;
	}
	cout<< mymin(dp[0][n - 1], dp[1][n - 1], dp[2][n - 1])<<endl;
	system("pause");
	return 0;
}

自己菜还是要多总结多进步。一般来说,带有状态转移的动态规划,一般会以最后一步的状态作为区分,来进行状态转移。这里面也是如此,设置dp[1][i],第一维度是最后一天确定干了什么东西的条件下来进行分析。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值