这一章我看的,写的都挺爽快的;
难度不大,但是又非常有意思;
有两点思想被体现:
1.保存状态,避免重复计算;(DB思想);
2.将信息预处理至数据结构中,(打表);
还是看具体问题吧:
求一数组集合中最大的连续子序列:
最垃圾的算法,(n2)
int Oo(int *a, int n)
{
num =0;
int i, j,sum=0, max=0;
for (i=0;i<n; i++)
{
for (j=i;j<n; j++)
{
sum+=a[j];
max =MAX(sum, max);
}
sum =0;
}
returnmax;
}
分治法优化:
将序列分为两段A,B,则很明显最大的连续子序列,要么是A中的最大连续子序列,或B,或过中点;
int OO(int *a, int l, int r)
{
int sum,lmax, rmax, m;
if(l>r) return 0;//此时 zero element;
if (l==r)return MAX(0, a[l]);//此时 one element;
m =(l+r)>>1;//m为l+r 除以二;
sum = lmax =rmax =0;
//计算l边从中点起的最大值;
for (inti=m; i>=l; i--)
{
sum+=a[i];
lmax =MAX(lmax, sum);
}
sum =0;
for (inti=m+1; i<=r; i++)
{
sum+=a[i];
rmax =MAX(rmax, sum);
}
returnMAX(MAX((lmax+rmax), OO(a, l, m)),OO(a, m+1, r));
}
最后是线性o(n)算法:(扫描算法)
遇前子序列相加小于0;就重新计算;考虑到负数的因素,这个原因很容易相出来的;
int OOO(int *a, int n)
{
int i,maxford=0, max=0;
for(i=0;i<n; i++)
{
max =MAX(max+a[i], 0);
//与每一个截断的自序列做对比;
maxford =MAX(max, maxford);
}
returnmaxford;
}
课后习题:
第五题:
int *cumarr = a+1;
cout<<cumarr[-1]<<endl;
第九题:
int OOO(int *a, int n)
{
int i;
intmaxford=0, max=0;
int mx =a[0];
for(i=0;i<n; i++)
{
//全是负数的数组,那么最大子序列集合就是其最大值。
mx =(mx>a[i])?mx:a[i];
max =(max+a[i]> 0)?(max+a[i]):0;
//与每一个截断的自序列做对比;
maxford=(maxford>max)?maxford:max;
}
if(mx>0)
{returnmaxford;}
else returnmx;
}
第十题:
#include<iostream>
#include<map>
#include<cmath>
using namespace std;
typedef struct
{
intxi;
intyj;
}INT;
int OOO(int *a, int n, int t)
{
intcum[n];
intde;
inthr;
cum[0] =a[0];
for(int i=1; i<n; i++)
{
cum[i] =cum[i-1] + a[i];
}
map<int, INT> _map;
for (intj=n-1; j>0; j--)
{
for (inti=0; i<=j-1; i++)
{
hr =abs(cum[(j)]-cum[i]-t);
_map[hr].xi= i;
_map[hr].yj= j;
}
}
_map[abs(a[0]-t)].yj = 0;
cout<<"begin:"<<(_map.begin()->second).xi+1<<"end:"<<(_map.begin()->second).yj<<endl;
if(0 !=((_map.begin()->second).yj))
de =cum[(_map.begin()->second).yj] -cum[(_map.begin()->second).xi];
else de =a[0];
returnde;
}
int main()
{
inta[10]={31,-41,59,26,-53,58,97,-93,-23,84};
intn;//你所希望接近的序列值;
while(cin>>n)
cout<<OOO(a, 10,n)<<endl;
return0;
}
难度不大,但是又非常有意思;
有两点思想被体现:
1.保存状态,避免重复计算;(DB思想);
2.将信息预处理至数据结构中,(打表);
还是看具体问题吧:
求一数组集合中最大的连续子序列:
最垃圾的算法,(n2)
int Oo(int *a, int n)
{
}
分治法优化:
将序列分为两段A,B,则很明显最大的连续子序列,要么是A中的最大连续子序列,或B,或过中点;
int OO(int *a, int l, int r)
{
}
最后是线性o(n)算法:(扫描算法)
遇前子序列相加小于0;就重新计算;考虑到负数的因素,这个原因很容易相出来的;
int OOO(int *a, int n)
{
}
课后习题:
第五题:
int *cumarr = a+1;
第九题:
int OOO(int *a, int n)
{
}
第十题:
#include<iostream>
#include<map>
#include<cmath>
using namespace std;
typedef struct
{
}INT;
int OOO(int *a, int n, int t)
{
}
int main()
{
}