Codeforce 基础dp专题

链接:https://codeforces.com/contest/467/problem/C

这道题是求拿k个子序列且不能相交,问如何拿使得这些序列的值的和最大,那么阶段划分就很明显了,相当于这道问题对应的隐式DAG上一共可以被分成K层,接着就是枚举在哪个点转移,也就是是否取当前的往左m的区间,对应的就是在DAG求最短最长路的时候,是从同一层转移过来还是从前一层转移过来,取最大最小值贪心,类似dijk的思路。

#include<bits/stdc++.h>
using namespace std;
void check_max (int &a,int b) {a=max (a,b);}
typedef long long ll;
const int maxn=5100;
ll a[maxn];
ll dp[maxn][maxn];
ll pre[maxn];

int main () {
  int n,m,k;
  scanf ("%d%d%d",&n,&m,&k);
  ll st=0;
  for (int i=1;i<=n;i++) {
    scanf ("%lld",&a[i]);
    st+=a[i];
    pre[i]=st;
  }
  memset (dp,0,sizeof (dp));
  // for (int j=m;j<=n;j++) 
  //  for (int i=1;i<=k;i++) {
  //   dp[i][j]=max (dp[i][j-1],dp[i-1][j-m]+pre[j]-pre[j-m]);
  //  }
  for (int i=1;i<=k;i++) 
   for (int j=m;j<=n;j++) {
    dp[i][j]=max (dp[i][j-1],dp[i-1][j-m]+pre[j]-pre[j-m]);
   }
  printf ("%lld\n",dp[k][n]);
  return 0;
}
上一篇:CodeForce 387D. George and Interesting Graph


下一篇:CodeForce 981F. Round Marriage