• 选择数字(codevs 3327)


    题目描述 Description

    给定一行n个非负整数a[1]..a[n]。现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择。你的任务是使得选出的数字的和最大。

    输入描述 Input Description

    第一行两个整数n,k

    以下n行,每行一个整数表示a[i]。

    输出描述 Output Description

    输出一个值表示答案。

    样例输入 Sample Input

    5 2

    1

    2

    3

    4

    样例输出 Sample Output

    12

    数据范围及提示 Data Size & Hint

    对于20%的数据,n <= 10

    对于另外20%的数据, k = 1

    对于60%的数据,n <= 1000

    对于100%的数据,1 <= n <= 100000,1 <= k <= n,

                      0 <= 数字大小 <= 1,000,000,000

    /*
      设f[i]为取前i件物品的最大价值,因为不能连续取k件,所以f[i]的状态可由j∈[i-k+1,i]转移来。直接写暴力的DP会超时,由于i的状态与i-k及之前的没有关系了,所以可以用单调队列优化。 
    */
    #include<cstdio>
    #include<iostream>
    #define M 100010
    #define ll long long
    using namespace std;
    ll sum[M],f[M],d[M],q[M];
    int n,k,head=0,tail=1;
    void put(int j)
    {
        d[j]=f[j-1]-sum[j];
        if(j>=k+1&&d[j-k-1]==q[head])head++;
        while(head<tail&&d[j]>q[tail-1])tail--;
        q[tail++]=d[j];
    }
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            ll x;cin>>x;
            sum[i]=sum[i-1]+x;
        }
        for(int i=1;i<=n;i++)
        {
            put(i);
            f[i]=q[head]+sum[i];
        }
        cout<<f[n];
        return 0;
    }
    View Code
  • 相关阅读:
    待整理
    字符编码 【ZZ】
    python中的数据类型,存储,实现
    python中的浅拷贝和深拷贝
    算法比较-SVM和logistic回归
    机器学习中的范数规则化之(一)L0、L1与L2范数
    全排列的编码和解码----康托编码
    C++的const类成员函数
    Trie树的简单描述(需后续总结)
    UWP 手绘视频创作工具技术分享系列
  • 原文地址:https://www.cnblogs.com/harden/p/5827674.html
Copyright © 2020-2023  润新知