题解:P14597 [COCI 2025/2026 #2] 递增 / Rastući
吐槽 C 题放紫卡我一年/pz
先转化一下题意:
给你一个长为
n 的序列,要划分为若干连续子段使得每段和单调不降,求划分的最大段数。
显然是一个比较经典的 dp。我们设
说完了状态再来考虑转移。对于每个
#include <bits/stdc++.h>
#define INF 1e18
using namespace std;
using ll=long long;
int n,a[5010];
ll sum[5010],f[5010],g[5010],pre[5010];
vector<ll> ans;
int main(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
sum[i]=sum[i-1]+a[i];
g[i]=INF,pre[i]=-1;
}
g[0]=0;
for(int i=1;i<=n;++i){
for(int j=0;j<i;++j){
ll s=sum[i]-sum[j];
if(s>=g[j]){
if(f[i]<f[j]+1 || (f[i]==f[j]+1 && s<g[i])){
f[i]=f[j]+1;
g[i]=s;
pre[i]=j;
}
}
}
}
int i=n;
while(i){
int j=pre[i];
ans.push_back(sum[i]-sum[j]);
i=j;
}
reverse(ans.begin(),ans.end());
cout<<ans.size()<<"\n";
for(int i=0;i<ans.size();++i) cout<<ans[i]<<" ";
return 0;
}
点个赞呗 qaq