Description
快到奶牛冠军杯足球赛了,今年在J队与H队之间将会出现十分激烈的对抗.
作为今年牛奶生产创记录的奖励,约翰同意他的奶牛们观看这场比赛.N(1≤N≤2500)头牛已经在仓房排好队.他们将被挨个儿地接上车,直到约翰喊停.之后下一辆车继续挨个儿接奶牛.最终,奶牛将都被送上车.一些牛是J队的球迷,另一些是H队的球迷,竞争对手之间往往相处得很糟.所以,约翰不能让一辆汽车上载过多的J队球迷或H队球迷,这样另一支队的球迷在途中会受到恐吓.因此,他得保证一辆车中,两队球迷的个数差的绝对值在I(1≤I≤N)内.除非那辆车上只有J队或H队的球迷.
给出奶牛上车的次序,请计算出最少几辆汽车可以解决问题.
Input
第1行输入两个分开的整数N和J;接下来N行表示奶牛们在仓房中排队的顺序.用J和H表示
她们是J队和H队昀球迷.
Output
一个整数,表示最少汽车的数量.
Sample Input
14 3
H
J
H
H
H
J
H
J
H
H
H
H
H
H
Sample Output
2
有多种方案,如:除最后5只外,其余皆坐一辆车;最后5只坐第二辆车
**
题解:
dp[i]表示对于前i头牛都上车的话所需要的车的最少数量,那么dp[i]=min(dp[i],dp[j]+1),当第j+1个数和第i个数之间的所有牛满足在同一辆车上的条件的时候即可。判断区间牛数差预处理一下前缀和之类的即可。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN=2501;
int dp[MAXN];
int a[MAXN],b[MAXN];
int main(int argc, char *argv[])
{
memset(dp,0x7f,sizeof(dp));
dp[0]=0;
int n,i,j,m;
char x;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("\n%c",&x);
a[i]=a[i-1],b[i]=b[i-1];
if(x=='H') a[i]++;
else b[i]++;
}
for(i=1;i<=n;i++)
for(j=0;j<i;j++)
{
if((abs(a[i]-a[j]-b[i]+b[j])<=m)||(a[i]-a[j]==0)||(b[i]-b[j]==0)) dp[i]=min(dp[i],dp[j]+1);
}
printf("%d\n",dp[n]);
return 0;
}