CF1197D

Yet Another Subarray Problem - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这道题是一道dp状态跟模数有关的dp,难点就是想到以模数作为dp状态之一,因为 m 很小 (这个以模数作为dp状态是真的妙!!!)

设dp[i][j]为以 i 结尾,取了若干个连续 x个数字( i 一定取走 ),j=x%m

 

为了跟方便的写题以及不容易出错

1.当 x 为j的倍数时且不为 0,规定 j=m(这要主要是好写 关于 k 的向上取整)

2.由于以 i 结尾至少取走一个数,所以 j>0

 

dp转移:dp[i-1][j]已知推广出新的状态:

if(j==m)  dp[i][1]=max(dp[i][1],dp[i-1][j]+a[i]-k); //在j==1时,新出现了一个区间,由于向上取整,故要及时 -k

else  dp[i][j+1]=max(dp[i][j+1],dp[i-1][j]+a[i]);

 

初始化: for(int i=1;i<=n;i++) dp[i][1]=a[i]-k;

ans=max(dp[i][j])

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db long double
#define mp make_pair
#define pb push_back   
#define popb pop_back  
#define fi first
#define se second
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
const int N=3e5+10;
//const int M=;
//const int inf=(int)1e9;
const ll INF=(ll)1e18;
int T,n,m,k,a[N];
ll dp[N][11];
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*f;
}
int main()
{
//    freopen("","r",stdin);
//    freopen("","w",stdout);
//    ios::sync_with_stdio(0);
//    cin.tie(0);
    n=read(),m=read(),k=read();
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=0;i<=n;i++)
        for(int j=0;j<=m;j++)
            dp[i][j]=-INF;
    for(int i=1;i<=n;i++) dp[i][1]=a[i]-k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            if(dp[i-1][j]==-INF) continue;
            if(j==m) dp[i][1]=max(dp[i][1],dp[i-1][j]+a[i]-k);
            else dp[i][j+1]=max(dp[i][j+1],dp[i-1][j]+a[i]);
        }
    ll ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            ans=max(ans,dp[i][j]);
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2023-07-13 21:43  QAQ啥也不会  阅读(7)  评论(0编辑  收藏  举报