Face The Right Way POJ - 3276 简单开关问题


传送门


题目大意:白书例题p150    N头牛拍成一排, 没有牛有头朝前和头朝后,一个机器可以一次反转连续的几头牛, 但需要固定个数K, 也就是每次都反转K头牛,求解反转的最少的次数M和对应的K。注意:反转的牛不能少于K,也就是说在开头和结尾也必须反转K头。


解题思路:递归思想,将问题分解为更小的问题。如果开头第一个牛头朝前,那么其最少的次数就是第二头牛到n-1头牛时最小的次数。如果第一头牛头朝后,那么必须反转。

小技巧:不需要真正的去反转,这样复杂度太高,我们只需记录反转次数,当为奇数时牛就反转了。实现方式看代码。


AC代码:

#include <iostream>
#include <cstdio>

using namespace std;

int A[5005];
int n;

int solve(int k)
{
	int ans = 0;
	int d = 0;
	int md[5005] = {0};
	int sum = 0;
	for(int i=0; i+k<=n; i++)
	{
		if((A[i] + ans)%2)
		{
			md[i] = 1;
			ans++; sum++;
		}
		if(i-k+1 >=0) ans -= md[i-k+1];
	}
	
	for(int i=n-k+1; i<n; i++)
	{
		if((A[i] + ans) %2) return -1;
		if(i-k+1 >= 0) ans -= md[i-k+1];
	}

	return sum;
}

int main()
{
	scanf("%d", &n);
	char s[10];
	for(int i=0; i<n; i++)
	{
		scanf("%s", s);
		if(s[0] == 'B') A[i] = 1;
	}
	int K = 0, M = 1 << 31 -1;
	for(int i=1; i<=n; i++)
	{
		int x = solve(i);
		if(x == -1) continue;
		if(x < M)
		{
			M = x;
			K = i;
		}
	}
	printf("%d %d\n", K, M);
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值