前缀和优化dp求助
查看原帖
前缀和优化dp求助
890346
Autumn_0930楼主2025/7/3 17:36

rt,全红了

省流不用管二分(应该……没问题吧)

盲猜是第二问的问题

#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int N=50005,MOD=10007;
int n,m,a[N],s[N],ed[N];
LL f[N],pre[N],ans=0;
int l=0,r=0;
bool check(int lim){
	int add=0,res=0;
	for(int i=1;i<=n;i++){
		if(add+a[i]<=lim) add+=a[i];
		else{
			add=a[i];
			res++;
		}
	}
	if(res<=m) return 1;
	return 0;
}
void dp(){
	for(int i=1;i<=n;i++){ //预处理ed[] 
		for(int j=ed[i-1];j<i;j++){
			if(s[i]-s[j]<=l){
				ed[i]=j;
				break;
			}
		}
	}
	for(int i=1;i<=n;i++){
		if(s[i]<=l) f[i]=1;
		pre[i]=pre[i-1]+f[i];
	}
	for(int i=1;i<=m;i++){
		for(int j=1;j<=n;j++){
			if(ed[j]>=1) f[j]=(pre[j-1]-pre[ed[j]-1]+MOD)%MOD;
			else f[j]=pre[j-1];
		}
		ans=(ans+f[n])%MOD;
		pre[0]=0;
		for(int j=1;j<=n;j++){
			pre[j]=(pre[j-1]+f[j])%MOD;
		}
	}
	if(s[n]<=l) ans++;
	printf("%lld",ans%MOD);
}
int main(){
 	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++){
 		scanf("%d",&a[i]);
 		s[i]=s[i-1]+a[i];
 		l=max(l,a[i]);
 		r+=a[i];
	}
	while(l<=r){
	 	int mid=l+r>>1;
	 	if(check(mid)) r=mid-1;
	 	else l=mid+1;
	}
	printf("%d\n",l);
	dp();
	return 0;
}

求助!另外捞一下

2025/7/3 17:36
加载中...