NYOJ 873 环之最大和

来源:互联网 发布:表白楼宇生成器软件 编辑:程序博客网 时间:2024/06/02 01:59

题目意思很简单  就是让你从n个数字中选取m个连续的数字使和最大  就是这样没错  因为是环状的 所以可以从末尾连到最开始 

PS: 如果你觉得写得一定没有错 但还是wa   你可能忽略了 long long 没错 恭喜你!!!(还要注意最后 MOD   n)

方法一 :  可以用前缀和 遍历一遍得到最大值和边界问题 





#include <iostream>#include <algorithm>#include <cstring>using namespace std;const int maxn = 3000;int main(){int n, m, arr[maxn];long long pres[maxn];while (cin >> n >> m) {memset(pres , 0, sizeof(pres));for (int i = 1; i <= n; i ++) {cin >> arr[i];pres[i] = pres[i - 1] + arr[i];}for (int i = n + 1; i <= n + m; i ++) {arr[i] = arr[i - n];pres[i] = pres[i - 1] + arr[i];}//for (int i = 1; i <= n + m - 1; i ++) {//cout << arr[i] << " ";//}cout << endl;//for(int i = 1; i <= n + m - 1; i ++) {//cout << pres[i] << " ";//}int head , tail;long long ans = -999999;for (int i = m; i <= n + m; i ++) {if(pres[i] - pres[i - m ] > ans) {ans = pres[i] - pres[i - m ];head = i - m + 1;tail = i;}}if(head > n)head %= n;if(tail > n)tail %= n;cout << ans << " " << head << " " << tail << endl;}} 


方法二 是这样的  可以用尺取法  维护两个伪指针 和 中间变量来得到最大值  这样的好处在于 如果数组特别特别大   前缀和无法保存的时候  而且也比前缀和的方法更快





#include <iostream>using namespace std;const int maxn = 3000;int main(){int n, m, arr[3000];while (cin >> n >> m) {for (int i = 1 ;i <= n; i ++) {cin >> arr[i];}for (int i = n + 1; i <= n + m - 1; i ++) {arr[i] = arr[i - n];}int head = 1, tail = m;long long ans = -999999;long long temp = 0;for (int i = 1; i <= m; i ++) temp += arr[i];ans = temp;int l = head;int r = tail;for (int i = 1; i < n; i ++) {temp += arr[++r];temp -= arr[l++];if( temp > ans ) {ans = temp;head = l;tail = r;}}if(head > n)head %= n;if(tail > n)tail %= n;cout << ans << " " << head << " " << tail << endl;}}

没错我把两种方法对应反了  你以为我是不小心的??  笑话 我怎么可能没发现  我就是故意的  就是这么傲娇

原创粉丝点击