NKOI 1759 监狱

监狱

Time Limit:10000MS  Memory Limit:65536K
Total Submit:109 Accepted:56 
Case Time Limit:1000MS

Description

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

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。

Source



一道有点意思的动规,用f[i]表示前i个人所需的最小监狱数量,用前缀和分别求出i之前的黑人白人的数量b[i]和w[i]

状态转移方程f[i]=min(f[j-1])+1 即第j到第i个人分在同一个房间

注意条件:abs(w[i]-w[j]-b[i]+b[j])<=M或w[i]-w[j]==0或b[i]-b[j]==0,0<=j<i

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值