• 要线段树资瓷区间max和询问区间和。 设要把$[L, R]$对mx取max。...然后我们假设找到了一个区间被$[L, R]$包含，那么如果这个区间的最大值小于mx，就直接修改，否则再递归进入他的子区间进行查找。 ...
要线段树资瓷区间max和询问区间和。
设要把$[L, R]$对mx取max。
我们可以在线段树上二分出小于mx的区间然后变成区间修改了。
具体实现是，维护区间最小值和区间最大值，我们递归进入一个区间，如果这个区间的最小值都大于mx的话就不用管这个区间了。
然后我们假设找到了一个区间被$[L, R]$包含，那么如果这个区间的最大值小于mx，就直接修改，否则再递归进入他的子区间进行查找。

void change(int l, int r, int o, int ql, int qr, int c)
{
if (mn[o] >= c) return ;
if (l >= ql and r <= qr)
{
if (mx[o] <= c) {
mx[o] = mn[o] = lzy[o] = c;
tr[o] = (r - l + 1) * c;
return ;
}
}
spread(o, l, r);//下放标记
int mid = (l + r) >> 1;
if (ql <= mid) change(l, mid, ls, ql, qr, c);
if (qr > mid) change(mid + 1, r, rs, ql, qr, c);
pushup(o);
}

转载于:https://www.cnblogs.com/BriMon/p/9864702.html
展开全文 • 求该区间内的最大子区间的和。 思路 暴力要搞到 O(n4)O(n^4)O(n4)。考虑一下降维和动归。 正常动归，要用到二维动态规划，可能会超时。 这里可以将每一列的前缀和算出来，即把每一列当作一个数，在确定好上下界之后...
题面：To the Max
题目大意
给定一个整数 $n$ ，代表的是方形区间的边长，之后再输入所有格子内的数。
求该区间内的最大子区间的和。
思路
暴力要搞到 $O(n^4)$。考虑一下降维和动归。
正常动归，要用到二维动态规划，可能会超时。
这里可以将每一列的前缀和算出来，即把每一列当作一个数，在确定好上下界之后，就可以用一维动归来解决这个问题了。
算法的时间复杂度就降到了 $O(n^3)$
贪心思想
在做一维动归的时候，需要一些贪心思想。
遍历到第 $k$ 个数时，如果前面 $[1,k-1]$ 个数的总和 $last\_sum\leq 0$，那么说明我们可以将这第 $k$ 个数当作一个新的区间的开始。假设还加进 $last\_sum$ 的话，此时 $last\_sum+a[k]\leq a[k]$，则这个情况一定不是最优的，所以可以摒弃 $last\_sum$。
代码
#include <bits/stdc++.h>
#define sc scanf
#define pf printf
using namespace std;
const int N = 110;
int n;
int g[N][N];

int main()
{
sc("%d", &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
sc("%d", &g[i][j]);
//这里计算每一列的前缀和
g[i][j] += g[i - 1][j];
}
int ans = INT_MIN;
//用i确定上界
for(int i = 1; i <= n; i++)
//用j确定下界
for(int j = i; j <= n; j++)
{
int last = 0;//记录已经遍历过的总和。
for(int k = 1; k <= n; k++) {
//如果last<=0，则让其等于0.
//g[j][k] - g[i-1][k] 计算的是上界 i 到下界 j的区间和
//子区间为 [i + x, i + k, j + x, j + k]
//其中 x 为last的起点，也可能为 k。
last = max(last, 0) + g[j][k] - g[i - 1][k];
ans = max(ans, last);
}
}
pf("%d\n", ans);
return 0;
}



展开全文  算法 动态规划 贪心算法
• 思路：对于此类型的题目，可以从以下几个方面分析，  1....固有状态转移方程：dp[i][j]=max(dp[i-1][j-1],dp[i][j-1])+a[j];由于m的范围没有给出所以不可开dp[m][n]的数组。那么就需要有优化的方
思路：对于此类型的题目，可以从以下几个方面分析，
1.以当前的数为切入点，只有两种情况（1）当前的数单独的新放到一个区间.（2）将其放入和j-1同个区间。那么我们可以用dp[i][j]表示在前j个数划分了i个区间。固有状态转移方程：dp[i][j]=max(dp[i-1][j-1],dp[i][j-1])+a[j];由于m的范围没有给出所以不可开dp[m][n]的数组。那么就需要有优化的方案。类似于滚动数组的优化方式，可以开两个数组分别为pre[],now[]代表前一组和当前组的数字和情况。那么当加入一个新的数时，就需要判断一下是放入前一组还是当前组所得到的解最优。同时不断更新pre[]数组。（不知为啥用%I64dWA-
-！）

#include <iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define L int
using namespace std;

L now,pre,a;

int main()
{
int n,m,i,j,k;
while(~scanf("%d%d",&m,&n))
{
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
now[i]=pre[i]=0;
}
now=pre=0;
L ma;
for(i=1; i<=m; i++)
{
ma=-0x3f3f3f3f;
for(j=i; j<=n; j++)
{
now[j]=max(now[j-1],pre[j-1])+a[j];
pre[j-1]=ma;
if(now[j]>ma)
{
ma=now[j];
}
}
// pre[j-1]=ma;
}
printf("%d\n",ma);
}
return 0;
}


展开全文  DP
• Max Sum  Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 169481 A

Max Sum
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 169481    Accepted Submission(s): 39557

Problem Description

Given a sequence a,a,a......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.

Input

The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

Output

For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence.
If there are more than one result, output the first one. Output a blank line between two cases.

Sample Input

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

Sample Output

Case 1:
14 1 4

Case 2:
7 1 6

Author

Ignatius.L

Recommend

We have carefully selected several similar problems for you:  1176 1087 1069 2084 1058

解析：求连续子区间最大和。
用f【i】表示以第 i 个数字结尾的连续子区间的最大值，则 f【i】=max{f【i-1】+a【i】，a【i】}，然后分情况处理一下起点、终点，并更新当前最优值即可。

代码：
#include<cstdio>
#define inf 1000000000
#define maxn 1000
using namespace std;

int ans,ans_l,ans_r;

void work()
{
int i,j,k,n,x,sum,l,r;
scanf("%d",&n);
ans=-inf,sum=0,l=1,r=0;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
if(sum<0)sum=x,l=r=i;
else sum+=x,r=i;

if(sum>ans)ans=sum,ans_l=l,ans_r=r;
}
printf("%d %d %d\n",ans,ans_l,ans_r);
}

int main()
{
freopen("1.in","r",stdin);
int t,i;
while(scanf("%d",&t)!=EOF)
for(i=1;i<=t;i++)
{
printf("Case %d:\n",i);
work();
if(i<t)printf("\n");
}
return 0;
}


展开全文  动态规划
• ## 最大子区间和

千次阅读 2015-10-11 20:04:09
#include "stdio.h" #include "stdlib.h" #include "math.h" ...#define N 100int MaxSum(int a[N], int n) //计算区间a[0:n-1]上最大子区间长度 { int i; int b = 0; int sum = 0; for(i=0; i
• HDU 1231 最大连续序列 &&HDU 1003Max Sum （区间dp问题） 阅读：134 时间：2015-11-21 16:30 分享： C - 最大连续序列 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64...
• 题目大意：求一个数列区间中最大的连续序列。  解题思路：这个题有三种做法，因为在学DP，所以只用了DP的做法，感觉DP很不好想，但想到了就会很简单。这个题的转移方程为：dp[i]=max(a[i],dp[i-1]+a[i]);即第i个...
• 题意：价值 = 区间和 × 区间最小值，求数组的子区间的最大价值 （1）区间和---->前缀和 （2）O(n2) 枚举区间 —> O( n ) 枚举元素，根据当前元素查询相应区间和 对每个元素，维护他作为最小值的左右端点，...
• http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 294367 Accepted Submission(s): 6989...
• int a,i,b,t; for(i=0;i<10;i++) scanf("%d",&a[i]);...b[i]=max(b[i-1]+a[i],a[i]); 再用选择排序法求数组b 的最大值 转载于:https://www.cnblogs.com/woyaocheng/p/4638054.htm...
• dp[i]表示以in[i]结尾的最大子区间和，则dp[i]=max(0,dp[i-1])+in[i];然后比较dp[1...n]找到最大值 这道题的难点在于找到首尾的位置 1 #include<iostream> 2 #include<string.h> 3 #include<...
• 维护2个双端队列A，B。...窗口扩张后，当前窗口的max只会比之前窗口的max大，min比之前窗口的min小。 那这时就可以求出窗口左边以第一位置开始的valid窗口的个数，就是窗口的宽度 接着左边从第一位移到第二
• Problem Description ... Given a sequence a,a,a......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1...
• 题意：n个数，分成m片区间Max为m片区间中的最大区间区间元素和最大），求Max的最小值 思路：二分枚举一个最大值，每次判断从前往后是否可以分成m份（如果分成小于m份也可以把一个区间拆成多个区间，所以&...
• 最大连续子区间（和） ans = lst = 0; for(i = 0; i < n; ++i){ lst = max(0, lst) + a[i]; //lst = max(lst+a[i], a[i]); ans = max(ans, lst); }
• 题目大意：给定一整型数列{a1,a2...,an}，找出连续非空子串{ax,ax+1,...,ay}，使得该序列的和最大，其中，1 思路：m是元素总个数，sum是第一个元素，将当前的第一个元素作为最大值max,之后依次输入，检查sum 代码...
• 不熟练的原因是理解的不够深…… ...#define MAX(a, b) ((a)>(b)?(a):(b)) int num = {-1, 2, 5, -4, 3, 0, -1, 3, 6, -10}; int n = 10; int func1(){ int i; int max = 0x80000000, sum = 0;
• 问题：问题1 的代码实现：#coding:utf-8#py2.7def findmaxsubstr(nums):bufs={}for i,num in enumerate(nums):if i==0:bufs[i]=numelse:bufs[i]=bufs[i-1]+num if...=0 else numprint bufsb=max([(bufs[i],i) for i ...
• 给定一个序列a，a，a…a[n]，你的工作是计算序列的最大和。例如，给定(6，-1,5,4，-7)，这个序列中的最大和是6 +(-1)+ 5 + 4 = 14。 输入 输入的第一行包含一个整数T(1<=T<=20)，这意味着测试用例... 算法
• dp(i+1)=max(num[i+1], num[i+1]+dp(i)); dpi表示以第i元素结尾的最大区间和。 #include<iostream> using namespace std; int main() { int n; cin>>n; int* a=new int[n+1]; a=0; for(int ...
• #include #include //小白窝不讲题hhh int num=1; int start,end; int dp;...int max(int m,int n) { if(m>=n) return m; else return n; } int SQRT(int n) //求2的n次方 { int t=n%2; RMQ c语言 动态规划 数据结构
• 题目一描述： 给定一个整数数组 nums ，找到一个具有最大和的连续数组（...动态规划： dp[i]=Math.max(dp[i-1]+nums[i],nums[i]) 贪心法： 分治法： 最优解：动态规划 代码： /** * @param {number[]} nums * @re 算法 数据结构
• 求一个数组的连续数组的最大值（以及区间） package suanfa.impover; /** * 求一个数组的连续数组的最大值（以及区间） */ import java.util.Arrays; public class SubArrayMaxSum { // 暴力破解，O(n2)...
• 区间最大连续字段 线段树多维护三个值:当前区间从左端开始最大连续和cl，从右端开始最大连续和...m等于max(左子区间m，右子区间m，左子区间cr+右子区间cl) 查询时返回区间段并不断合并。 struct node { int s,c...
• 原题链接：http://acm.hdu.edu.cn/showproblem.php?pid=1003本题使用递归分治求解最大序列问题。# include # include<malloc.h>typedef struct{ int left;... int maxsum;//区间最大和 }Sum;Sum m
• 求一段区间的最优解，该区间的最优解可以由其子区间的最优解推导而来，类似分治思想。 令状态f(i,j)表示将下标位置 i 到 j 的所有元素合并能获得的价值的最大值，那么 f(i,j) = max{f(i,k) + f(k+1, j) + cost}, k∈...
• 方程是：f[i][j]=max(f[i][j],f[i-1][k]+a[i][j-k]);我们要去枚举每一个i和j，因此用双重循环来解决，k表示第i个公司取的不取机器数，即1~i-1个公司取的机器数；f[i-1][k]表示前i-1个公司取k台机器的最大值，a[i][j-...
• 题目翻译：给出N个数字，Q个操作，如果输入操作类型是a,则【L,R】...一个区间，其两个子区间依据边界值对 两个区间进行合并。 Max数组维护任意一个区间的最长连续子序列长度。 lnum数组保存一个区间左边界的数  ...