zoukankan      html  css  js  c++  java
  • Codefroces 958C2

    转自:https://www.cnblogs.com/widsom/p/8857777.html     略有修改

    题目大意:

    n个数,划分为k段,每一段的和mod p,求出每一段的并相加,求最大是多少

    基本思路:

    区间dp无疑

    dp[i][j] 表示到第i个位置为止,分成j段的最大值

    dp[i][j]=max(dp[i][j],dp[l][j-1]+(sum[i]-sum[l])%p)  0<l<i

    由于n很大,p很小,所以优化一下

    dp[i][j] 表示sum取模p后为i,分成j段的最大值

    dp[i][j] = max(dp[i][j],dp[l][j-1] + (sum[i] - l) % p) 0<= l < p

    代码如下:

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<set>
    
    using namespace std;
    
    typedef long long ll;
    typedef long long LL;
    typedef pair<int,int> pii;
    const int inf = 0x3f3f3f3f;
    const int maxn = 20000+10;
    const ll mod = 1e9+9;
    
    int dp[110][60];
    int a[maxn];
    int main(){
        int n,k,p;
        scanf("%d%d%d",&n,&k,&p);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            a[i]+=a[i-1];
            a[i]%=p;
        }
        for(int i=0;i<p;i++){
            for(int j=0;j<=k;j++){
                dp[i][j]=-inf;
            }
        }
        dp[0][0]=0;
        for(int i=1;i<=n;i++){
            for(int j=k;j>=1;j--){
                for(int l=0;l<p;l++){
                    dp[a[i]][j]=max(dp[a[i]][j],dp[l][j-1]+(a[i]-l+p)%p);
                }
            }
        }
        printf("%d
    ",dp[a[n]][k]);
        return 0;
    }
    

      

  • 相关阅读:
    shell中对于命令的搜寻顺序
    在shell中运行以不同方式运行脚本
    shell中的type命令
    shell中的数组
    shell中的循环语句
    shell中的case表达式
    双方括号
    34. Win7_x64安装oracle11g出现DIM-00019
    33. 完全卸载oracle11g步骤
    32. 安装oracle11g时,先决条件一直失败的解决方法
  • 原文地址:https://www.cnblogs.com/imzscilovecode/p/8889350.html
Copyright © 2011-2022 走看看