zoukankan      html  css  js  c++  java
  • 选择数字

    题目描述

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

    输入输出格式

    输入格式:

    第一行两个整数n,k

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

    输出格式:

    输出一个值表示答案。

    输入输出样例

    输入样例#1:
    5 2
    1
    2
    3
    4
    5 
    
    输出样例#1:
    12

    说明

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

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

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

    对于100%的数据,1 <= n <= 100000,1 <= k <= n,0 <= 数字大小 <= 1,000,000,000

    时间限制500ms

    动归 设f[i]为取前i件物品的最大价值,因为不能连续取k件,所以f[i]的状态可由j∈[i-k+1,i]转移来。

    f[i]=max(f[j]+sum[i]-sum[j+1],f[j-1]+sum[i]-sum[j])

    =max(f[j]-sum[j+1],f[j-1]-sum[j])+sum[i]

    维护一个单调队列就行了

    复杂度O(n)

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 int n,k;
     7 long long sum[100001],f[100001];
     8 long long q[100001],d[100001];
     9 int head,tail=1;
    10 int main()
    11 {
    12     int i,j;
    13     cin>>n>>k;
    14     for (i=1; i<=n; i++)
    15     {
    16         scanf("%lld",&sum[i]);
    17         sum[i]+=sum[i-1];
    18     }
    19     head=0;tail=1;
    20     for (i=1; i<=n; i++)
    21     {
    22         d[i]=f[i-1]-sum[i];
    23         if  (i>=k+1&&d[i-k-1]==q[head]) head++;
    24         while (head<tail&&d[i]>q[tail-1]) tail--;
    25         q[tail++]=d[i];
    26         f[i]=q[head]+sum[i];
    27     }
    28     cout<<f[n];
    29 }
  • 相关阅读:
    数据处理之PostgreSQL过程语言学习
    Thinkphp中的assign() 和 display()
    JS截取与分割字符串常用技巧总结
    三种JS截取字符串方法
    十大经典排序算法的JS版
    js时间与毫秒互相转换
    javascript--清除表单缓存
    JS join()和split()方法、reverse() 方法、sort()方法
    JS数组去重的几种常见方法
    CSS样式大全
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/7231397.html
Copyright © 2011-2022 走看看