zoukankan      html  css  js  c++  java
  • LETTers第五场Sleeping 解题报告

    题目描述:

        一节课有n分钟,ZZZ每听一分钟课都能得到一定的分数,一旦她开始听课就必须要至少连续听l分钟,但是她每节课都要有m分钟的睡眠时间(这m分钟不连续),问在不影响她睡觉的情况下, 她一节课最多能得多少分。。。

    题面建模:

        dp。

     首先dp[i][j]表示前i分钟有j分钟是睡觉时间, 如果第i分钟睡觉dp[i][j]=dp[i-1][j-1];

       第i分钟学习的话: dp[i][j]=max(dp[k][j]+score[i]-score[k]) (1<=k<=i-l)。 score[i]表示前i分钟的分数之和。

    解题要点:

       注意边界的处理和dp数组的初始化,开始的时候应将dp[i][j]=0。

       另外就是求dp[i][j]时如果将k从1到i-l遍历会超时,需要一个memory数组,记录这里求出的最大值,那么转移方程改写为:

       dp[i][j]=Max(mem[i-1][j]+score[i]-score[i-1],dp[i-l][j]+score[i]-score[i-l]);

    时空开销分析:

    空间复杂度:O(n^2)。

    时间复杂度:O(n^2)。

    特别说明:

    无。

    程序:

    #include <stdio.h>
    #include <string.h>
    int score[1010];
    int mem[1010][1010];
    int dp[1010][1010];
    int Max(int a,int b)
    {
        return a>b?a:b;
    }
    int main()
    {
        int n,m,l,i,j;
        while(scanf("%d %d %d",&n,&m,&l)!=EOF)
        {
            memset(score,0,sizeof(score));
            memset(dp,0,sizeof(dp));
            memset(mem,0,sizeof(mem));
            for(i=1;i<=n;i++)
            {
                scanf("%d",score+i);
                score[i]+=score[i-1];
            }
            for(i=1;i<=n;i++)
                for(j=0;j<=m;j++)
                {
                    if(i>=l+j)
                        dp[i][j]=Max(mem[i-1][j]+score[i]-score[i-1],dp[i-l][j]+score[i]-score[i-l]);
                     mem[i][j]=dp[i][j];
                    if(j>=1)
                        dp[i][j]=Max(dp[i][j],dp[i-1][j-1]);
                }
            printf("%d\n",dp[n][m]);
        }
        return 1;
    }
  • 相关阅读:
    多线程
    Java命令行传参
    IO流
    集合
    Java基础语法
    常见的数据结构
    泛型
    java 集合重要概念 (Set 的存储内存解析)
    java 集合重要概念 (== 和 equals 解读)
    java 集合重要概念 (实现一个简单的斗地主)
  • 原文地址:https://www.cnblogs.com/LETTers/p/2461108.html
Copyright © 2011-2022 走看看