問題描述: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能得到的最大連續子序列和。
作者:何知令
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;
}
程序運行結果展示:
知識點總結:暴力。。。
學習心得:超時算法不值得拿出來,不過思想可以借鑑一二