原题链接:https://codeforces.ml/contest/1389/problem/B
我连B题都能WA,菜得真实,难受
(一打就掉分)==》(不打==上分)
题目大意:
给出一个n个数的数组,从第一个位置开始,可以向左或向右移动一个位置,把每次移动到的位置的数累加起来(把第一个数也加进去),不能连续向左移动两次,现要求刚好移动k次,最多向左移动z次时所累加得到的和的最大值,k<=n-1,z<=min(5,k)
思路:
不向左移动的话,最远到达第k+1个位置,每向左一次,能到达的位置向前推两格
所求的最大值一定是在某处反复横跳的结果
求后缀和,在某处横跳的结果为前k+1个数的和 - 少掉的后缀部分的和 + 横跳处相邻两个数的和 * 横跳次数
在所有结果中取个最大值即可
代码:
扫描二维码关注公众号,回复:
11474544 查看本文章
1 #define _USE_MATH_DEFINES 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <string> 6 #include <math.h> 7 #include <ctype.h> 8 #include <vector> 9 #include <stack> 10 #include <map> 11 #include <set> 12 #include <algorithm> 13 #include <iostream> 14 #include <limits.h> 15 #include <iomanip> 16 #include <queue> 17 #include <functional> 18 #define el '\n' 19 #define M 200005 20 const long long N = 1e9+7; 21 #define ll long long 22 using namespace std; 23 24 int a[100005]; 25 int back[10]; 26 int main() 27 { 28 ios::sync_with_stdio(false); 29 cin.tie(0); 30 cout.tie(0); 31 32 //freopen("test14.in","r",stdin); 33 //freopen("test14.out","w",stdout); 34 int t; 35 cin>>t; 36 while(t--){ 37 int n,k,z; 38 int sum=0; 39 cin>>n>>k>>z; 40 k++; 41 for(int i=1;i<=n;i++){ 42 cin>>a[i]; 43 if(i<=k){ 44 sum+=a[i]; 45 } 46 } 47 memset(back,0,sizeof(back)); 48 for(int i=0;i<z;i++){ 49 if(k-1-2*i>=1)back[i+1]=back[i]+a[k-1-2*i]+a[k-2*i]; 50 } 51 int max=sum; 52 int tmp; 53 for(int i=1;i<=k-2;i++){ 54 for(int j=1;j<=z;j++){ 55 if(i<=k-j*2){ 56 tmp=sum-back[j]+(a[i]+a[i+1])*j; 57 } 58 max=std::max(max,tmp); 59 } 60 } 61 cout<<max<<el; 62 } 63 return 0; 64 }
做的时候犯了极其低级的错误,太丢人了,没脸说出来
下一场干回来