当前位置: 首页 > 编程日记 > 正文

OI基础系列之最大子数组问题

OI基础系列之最大子数组问题  

——Edward2414
    oi退役了,虽然没取得多少成绩,也算是走过一会的人了。我相信绝大多数oi党都是自学成才,在此,我感谢那些把自己所学写到博客里的前辈们,没有你们,我不可能学到那么多的知识。所以,从今天起,我也会将自己的一些所学所得写下来,给后面的人做个参考,讲的都是很基础的东西,大神请直接无视。笔者水平有限,有疏漏之处,还望指出。

今天说的叫最大子数组问题,大意是一个长度为n的数组中,求一个子数组,使这个子数组是所有子数组中元素和最大的那个。

一、最最朴素的算法      时间复杂度:O(n^3)      空间复杂度:O(n)

直接枚举每个字数组的首尾,并求和后与max比较即可。

PASCAL版:

//没安PASCAL编译器,所以细节上可能有些问题,大家凑合看。

program ed;

var

i,j,k,n,max,sum:longint;

a:array[0..1001] of longint;

begin

readln(n);

for i:=1 to n do read(a[i]);

max:=-maxlongint;

for i:=1 to n do

for j:=i to n do

begin

sum:=0;

for k:=i to j do

inc(sum,a[k]);

if sum>max then max:=sum;

end;

writeln(max);

end.

C++版:

#include<iostream>

using namespace std;

int main()

{

long n,a[1001];

cin>>n;

for(long i=0;i!=n;i++)cin>>a[i];

long max=-0x3fffffff,sum;

for(long i=0;i!=n;i++)

for(long j=i;j!=n;j++)

{

sum=0;a

for(long k=i;k<=j;k++)

sum+=a[k];

if(sum>max)max=sum;

}

cout<<max<<endl;

return 0;

}

二、朴素的算法      时间复杂度:O(n^2)      空间复杂度:O(n)

在算法一的基础上,考虑到每个子数组的和是可以预先求出来的。即预先求出sum[i]表示a[1] 到a[i]所有数的和,这样a[i]到a[j]的和就可以表示为sum[j]-sum[i-1],这样就可以省去第三重循环,把算法的时间复杂度降到O(n^2)。

PASCAL版:

program ed;

var

i,j,n,max:longint;

a,sum:array[0..1001] of longint;

begin

readln(n);

for i:=1 to n do read(a[i]);

sum[0]=0;

for i:=1 to n do

sum[i]:=sum[i-1]+a[i];

max:=-maxlongint;

for i:=1 to n do

for j:=i to n do

If sum[j]-sum[i-1]>max then

max:=sum[j]-sum[i-1];

writeln(max);

end.

C++版:

#include<iostream>

using namespace std;

int main()

{

long n,a[1001];

cin>>n;

a[0]=0;

for(long i=1;i<=n;i++)

{

cin>>a[i];

a[i]+=a[i-1];

}

long max=-0x3fffffff;

for(long i=1;i<=n;i++)

for(long j=i;j<=n;j++)

if(a[j]-a[i-1]>max)

max=a[j]-a[i-1];

cout<<max<<endl;

return 0;

}

三、分治法        时间复杂度:O(nlgn)       空间复杂度:O(n)

这个方法是从《算法导论》上看到的方法,虽然算法不是最优的,但是整个算法的思路还是很有启发性的。这里引用《算法导论》的原话(略有删改):

我们来思考如何用分治法技术来求解最大子数组问题。假定我们要寻求子数组A[low..high]的最大子数组。使用分治技术以为这我们要将子数组划分为两个规模尽量相等的子数组。也就是说,寻找子数组的中央位置,比如mid,然后考虑求解两个子数组A[low..mid]和A[mid+1..high]。A[low..high]的任何连续子数组A[i..j]所处的位置必然是一下三种情况之一:

  1. 完全位于子数组A[low..mid]中,因此low<=i<=j<=mid。
  2. 完全位于子数组A[mid+1..high]中,因此mid<i<=j<=high。
  3. 跨越了中点,因此low<=i<=mid<j<=high。

因此,A[low..high]的一个最大子数组所处的位置必然是这三种情况之一。实际上,A[low..high]的一个最大子数组必然是完全位于A[low..mid]中、完全位于A[mid+1..high]中或者跨越中点的所有子书中和最大者。我们可以递归地求解A[low..mid]和A[mid+1..high]的最大子数组,因此这两个子问题仍是最大子数组问题,只是规模更小。因此,剩下的全部工作就是寻找跨越中点的最大子数组,然后在三种情况下选取和最大者。

我们可以很容易地在线性时间(相对于子数组A[low..high]的规模)内求出跨越中点的最大子数组。此问题并非原问题规模更小的实例,因此它加入了限制——求出的子数组必须跨越中点。任何跨越中点的子数组都有两个子数组A[i..mid]和A[mid+1..j]组成,其中low<=i<=mid且mid<j<=high。因此,我们只需找出形如A[i..mid]和A[mid+1..j]的最大子数组,然后将其合并即可。

而因为A[i..mid]和A[mid+1..j]相互独立,我们可以很容易的在O(n)时间内分开求出他们的最大子数组。

PASCAL版:

//再次声明,笔者没有PASCAL的编译器,所有程序都是对着C++手码的,仅仅方便//pascaler的理解,不保证正确。

program ed;

var

a:array[0..100001] of longint;

i,n:longint;

function max(a,b:longint):longint;

begin

if a>b then exit(a);

exit(b);

end;

function find_max_crossing_subarray(low,mid,high):longint;

var

left_sum,right_sum,sum,i:longint;

begin

left_sum:=-maxlongint;

sum:=0;

for i:=mid downto low do

begin

inc(sum,a[i]);

left_sum:=max(left_sum,sum);

end;

right_sum:=-maxlongint;

sum:=0;

for i:=mid+1 to high do

begin

inc(sum,a[i]);

right_sum:=max(right_sum,sum);

end;

exit(left_sum+right_sum);

end;

function find_maximum_subarray(low,high):longint;

var

mid,maxn:longint;

begin

if high=low then exit(a[low]);

mid:=(low+high) div 2;   //类似的,这样写 mid:=(low+high)>>1; 也行。

maxn:=find_max_crossing_subarray(low,mid,high);

maxn:=max(maxn,find_maximum_subarray(low,mid));

maxn:=max(maxn,find_maximum_subarray(mid+1,high));

exit(maxn);

end;

begin

readln(n);

for i:=1 to n do read(a[i]);

writeln(find_maximum_subarray(1,n));

end.

C++版:

#include<iostream>

#define min_num -0x3fffffff

using namespace std;

long a[100001];

long max(long a,long b){return (a>b)?a:b;}

long  find_max_crossing_subarray(long low,long mid,long high)

{

long left_sum=min_num,sum=0;

for(long i=mid;i>=low;i--)

{

sum+=a[i];

left_sum=max(left_sum,sum);

}

long right_sum=min_num; sum=0;

for(long i=mid+1;i<=high;i++)

{

sum+=a[i];

right_sum=max(right_sum,sum);

}

return left_sum+right_sum;

}

long find_maximum_subarray(long low,long high)

{

if(low==high)return a[low];

long mid=(low+high)/2;

long maxn=find_max_crossing_subarray(low,mid,high);

maxn=max(maxn,find_maximum_subarray(low,mid));

maxn=max(maxn,find_maximum_subarray(mid+1,high));

return maxn;

}

int main()

{

long n; cin>>n;

for(long i=1;i<=n;i++)cin>>a[i];

cout<<find_maximum_subarray(1,n)<<endl;

return 0;

}

四、动态规划法(DP)    时间复杂度:O(n)     空间复杂度:O(n)

设f[i]表示a[1..i]的最大子数组。设想我们已经求出f[i],如何扩展到f[i+1]?仔细思考后会发现,在已知f[i]的前提下,f[i+1]不外乎就两种情况:一种是f[i+1]不包含a[i+1],那么显然f[i+1]=f[i]。另一种是f[i+1]包含a[i+1],那么f[i+1]显然是a[j..i+1](1<=j<=i+1)中最大的那个,不妨设max{a[j..i+1]}(1<=j<=i+1)为g[i+1],那么显然g[i+1]就是表示以a[i+1]结尾的最大子数组。

假设我们已经求出了g[i+1],那么依据上面所述,便可得f[i+1]的状态转移方程:

f[i+1]=max{f[i],g[i+1]}

现在问题已经成功转化为求g[i+1]。还是按照同样的思路去想,假设我们已经求出g[i],如何扩展到g[i+1]?同样也就两种情况:一种是g[i]为负数,那么显然g[i+1]=a[i+1];另外一种g[i]不是负数,那么g[i+1]=g[i]+a[i+1]。所以,g[i+1]的为状态转移方程:

g[i+1]=max{g[i]+a[i+1],a[i+1]}

综上所述我们便得到了整个问题的状态转移方程:

f[i+1]=max{f[i],g[i+1]}

g[i+1]=max{g[i]+a[i+1],a[i+1]}

多说一句,如果你对这种含有多个数组DP很感兴趣,推荐做一下RQNOJ上的又上锁妖塔一题,也是这个类型的。还有一道USACO的一道奶牛跑步的题目用的也是这个方法,具体哪一题记不清了,有兴趣可以去找一下。

PASCAL版:

program ed;

var

a,f,g:array[0..100001] of longint;

i,n:longint;

fucntion max(a,b:longint):longint;

begin

if a>b then exit(a);

exit(b);

end;

begin

readln(n);

for i:=1 to n do read(a[i]);

f[0]:=-maxlongint; g[0]:=-maxlongint;

for i:=1 to n do

begin

g[i]:=max(g[i-1],0)+a[i];

f[i]:=max(f[i-1],g[i]);

end;

writeln(f[n]);

end.

C++版:

#include<iostream>

#define maxn 100001

#define min_num -0x3fffffff

using namespace std;

long max(long a,long b){return (a>b)?a:b;}

int main()

{

long n,a[maxn],f[maxn],g[maxn]; cin>>n;

for(long i=1;i<=n;i++)cin>>a[i];

f[0]=min_num; g[0]=min_num;

for(long i=1;i<=n;i++)

{

g[i]=max(g[i-1],0)+a[i];

f[i]=max(f[i-1],g[i]);

}

cout<<f[n]<<endl;

return 0;

}

五、动态规划法(空间优化版)         时间复杂度O(n)     空间复杂度O(1)

好吧,我承认这种方法就是闲的蛋疼,没太大实质性优化,拿出来给大家参考一下。

回顾下上面方法的状态转移方程:

f[i+1]=max{f[i],g[i+1]}

g[i+1]=max{g[i]+a[i+1],a[i+1]}

你会发现无论是f[i]还是g[i]都只与前一项有关,想到了什么,滚动数组!(不知道的自行百度,很多大神的文章讲的都很详细)自然而然就有了这种方法(用了位运算的知识,不会的同样百度,推荐Matrix67神牛讲解位运算的文章)。表达式如下:

PASCAL:

f[(i+1) and 1]=max{f[i and 1],g[(i+1) and 1]}

g[(i+1) and 1]=max(g[i and 1]+a[(i+1) and 1],a[(i+1) and 1]

C++:

f[(i+1)&1]=max{f[i&1],g[(i+1)&1]}

g[(i+1)&1]=max(g[i&1]+a[(i+1)&1],a[(i+1)&1]

PASCAL版:

program ed;

var

i,n,a:longint;

f,g:array[0..1] of longint;

function max(a,b:longint):longint;

begin

if a>b then exit(a); exit(b);

end;

begin

readln(n);

f[0]:=-maxlongint; f[1]:=-maxlongint; g[0]:=-maxlongint; g[1]:=-maxlongint;

for i:=1 to n do

begin

read(a);

g[i and 1]:=max(g[(i-1) and 1],0)+a;

f[i and 1]:=max(f[(i-1) and 1],g[i and 1];

end;

writeln(f[n and 1]);

end.

C++版:

#include<iostream>

#include<cstdlib>

#define min_num -0x3fffffff

using namespace std;

int main()

{

long n,a,f[2]={min_num,min_num},g[2]={min_num,min_num}; cin>>n;

for(long i=1;i<=n;i++)

{

cin>>a;

g[i&1]=max(g[(i-1)&1]+a,a);

f[i&1]=max(f[(i-1)&1],g[i&1]);

}

cout<<f[n&1]<<endl;

return 0;

}

六、动态规划法2                 时间复杂度O(n)     空间复杂度O(1)

换一个思路想想,其实f[i]数组是不必要的。因为最大子数组一定是以某一个a[i]结尾的,所以答案就是g[i]的最大值。

PASCAL版:

program ed;

var

i,n,a,ans:longint;

g:array[0..1] of longint;

function max(a,b:longint):longint;

begin

if a>b then exit(a); exit(b);

end;

begin

readln(n);

g[0]:=-maxlongint; g[1]:=-maxlongint; ans:=-maxlongint;

for i:=1 to n do

begin

read(a);

g[i and 1]:=max(g[(i-1) and 1],0)+a;

ans:=max(ans,g[i and 1]);

end;

writeln(ans);

end.

C++版:

#include<iostream>

#include<cstdlib>

#define min_num -0x3fffffff

using namespace std;

int main()

{

long n,a,ans=min_num,g[2]={min_num,min_num}; cin>>n;

for(long i=1;i<=n;i++)

{

cin>>a;

g[i&1]=max(g[(i-1)&1]+a,a);

ans=max(ans,g[i&1]);

}

cout<<ans<<endl;

return 0;

}

七、一种新的思路——转化问题                时间复杂度O(n)   空间复杂度O(n)

放在这里并不是说这种方法比上面的要好,只是思路比较新颖。

设b[i]表示a[1..i]的和,那么问题转化为求i,j(i<=j),使b[j]-b[i]的差最大。记f[i]表示b[i..n]的最大值。那么答案显然是f[i]-b[i]的最大值。

f[i]可以在线性时间内求出来,状态转移方程如下:

f[i]=max{f[i+1],b[i]}

有了f[i],答案就显而易见了。

PASCAL版:

program ed;

var

a,f:array[0..100001] of longint;

i,n,ans:longint;

function max(a,b:longint):longint;

begin

if a>b then exit(a); exit(b);

end;

begin

readln(n);

for i:=1 to n do

begin

read(a[i]);

inc(a[i],a[i-1]);

end;

ans:=-maxlongint; f[n+1]:=-maxlongint;

for i:=n downto 0 do

begin

f[i]:=max(f[i+1],a[i]);

ans:=max(ans,f[i]-a[i]);

end;

writeln(ans);

end.

C++版:

#include<iostream>

#include<cstdlib>

#define min_num -0x3fffffff

using namespace std;

int main()

{

long n,a[

long ans=min_num; f[n+1]=min_num;

for(long i=n;i>=0;i--)

{

f[i]=max(f[i+1],a[i]);

ans=max(ans,f[i]-a[i]);

}

cout<<ans<<endl;

return 0;

}

八、最大子数组问题的扩展——最大子矩阵    时间复杂度:O(n^3)    空间复杂度:O(n^2)

现在我们将最大子数组问题扩展到2维,变成最大子矩阵问题。即在一个二维数组中找一个最大子矩阵。这里用到的方法就是把最大子矩阵问题转化为最大子数组问题解决。说的具体点就是枚举矩阵行的上下界,设二维数组为a[m][n],假设枚举上下界为i,j(i<=j),那么b[k]=a[t][k](i<=t<=j)的和。这样就可以用最大子数组的方法。枚举的时间复杂度为O(n^2),和可以用与算法二类似的方法预处理,最后最大子数组时间复杂度为O(n),所以最大子矩阵问题的时间复杂度:O(n^3)。

经典的问题如AHOI2011的第一题,以及RQNOJ上的某题。当然这个问题还能扩展到三维、四维乃至更高维,基本上对于M维的问题,用类似的方法可以写出一个时间复杂度O(n^(2M-1)),空间复杂度O(n^M)的算法。比较经典的例子就是RQNOJ上的切西瓜这题。

下面给出二维情况的代码:

PASCAL版:

program ed;

var

a:array[0..101,0..101] of longint;

f:array[0..101] of longint;

i,j,k,m,n,ans:longint;

function max(a,b:longint):longint;

begin

if a>b then exit(a); exit(b);

end;

begin

readln(m,n);

for i:=1 to m do

begin

for j:=1 to n do

begin

read(a[i,j]);

inc(a[i,j],a[i-1,j]);

end;

readln;

end;

ans:=-maxlongint;

for i:=1 to m do

for j:=i to m do

begin

f[0]:=-maxlongint;

for k:=1 to n do

begin

f[k]:=max(f[k-1],0)+a[j,k]-a[i-1,k];

ans:=max(ans,f[k]);

end;

end;

writeln(ans);

end.

C++版:

#include<iostream>

#include<cstdlib>

#define min_num -0x3fffffff

using namespace std;

int main()

{

long m,n,a[101][101],f[101]; cin>>m>>n;

for(long i=1;i<=n;i++)a[0][i]=0;

for(long i=1;i<=m;i++)

for(long j=1;j<=n;j++)

{

cin>>a[i][j];

a[i][j]+=a[i-1][j];

}

long ans=min_num;

for(long i=1;i<=m;i++)

for(long j=i;j<=m;j++)

{

f[0]=min_num;

for(long k=1;k<=n;k++)

{

f[k]=max(f[k-1]+a[j][k]-a[i-1][k],a[j][k]-a[i-1][k]);

ans=max(ans,f[k]);

}

}

cout<<ans<<endl;

return 0;

}

至此,最大子数组问题就就告一段落了。作者本人水平有限,如果读者发现内容中的错误或是有什么建议,希望予以指出。

本文由Edward2414创作,转载请注明出处。

转载于:https://www.cnblogs.com/edward2414/archive/2013/03/27/oi-01.html

相关文章:

springCloud Zuul网关

1.springboot 仅2.0.x 支持&#xff0c;在此选择 2.0.7 2.新建Module eureka-zuul-client 3.导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/…

f-free 查看系统中空闲和使用的内存

文章目录前言语法格式以指定单位显示内存占用情况打印所有内存占用&#xff08;RAM SWAP&#xff09;打印间隔以及次数打印所有的列&#xff08;将buff和cache分开&#xff09;free各个空间含义swap交换空间cache页高速缓存free 与 available前言 free 支持查看空闲的和已使用…

对比两个同类型的泛型集合并返回差异泛型集合 ——两个List类名的比较

1: /// <summary> 2: /// 对比两个同类型的泛型集合并返回差异泛型集合 3: /// </summary> 4: /// <typeparam name"T">泛型类型</typeparam> 5: /// <param name"newModel">修改后的数据集合</param> 6: /// &…

php insert failed,较大的MySQL INSERT语句导致PHP错误

好吧,我正在编写代码,但是发生了一些奇怪的事情,我不认为我的代码是错误的…但是它仍在垂死,我不知道为什么…有错误&#xff1a;Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use …

js 取得文件大小

document.getElementById("file").files[0].size

Spring Boot thymeleaf模版支持,css,js等静态文件添加

Thymeleaf引入 Thymeleaf是一个Java模板引擎开发库&#xff0c;可以处理和生成HTML、XML、JavaScript、CSS和文本&#xff0c;在Web和非Web环境下都可以正常工作。 1.添加依赖包 <dependency><groupId>org.springframework.boot</groupId><artifactId>…

s-sed(stream editor) 文本填充和编辑 基本使用

文章目录前言语法格式sed 操作地址sed子命令sed正则表达式sed使用实例打印命令 p删除命令 d替换命令 s指定操作地址的范围 逗号 ,多重编辑命令 e下行插入命令 a上行插入命令 i修改命令 c获取下一行命令 n转换命令 y退出命令 q总结前言 sed是一个“非交互”式的字符流编辑器&am…

c语言动态迁移mysql,flask-migrate动态迁移数据库

了解flask_migrate需要先了解flask-script&#xff0c;那么flask-script的作用是什么呢&#xff1f;flask-script的作用是可以通过命令行的形式来操作Flask。例如通过命令跑一个开发版本的服务器、设置数据库&#xff0c;定时任务等。2.执行pip install flask-script来进行安装…

软考之路-网络攻击:主动攻击和被动攻击

被动攻击(针对路上的东西下手) 概念&#xff1a;就是网络窃听&#xff0c;窃取数据包并进行分析&#xff0c;从中窃取重要的敏感信息 措施&#xff1a;防止被动攻击的主要手段是数据加密传输 主动攻击(针对计算机下手) 概念&#xff1a;包括窃取、篡改、假冒和破坏 措施&#x…

edge.js架起node.js和.net互操作桥梁

今天要介绍的是edge.js这个github上刚兴起的开源项目&#xff0c;它可以让node.js和.net之间在in-process下互操作。.net版本在4.5及以上&#xff0c;因为.net4.5带来的Task&#xff0c;asyn&#xff0c;await关键字和node.js的Event模型正好匹配。如果你感兴趣的话&#xff0c…

connect() failed (111: Connection refused) while connecting to upstream, cli

php-fpm没有运行 执行如下命令查看是否启动了php-fpm&#xff0c;如果没有则启动你的php-fpm即可 netstat -ant | grep 9000没有运行为空&#xff0c;有运行显示 tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN 启动方法 sudo /usr/loca…

C++的STL 栈实现 判断栈的出栈顺序是否合理

有这样的题目&#xff1a; 已知从1至n的数字序列&#xff0c;按顺序入栈&#xff0c;每个数字入栈后即可出栈&#xff0c; 也可在栈中停留&#xff0c;等待后面的数字入栈出栈后&#xff0c;该数字再出栈&#xff0c;求该数字序列的出栈序列是否合法? 类似如下&#xff1a; 已…

fire.php,Fire PHP

项目介绍&#xff1a; Fire PHP 是基于 PHP JavaScript开发的跨平台的Firefox 的扩充套件&#xff0c;即PHP调试插件&#xff0c;可以帮你debug 后端PHP 的程式&#xff0c;其使用的技术跟某些IDE 一样&#xff0c;要求你在写程式时加入一些追踪用的代码。通过使用Firephp你可以…

json_encode时中文编码转正常状态

function json_encode_cn($data) {$data json_encode($data);return preg_replace("/\\\u([0-9a-f]{4})/ie", "iconv(UCS-2, UTF-8, pack(H*, $1));", $data); }直接json_encode()函数 ["\u6fb3\u5927\u5229\u4e9e","\u8056\u8a95\u5cf6&q…

验证URL链接和IP有效性的JS代码(正则表达式)

千里之行&#xff0c;始于足下&#xff0c;因之前毕业设计的耽误&#xff0c;没能在博客园记录我的程序猿体会&#xff0c;稍有遗憾&#xff0c;这么多的时间&#xff0c;我竟让他转瞬而过&#xff01;但没关系&#xff0c;再次出发&#xff0c;勿忘为什么出发&#xff01; 一下…

[转帖]什么是光纤的波长?看看有哪些是你不知道的!

什么是光纤的波长&#xff1f;看看有哪些是你不知道的&#xff01; FShttps://www.feisu.com/bbs/e-1640.html2017-07-01 00:00:001084我们平时最熟悉的光当然是我们肉眼所能看见的光。我们的眼睛对波长在400nm的紫光到700nm的红光很敏 感。但对于携带玻璃纤维的光纤&#xff0…

C++的STL 栈 实现四则运算

使用栈实现四则运算&#xff0c;支持&#xff0c;-&#xff0c;*&#xff0c;/&#xff0c;(&#xff0c;) 输入为字符串&#xff0c;输出为计算好的数值&#xff0c;如不符合四则运算的规定&#xff0c;则异常退出 这个实现借用了栈以及字符处理状态机的思想&#xff1a; 维…

javascript小数相减会出现一长串的小数位数的原因

javascript小数相减会出现一长串的小数位数的原因 <script>var a38.8;var b6.8;alert(parseFloat(a)-parseFloat(b));var a134.22;var b6;alert(a*b);</script>以上代码为什么产生一长串小数位出来&#xff0c;虽然比较精确&#xff0c;可没必要呀。这个和数据结构…

Java孩子父母类,@Output孩子和父母之间的沟通 . 角2(5)

我正在尝试学习角度2&#xff0c;并且我正在尝试使用来自我的子组件的数据在父组件中设置变量 . 基本上我在父视图中有一个子 Headers &#xff0c;我希望 Headers 和一些HTML根据加载的子项进行更改 .父组件&#xff1a;import { Component, OnInit, ViewEncapsulation } from…

SQL 自学笔记1(W3School)

自学W3Schoolhttp://www.w3school.com.cn/sql/index.asp 简介 SQL是什么&#xff1f; Structured Query Language 结构化的查询语言 SQL能做什么&#xff1f; 面向数据库查询、取出数据、插入新数据、更新数据、删除数据在数据库中建立库、表&#xff1b;创建存储过程及视图可设…

BZOJ 1096: [ZJOI2007]仓库建设

传送门 斜率优化DP入门题 显然如果在一个位置 i 建一个仓库&#xff0c;且上一个仓库位置为 j 那么从 j1到 i 的物品显然都要存在 i 仓库是最优的 设 $f [ i ]$ 表示在第 i 个工厂建设仓库时&#xff0c;工厂 1 到 i 的物品都转移好的最小花费 考虑上一个仓库的位置 j 设工厂 i…

C++的STL 堆 实现获取数组堆第K大的数

前言 堆数据结构 使用的是优先级队列实现&#xff0c;创建堆的时候需要指定堆中元素的排列方式&#xff0c;即最大堆或者最小堆 最大堆即 堆顶元素为堆中最大的元素 最小堆即 堆顶元素为堆中最小堆元素 如下为一个最大堆 回到文章标题&#xff0c;获取一个数组中第K大的数&a…

HTML+CSS布局技巧及兼容问题【阅读季】

在IE6和IE7中&#xff0c;行高值必须大于字体的2px以上才能保证字体的完整显示或当作为链接时能显示下划线。 IE6 下去掉 input等元素 的边框 border: 0 none; 所有浏览器都可以了 边框1px {td不重叠状态}&#xff1a;border-collapse: collapse;&#xff08;table、td需同时…

php 去掉数组相同元素,php怎么去掉数组中重复的元素

php去掉数组中重复的元素的方法&#xff1a;可以通过内置函数array_unique()来实现。array_unique()函数可以移除数组中重复的值并返回过滤后的数组。如果数组中存在多个相同元素&#xff0c;则只保留第一个值。php为我们提供了专门的内置函数array_unique()来解决此问题。该函…

Office文件的奥秘——.NET平台下不借助Office实现Word、Powerpoint等文件的解析(完)...

原文 http://www.cnblogs.com/mayswind/archive/2013/04/01/2991271.html 【题外话】 这是这个系列的最后一篇文章了&#xff0c;为了不让自己觉得少点什么&#xff0c;顺便让自己感觉完美一些&#xff0c;就再把OOXML说一下吧。不过说实话&#xff0c;OOXML真的太容易 解析了&…

Makefile (2) gdb

gdb调试 1.用debug的方式编译 -g 2.打上断点 3.单步调试 step into 进入函数里面step over 运行整个函数step return 跳出当前函数 4.继续运行 5.打印和监控值 下面是栗子: 1 #include <stdlib.h>2 #include <stdio.h>3 ​4 static int add(int i) //创…

C++的 STL堆 实现获取中位数

前言 堆数据结构 使用的是优先级队列实现&#xff0c;创建堆的时候需要指定堆中元素的排列方式&#xff0c;即最大堆或者最小堆 最大堆即 堆顶元素为堆中最大的元素 最小堆即 堆顶元素为堆中最小堆元素 如下为一个最大堆 中位数&#xff1a; 一组数排序后&#xff0c;如果元…

php 变更 obj,PHP: 不向后兼容的变更 - Manual

不向后兼容的变更PHP 核心中不向后兼容的变更以数组形式访问非数组尝试以数组方式访问 null&#xff0c;bool&#xff0c;int&#xff0c;float 或 resource(例如 $null["key"])将会抛出 notice 通知。fn 关键词fn 成为了保留关键词。需要特别注意&#xff0c;它不能…

正由另一进程使用,因此该进程无法访问此文件。

相信很多人都遇到过这样的问题吧 最近我的电脑似乎有点抽风了,不知道为什么控制台程序,只要使用 开始执行(不调试) 必然就残留在进程中 而且进程管理器看不到~~ 最恶心的是,就算重启VS也还是不能生成 经过一些尝试后发现在cmd中tasklist可以看到这个进程 这就好办了 使用taskki…

mysql5.6下主主复制的配置实现

两台虚拟机192.168.183.131和192.168.183.132,装完系统之后直接把所有开发包都装上 下载软件包mysql-5.6.10.tar.gz&#xff0c;cmake-2.8.10.2.tar.gz&#xff08;从5.5开始mysql使用cmake来进行编译了而不是之前的configure&#xff09; mysql的编译安装 1.首先安装cmake [ro…