zoukankan      html  css  js  c++  java
  • hust 1539 I’m tired

    题目描述

    ZZZ is an enthusiastic ACMer and he spends lots of time on training. He always stays up late for training. He needs enough time to sleep, and hates skipping classes. So he always sleeps in the class. With the final exams coming, he has to spare some time to listen to the teacher. Today, he hears that the teacher will have a revision class. The class is N (1 <=N <= 1000) minutes long. If ZZZ listens to the teacher in the i-th minute, he can get Ai (1<= Ai <=1000)points. If he starts listening, he will listen to the teacher at least L (1 <=L <= N) minutes consecutively. It`s the most important that he must have at least M (1 <= M <= N) minutes for sleeping (the M minutes needn`t be consecutive).Suppose ZZZknows the points he can get in every minute. Now help ZZZ to compute the maximal points he can get.
    输入

    The input contains several cases. The first line of each case contains three integers N, M, L mentioned in the description. The second line follows N integers separated by spaces. The i-th integer Ai means there are Ai points in thei-th minute.
    输出For each test case, output an integer, indicating the maximal points ZZZ can get.
    样例输入

    10 3 3
    1 2 3 4 5 6 7 8 9 10
    

    样例输出

    49

    显然,类似于乘积最大,我们想到一个dp方程
    dp[i][j]表示在前i分钟睡了j分钟的最优,则dp[i][j]=max(dp[i][j],d[k][j-1]+s[k][i]);
    不过很遗憾,这个方程是n^3的时间复杂度,于是我们想优化一下,当然可以优化,具体看程序吧
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    
    int dp[1001][1001],f[1001][1001],sum[1001],a[1001];
    
    int main()
    {
        int n,m,L;
        while (scanf("%d%d%d",&n,&m,&L)!=EOF)
        {
            memset(dp,0,sizeof(dp));
            memset(f,0,sizeof(f));
            sum[0]=0;
            for (int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                sum[i]=sum[i-1]+a[i];
                if (i>=L) dp[i][0]=sum[i];
            }
            for (int i=1;i<=n;i++)
            for (int j=1;j<=min(m,i);j++)
            {
                if (i-j<L) break;
                f[i][j]=max(f[i-1][j]+a[i],dp[i-L][j]+sum[i]-sum[i-L]);
                dp[i][j]=max(dp[i-1][j-1],f[i][j]);
            }
            printf("%d
    ",dp[n][m]);
        }
        return 0;
    }
    至少做到我努力了
  • 相关阅读:
    六、显式锁和AQS
    五、原子操作(CAS)
    四、线程的并发工具类
    BZOJ 2176 Strange string ——最小表示法
    BZOJ 2882 工艺 ——后缀自动机 最小表示法
    Codeforces Round #401 (Div. 2)
    BZOJ 2331 [SCOI2011]地板 ——插头DP
    BZOJ 2005 [Noi2010]能量采集 ——Dirichlet积
    BZOJ 1087 [SCOI2005]互不侵犯King ——状压DP
    BZOJ 1072 [SCOI2007]排列perm ——状压DP
  • 原文地址:https://www.cnblogs.com/chensunrise/p/3730562.html
Copyright © 2011-2022 走看看