CF467C George and Job 题解 DP 前缀和

DP 前缀和

题目链接

题意:

给你一个长度为\(n\)的序列,让你从这个序列中挑选出\(k\)个长度为\(m\)的区间,并且任意区间不相交。使得选出的数之和最大,求出这个数。

解法:

很经典的DP模型,我们定义\(f_{i,j}\)表示从前\(i\)个数选出了\(j\)个区间可以取得的最大值,那么答案为:\(f_{n,k}\)
根据闫式DP分析法,我们可以按照第\(i\)个元素选还是不选来划分。
①不选:结果即为\(f_{i-1,j}\)
②选:结果即为:\(f_{i-m,j-1}+a_{i-m+1}+a_{i-m+2}+...+a_{i-1}+a_{i}\)
用前缀和优化一下:\(f_{i-m,j-1}+s_i-s_{i-m}\)
两种情况取个max即可。

参考代码

void Showball(){
  int n,m,k;
  cin>>n>>m>>k;
  vector<LL> a(n+1),s(n+1);
  for(int i=1;i<=n;i++){
    cin>>a[i];
    s[i]=s[i-1]+a[i];
  }    
  vector f(n+1,vector<LL>(k+1));

  for(int i=1;i<=n;i++){
    for(int j=1;j<=k;j++){
      f[i][j]=f[i-1][j];
      if(i>=m) f[i][j]=max(f[i][j],f[i-m][j-1]+s[i]-s[i-m]);
    }
  }
  
  cout<<f[n][k]<<endl;
}
posted @ 2024-01-24 21:36  Showball  阅读(3)  评论(0编辑  收藏  举报