Codeforce 基礎dp專題
阿新 • • 發佈:2020-10-29
連結: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; }