sjtu oj 1250 最大连续子序列问题变形

这道题目不知道是因为做的人少还是什么原因,pass率很低,我在去图书馆的路上忽然想起这道题目和最大连续子序列其实是一个问题,但是更难,更挑剔!

1250. BestSubsequence

Description

LL有n个妹子,他给妹子们编号排成一排。据说今天天气大好,LL要去春游了,他决定要选定至少F个妹子一起去玩。 为了让妹子们开心,他决定选连续一段的妹子们。然后LL有个特殊的癖好,他喜欢体重比较厉害一些的妹子。

那你可以帮LL选妹子吗,使得选出来的这些妹子的平均体重最大。

Input Format

输入第一行两个整数,n和F。

接下来n行,每行一个整数,表示妹子的体重。

对前50%的数据:1<=n<=20。 对100%的数据:1<=n<=100000, 1<=F<=n, 1<=妹子体重<=2000。

Output Format

输出一个整数,为这个平均值乘以1000,不要四舍五入,输出int(avergae * 1000)即可。

Sample Input

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

Sample Output

6500

题目显得很二逼,忽略这些,我们需要找出连续的子序列其平均值最大,且子序列的长度应该大于F,我们从归纳的角度去想这个问题,如果我们已知前n个人中平均值最大的这个序列,那么对于n+1,这个问题如何求解?

显然如果这个最大序列刚好以n为尾巴,那么n+1如果能够增大这个序列的平均体重,就把n+1加上去形成一个新的最大序列,问题是如果其不以n为结尾呢?此时可能存在一个以n结尾的后缀序列,它虽然不是前n个的最大序列,但是能够和n+1形成一个比当前最大序列更大的新序列,基于这点,我们提出更强的假设:

假设我们已知前n个值的最大序列和最大后缀序列,则只要比较n+1和最大后缀序列是否能够组成比前n个值的最大序列更大的解!

由于我们使用了更强的假设,即P&&Q,所以在求解的时候需要同时更新最大序列和后缀序列的最大值,否则归纳错误。

#include <iostream>
using namespace std;
int main()
{
    int nums,least_num;
    int global_max=0,suffix_max=0;
    int global_num,suffix_num;
    cin>>nums>>least_num;
    int *pounds=new int[nums];
    for(int i=0;i<nums;i++)
    {
        cin>>pounds[i];
    }
    for(int j=0;j<least_num;j++)
    {
        global_max+=pounds[j];
    }
    int tp=global_max-pounds[0];
    if(least_num==1)
    {
        int max=-1;
        for(int i=0;i<nums;i++)
        {
            if(max<pounds[i])
            {
                max=pounds[i];
            }
        }
        cout<<max*1000<<endl;
        return 0;
    }
    suffix_max=(global_max*1.0/least_num>(global_max-pounds[0])*1.0/(least_num-1))?global_max:(global_max-pounds[0]);
    global_num=least_num;
    suffix_num=(global_max>suffix_max)?(least_num-1):least_num;
    for(int j=least_num;j<nums;j++)
    {
        if((pounds[j]+suffix_max)*1.0/(suffix_num+1)>(global_max*1.0/global_num))
        {
            global_max=pounds[j]+suffix_max;
            global_num=suffix_num+1;
        }
        tp=tp+pounds[j]-pounds[j-least_num+1];
        if(tp*1.0/(least_num-1)>(suffix_max+pounds[j])*1.0/(suffix_num+1))
        {
            suffix_max=tp;
            suffix_num=least_num-1;
        }
        else
        {
            suffix_max+=pounds[j];
            suffix_num++;
        }
    }
    int ans=(global_max*1.0/global_num)*1000;
    cout<<ans<<endl;
}

这里需要注意的是如何更新suffix_max,这需要大家去思考,另外有一些小细节也很影响速度,整个过程也是几经修改pass,但思想是不变的,归纳非常强大!

时间: 2024-08-05 06:48:18

sjtu oj 1250 最大连续子序列问题变形的相关文章

【算法学习笔记】52.一道题的三种方法..二分答案、动态规划、计算几何 SJTU OJ 1250 BestSubsequence

---恢复内容开始--- 1250. BestSubsequence Description LL有n个妹子,他给妹子们编号排成一排.据说今天天气大好,LL要去春游了,他决定要选定至少F个妹子一起去玩. 为了让妹子们开心,他决定选连续一段的妹子们.然后LL有个特殊的癖好,他喜欢体重比较厉害一些的妹子. 那你可以帮LL选妹子吗,使得选出来的这些妹子的平均体重最大. Input Format 输入第一行两个整数,n和F. 接下来n行,每行一个整数,表示妹子的体重. 对前50%的数据:1<=n<=2

[HDOJ 1003]动态规划法求和最大的连续子序列

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1003 Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5

最大连续子序列和

对于给定的数组 numnum,一个长度为 ss 的连续子序列是指由 num_i,num_{i+1},num_{i+2}\ldots,num_{i+s-1}num?i??,num?i+1??,num?i+2??…,num?i+s−1?? 组成的序列.数组中的元素有可能为正数.负数或 00.你需要从数组中找出元素总和最大的一个连续子序列. 比如,对于数组 1,-3,2,6,-5,81,−3,2,6,−5,8,其最大连续子序列之和是 2+6-5+8=112+6−5+8=11. 对于一段区间内的最大连续

hdu1231 最大连续子序列

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 22849    Accepted Submission(s): 10135 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j

dp-最大连续子序列的和

什么是最大连续子序列和呢 ? 最大连续子序列和是所有子序列中元素和最大的一个 . 问题 : 给定一个序列 { -2, 11, -4, 13, -5, -2 } , 则最大连续子序列和为 20 , 即 { 11 , -4 , 13 } . 分析 : 要怎样去解决这个问题呢 ? 设出 两个变量 , 一个 ans 用来存放最终的结果 , 一个用来现在对元素进行加和 , 每当有最大的和则更形下 ans . 代码示例 : #include <iostream> #include <cstring&

HDU1231 最长连续子序列

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 31687    Accepted Submission(s): 14214 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j

动态规划:最大连续子序列和

问题:给出一个数组,求其连续子序列的最大和 package 动态规划; /** * 给出一个数组,求其连续子数组的最大和 * @author Administrator * */ public class MaxSum { public static void main(String[] args) { int[] arr = new int[]{-3,1,-3,4,-1,2,1}; int max=arr[0]; int current=arr[0]; for(int i=1;i<arr.le

UVa 108 - Maximum Sum(最大连续子序列)

题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=44  Maximum Sum  Background A problem that is simple to solve in one dimension is often much more difficult to solve in more th

[pythontip]最大非连续子序列

题目链接:http://www.pythontip.com/coding/code_oj_case/36给你一个整数list L, 如 L=[2,-3,3,50], 求L的一个非连续子序列,使其和最大,输出最大子序列的和. 这里非连续子序列的定义是,子序列中任意相邻的两个数在原序列里都不相邻. 例如,对于L=[2,-3,3,50], 输出52(分析:很明显,该列表最大非连续子序列为[2,50]). dp首先复制L序列的元素,然后比较前两个元素,确定最优解赋值给dp[1]. 1 # L=[2,-3