hdu 5280 贪心 O(n)算法

题意给你一个序列A[1...N],你必须修改一个A[i]为P,使得修改后的序列A的连续最大和最大

其中N<=1000

分析,N非常小,N^2暴力随便做,不细讲

说一个O(N)的算法

我们知道O(N)的求连续最大和的算法

那么定义L[i], R[i]分别为L[i]以i为结尾的最大连续和,R[i]一i为开头的连续最大和

由于必须要修改一个A[i]为P,这个修改后的A[i]可能不包含在连续最大和中,也可能包含在连续最大和中

如果包含,那么就等价于:max(L[i - 1], 0) + max(R[i + 1], 0) + P

如果不包含,那么就计算1...n-1的最大L[i], 2...n的最大的R[i]

 1 #include <set>
 2 #include <map>
 3 #include <queue>
 4 #include <deque>
 5 #include <cmath>
 6 #include <vector>
 7 #include <string>
 8 #include <cstdio>
 9 #include <cstdlib>
10 #include <cstring>
11 #include <cassert>
12 #include <iostream>
13 #include <algorithm>
14
15 #define dprint(expr) fprintf(stderr, #expr " = %d\n", expr)
16
17 using namespace std;
18
19 typedef long long LL;
20 typedef pair <int, int> PII;
21
22 const int N = 1e5 + 7;
23 const int INF = 0x3f3f3f3f;
24 const int MOD = 1e9 + 7;
25 const double EPS = 1e-6;
26 const double PI = acos(-1.0);
27
28 int a[N];
29 LL l[N], r[N];
30
31 int main(void){
32     int T;
33     scanf("%d", &T);
34     while (T--) {
35         int n, p;
36         scanf("%d%d", &n, &p);
37         for (int i = 1; i <= n; ++i)
38             scanf("%d", &a[i]);
39         l[0] = r[0] = l[n + 1] = r[n + 1] = 0;
40         for (int i = 1; i <= n; ++i)
41             l[i] = max(l[i - 1] + a[i], (LL)a[i]);
42         for (int i = n; i; --i)
43             r[i] = max(r[i + 1] + a[i], (LL)a[i]);
44         LL ans = -INF;
45         for (int i = 1; i <= n; ++i) {
46             ans = max(ans, max(l[i - 1], 0LL) + max(r[i + 1], 0LL) + p);
47         }
48         for (int i = 1; i < n; ++i) {
49             ans = max(ans, l[i]);
50         }
51         for (int i = n; i > 1; --i) {
52             ans = max(ans, r[i]);
53         }
54         printf("%I64d\n", ans);
55     }
56     return 0;
57 }
时间: 2024-11-08 14:34:09

hdu 5280 贪心 O(n)算法的相关文章

hdu 1050(贪心算法)

Moving Tables Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 19278    Accepted Submission(s): 6582 Problem Description The famous ACM (Advanced Computer Maker) Company has rented a floor of a

HDU 4864 Task(基本算法-贪心)

Task Problem Description Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this task has a difficulty level yi. The machine whose level below this task's level yi cannot complete this task. If the company

hdu 5280 Senior&#39;s Array

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5280 Senior's Array Description One day, Xuejiejie gets an array $A$. Among all non-empty intervals of $A$, she wants to find the most beautiful one. She defines the beauty as the sum of the interval. Th

HDU 4007 Dave (基本算法-水题)

Dave Problem Description Recently, Dave is boring, so he often walks around. He finds that some places are too crowded, for example, the ground. He couldn't help to think of the disasters happening recently. Crowded place is not safe. He knows there

hdu 4105 贪心思想

淋漓尽致的贪心思想 波谷一定是一位数,波峰一位数不够大的时候添加到两位数就一定够大了的. 当在寻找波谷碰到零了就自然当成波谷. 当在寻找波峰时碰到零时,将前面的波谷加到前一个波峰上,让当前的零做波谷,使得波谷的值尽量小,这就是本题最关键的贪心思想,一直想不到. 代码中:a表示前一个值,b表示当前考虑的值,tag为偶数时表示正在寻找波谷,奇数时在寻找波峰. #include<iostream> #include<cstdio> #include<cstring> #inc

hdu 1269 迷宫城堡(Targin算法)

---恢复内容开始--- 迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Swwubmission(s): 10884    Accepted Submission(s): 4878 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单

HDU 4923 (贪心+证明)

Room and Moor Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. In order to beat him, programmer Moor has to construct another sequence B = {B1, B2,... , BN} of the same length, which satisfies that:

hdu 2037 贪心

今年暑假不AC Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 27361    Accepted Submission(s): 14439 Problem Description "今年暑假不AC?" "是的." "那你干什么呢?" "看世界杯呀,笨蛋!" &quo

hdu 5280 Senior&#39;s Array(最大子段和)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5280 题意:将一个长度为n的数组,将里面某一个数改为p,使改变后最大子段和最大. 题解:dp[i]=max(dp[i-1)+a[i],a[i]),表示以第 i 个数结束的最大子段和,时间复杂度为O(n). 1)由于n<=1000,可以暴力解决,将每一个数都依次改为p,求出最大的子段和,再去这些最大子段和中最大的,时间复杂度为O(n*n); #include <iostream> #inclu