最大连续子序列之和

问题描述:Leyni得到了一个长度为n的序列,XianGe要求Leyni最多可以修改其中k个元素,每次修改的规则是只能将一个数字修改为其相反数。
Leyni想知道在修改后,他能得到的所有长度为len的连续子序列中,最大的(子序列和的绝对值)为多少?
Input
输入包含多组测试数据。
对于每组测试数据:
第1行,包含二个整数n, len (1 ≤ n, len ≤ 105)代表着序列的长度和子序列的长度限制。
第2行,包含n个由空格分隔的整数,每个元素的范围为[-109, 109],代表着Leyni得到的序列。
第3行,包含一个整数k (0 ≤ k ≤ n),表示允许修改的最大次数。
处理到文件结束。
Output
对于每组测试数据:
第1行,输出Leyni能得到的最大连续子序列和。
作者:何知令

完成时间:2017年8月22日

解题思想:这个与原始的最长子序列有较大差距,主要考虑如何转换相反数使其子段和最大,该种解法是超时的还需要改进。核心思想是将子段中最小且是负数的数变为它的相反数(即正数),这样得到的子段之和是最大的

代码如下:

/*
问题描述:Leyni得到了一个长度为n的序列,XianGe要求Leyni最多可以修改其中k个元素,每次修改的规则是只能将一个数字修改为其相反数。
Leyni想知道在修改后,他能得到的所有长度为len的连续子序列中,最大的(子序列和的绝对值)为多少?
Input
输入包含多组测试数据。
对于每组测试数据:
第1行,包含二个整数n, len (1 ≤ n, len ≤ 105)代表着序列的长度和子序列的长度限制。
第2行,包含n个由空格分隔的整数,每个元素的范围为[-109, 109],代表着Leyni得到的序列。
第3行,包含一个整数k (0 ≤ k ≤ n),表示允许修改的最大次数。
处理到文件结束。
Output
对于每组测试数据:
第1行,输出Leyni能得到的最大连续子序列和。
作者:何知令
完成时间:2017年8月22日
*/
#include <stdio.h>
#include <stdlib.h>
int n,len,m;//n为母序列长度,len为子序列最大长度,m为允许修改的最大次数
int oppNum(int s[],int len)
{
    int minplace;
    int min=32767;
    int sum=0;
    int negnum=0;//该子序列中负数的数量
    int time=m;//允许修改的次数
    int i;
    for(i=0; i<len; i++)
        if(s[i]<0)
            negnum++;
    while(negnum&&time)//筛选出最小的数,如果为负数将其改为正数
    {
        for(i=0; i<len; i++)//寻找数组中最小那个数
            if(s[i]<min)
            {
                min=s[i];
                minplace=i;
            }
        if(s[minplace]<0)
            s[minplace]=-s[minplace];
        min=32767;
        negnum--;
        time--;
    }
    for(i=0; i<len; i++)
        if(s[i]>0)
            sum+=s[i];
    return sum;
}
int main()
{
    int f[100000],s[100000];
    int i;
    int max=0,num;
    while(~scanf("%d %d",&n,&len))
    {
        for(i=0; i<n; i++)
            scanf("%d",&f[i]);
        scanf("%d",&m);
        for(i=0; i<n-2; i++)
        {
            s[0]=f[i];
            s[1]=f[i+1];
            s[2]=f[i+2];
            num=oppNum(s,len);
            if(num>max)
                max=num;
        }
        printf("%d\n",max);
    }
    return 0;
}
程序运行结果展示:

知识点总结:暴力。。。

学习心得:超时算法不值得拿出来,不过思想可以借鉴一二

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值