版权声明:这是gigo写的QAQ https://blog.csdn.net/qq_42835815/article/details/85387761
一道线性dp,,代码+读优 40排qwq
上代码+注释
#include<bits/stdc++.h>
#define in read()
using namespace std;
int in{
int cnt=0,f=1;char ch=0;
while(!isdigit(ch)){
ch=getchar();
if(ch=='-')f=-1;
}
while(isdigit(ch)){
cnt=cnt*10+ch-48;
ch=getchar();
}
return cnt*f;
}
int n,m;
int a[2503];
int f[2503];
int sum1[2503],sum2[2503];//1个数的前缀和,2的前缀和
int main(){
n=in;m=in;
for(int i=1;i<=n;i++){
a[i]=in;
sum1[i]=sum1[i-1];sum2[i]=sum2[i-1];
if(a[i]==1)sum1[i]++;
else sum2[i]++;
}
memset(f,0x3f,sizeof(f));//初始很大 ,f[i]表示1~i这些人用的最少教室
f[0]=0;//0个人自然0间教室
for(int i=1;i<=n;i++){
for(int j=1;j<i;j++){//枚举j~i的人放一间教室
if(abs(sum1[i]-sum1[j-1]-sum2[i]+sum2[j-1])<=m||sum1[i]-sum1[j-1]==0||sum2[i]-sum2[j-1]==0){
//分别是:人数差<=m,全部是2的粉丝,全部是1的粉丝。
f[i]=min(f[i],f[j-1]+1);
}
}
if(f[i]==f[i+1])f[i]=f[i-1]+1;//注意,如果之前没有可更新情况,那说明
//这个人要单独用一间教室,故直接等于上一个人+1
}
cout<<f[n]<<endl;
return 0;
}