HDOJ 3415 Max Sum of Max-K-sub-sequence(线段树优化DP)
来源:互联网 发布:js date format 函数 编辑:程序博客网 时间:2024/06/06 00:03
题意
给出一个环,求连续的k个数字中连续和最大是是多少,子串的开始下标和结束坐标是多少。
思路
第一次做这题的时候是在学单调队列的时候,单调队列的做法戳这里
这里我是直接dp搞,
显然直接做复杂度O(nk)是超时的,就用线段树维护一下min(sum[j])就行了。
我在找ansl的时候用lower_bound在sum里面找min(sum[j])的下标不知道为什么WA= =。。后来改成在外面遍历一遍[ansr - k + 1,ansr]才没有WA,然后TLE了。。。我刚开始是每做到一个数就update进去这个i,然后改成直接建树的时候就PushUp了不再update就过了。
代码
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <set>#include <map>#include <string>#include <math.h>#include <stdlib.h>#include <time.h>using namespace std;#define LL long long#define Lowbit(x) ((x)&(-x))#define lson l, mid, rt << 1#define rson mid + 1, r, rt << 1|1#define MP(a, b) make_pair(a, b)const int INF = 0x3f3f3f3f;const int MOD = 1000000007;const int maxn = 1e5 + 10;const double eps = 1e-8;const double PI = acos(-1.0);typedef pair<int, int> pii;int a[maxn*2], sum[maxn*2];int mmin[(maxn*2)<<2];inline void PushUp(int rt){ mmin[rt] = min(mmin[rt<<1], mmin[rt<<1|1]);}void build(int l, int r, int rt){ if (l == r) { mmin[rt] = sum[l]; return ; } int mid = (l + r) >> 1; build(lson); build(rson); PushUp(rt);}inline void update(int pos, int val, int l, int r, int rt){ if (pos <= l && r <= pos) { mmin[rt] = val; return ; } int mid = (l + r) >> 1; if (pos <= mid) update(pos, val, lson); if (pos > mid) update(pos, val, rson); PushUp(rt);}inline int query(int L, int R, int l, int r, int rt){ if (L <= l && r <= R) { return mmin[rt]; } int mid = (l + r) >> 1; int res = INF; if (L <= mid) res = min(res, query(L, R, lson)); if (R > mid) res = min(res, query(L, R, rson)); return res;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n, k, T; scanf("%d", &T); while (T--){ //T是后加的所以格式丑了点= = scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) scanf("%d", &a[i]), a[i+n] = a[i]; n <<= 1; memset(sum, 0x3f, sizeof(sum)); memset(mmin, 0x3f, sizeof(mmin)); sum[0] = 0; for (int i = 1; i <= n; i++) sum[i] = sum[i-1] + a[i]; build(1, n, 1); int ans = sum[1], ansl = 1, ansr = 1; for (int i = 2; i <= n; i++) { if (i - k <= 0 && sum[i] - sum[0] > ans) { ans = sum[i] - sum[0]; ansl = 1; ansr = i; } int l = max(i - k, 1), r = i - 1; int minval = query(l, r, 1, n, 1); //printf("%d %d %d %d\n", l, r+1, minval, sum[i] - minval); if (sum[i] - minval > ans) { ans = sum[i] - minval; ansr = i; } } for (int i = max(ansr - k + 1, 1); i <= ansr; i++) if (sum[ansr] - sum[i-1] == ans) { ansl = i; break; } if (ansl % (n >> 1) == 0) ansl = (n >> 1); else ansl %= (n >> 1); if (ansr % (n >> 1) == 0) ansr = (n >> 1); else ansr %= (n >> 1); printf("%d %d %d\n", ans, ansl, ansr);} return 0;}
0 0
- HDOJ 3415 Max Sum of Max-K-sub-sequence(线段树优化DP)
- POJ 3415 Max Sum of Max-K-sub-sequence (线段树+dp思想)
- HDOJ 3415 Max Sum of Max-K-sub-sequence
- hdoj 3415 Max Sum of Max-K-sub-sequence(单调队列+dp)
- HDU 3415 Max Sum of Max-K-sub-sequence[单调队列优化dp]
- HDU 3415(Max Sum of Max-K-sub-sequence-单调队列优化DP)
- HDU 3415 Max Sum of Max-K-sub-sequence - dp&单调队列优化
- DP单调队列:Max Sum of Max-K-sub-sequence
- Max Sum of Max-K-sub-sequence
- Max Sum of Max-K-sub-sequence
- hdu Max Sum of Max-K-sub-sequence 单调队列优化DP
- hdu 3415 Max Sum of Max-K-sub-sequence
- hdu 3415 Max Sum of Max-K-sub-sequence
- hduoj 3415 Max Sum of Max-K-sub-sequence
- hdu 3415 Max Sum of Max-K-sub-sequence题解
- hdu 3415 Max Sum of Max-K-sub-sequence
- hdu 3415 Max Sum of Max-K-sub-sequence
- HDU 3415 Max Sum of Max-K-sub-sequence
- 数据库--Orcal--day04
- Java基础部分
- FleaPHP的单入口文件详解
- Android源码解析(二十四)-->onSaveInstanceState执行时机
- 霍夫曼编码
- HDOJ 3415 Max Sum of Max-K-sub-sequence(线段树优化DP)
- mavlink的Java语言之探索实现
- POJ 1987Distance Statistics 树的分治
- Linux中如何添加/删除FTP用户并设置权限(后续)
- Mysql 总结(一)
- HuaXinIM聊项目阶段总结六(获取历史信息实现)
- JDK里的设计模式
- android 类型
- 20非常有用的Java程序片段