【dp】分配教室

版权声明:这是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;
}

猜你喜欢

转载自blog.csdn.net/qq_42835815/article/details/85387761