监狱

Description

Ciocio在执行刺杀计划的过程中被警方抓捕,被送到了一座监狱。与Ciocio同时入狱的共有N-1位罪犯(即共有N个人)。这些罪犯有的是白人,有的是黑人。狱警要给他们分房间。但是,监狱为减少不必要的冲突,要求:要么保证整个房间都是同一肤色的罪犯,或者同一房间两种不同肤色罪犯的人数差不超过M。另外,现在N个罪犯被锁链拴成成一排,狱警只会把连续一段的罪犯分进一个房间。狱警想知道,至少需要多少个房间(假设每个房间可容纳无限罪犯)。

Input

第一行包括N和M。 
之后N行,每行一个整数,代表罪犯的肤色,1表示白色,2表示黑色。

Output

一个整数,表示最小需要房间的数量。

Sample Input

12 1
1
1
1
1
2
1
2
1
1
2
2
2

Sample Output

2

Hint

对于30%的数据,有1 ≤ N ,M≤ 50; 
对于60%的数据,有1 ≤ N ,M≤ 1000; 
对于100%的数据,有1 ≤ N,M ≤ 2500。


【分析】

        很明显是DP,为什么很明显呢?因为题目要求的是连续的一段要放在一起。我们这样定义状态:F[i]表示以i结尾的人,最少用多少个房间。然后用两个数组w,b分别来记录白人和黑人的前缀和。

        方程:F[i]=min(F[k])+1;  abs((w[i]-w[k])-(b[i]-b[k]))<=M||w[i]-w[k]==0||b[i]-b[k]==0;


【代码】

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=999999999;
int N,M;
int v[2505],w[2505],b[2505],f[2505];
void _init()
{
	scanf("%d%d",&N,&M);
	for(int i=1;i<=N;i++)
	{
		f[i]=INF;
	    scanf("%d",&v[i]);
	}
}
void _solve()
{
	for(int i=1;i<=N;i++)
	{
		w[i]=w[i-1];
		b[i]=b[i-1];
		if(v[i]==1)
		    w[i]++;
		else
		    b[i]++;
	}
	f[0]=0;
	for(int i=1;i<=N;i++)
	{
		int temp=INF;
		for(int k=0;k<=i;k++)
		    if(abs(w[i]-w[k]-b[i]+b[k])<=M||w[i]-w[k]==0||b[i]-b[k]==0)
		        temp=min(temp,f[k]);
		f[i]=temp+1;
	}
	printf("%d\n",f[N]);
}
int main()
{
	_init();
	_solve();
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值