return0;
}
8、最大子段和问题
#include
usingnamespacestd;
//序列中全为负数,最大字段和为0
intMaxSum(inta[],intleft,intright)
{
intsum=0;
intcenter=0;
intleftsum=0;
intrightsum=0;
if(left==right)
{
if(a[left]>0)
sum=a[left];
elsesum=0;
}
else
{
center=(left+right)/2;
leftsum=MaxSum(a,left,center);
rightsum=MaxSum(a,center+1,right);
}
ints1=0;intlefts=0;
for(inti=center;i>=left;i--)
{
lefts+=a[i];
if(lefts>s1)s1=lefts;
}
ints2=0;intrights=0;
for(inti=center+1;i<=right;i++)
{
rights+=a[i];
if(rights>s2)s2=rights;
}
sum=s1+s2;
if(sumif(sumreturnsum;
}
intmain()
{
inta[]={1,2,3,4,5,-6};
cout<}
动态规划
9、0-1背包问题
#include
usingnamespacestd;
constintnum=50;//物品数量的上限
constintcap=1500;
intw[num]={0,2,1,3,2};
intv[num]={0,12,10,20,15};
intp[num][cap];
//n是物品的数量,c是背包的容量w
voidknapsack(intc,intn)
{
intjmax=min(w[n]-1,c);
for(intj=0;j<=jmax;j++)
p[n][j]=0;
for(intj=w[n];j<=c;j++)
p[n][j]=v[n];
for(inti=n-1;i>=1;i--)
{
jmax=min(w[i]-1,c);
for(intj=0;j<=jmax;j++)
p[i][j]=p[i+1][j];
for(intj=w[i];j<=c;j++)
p[i][j]=max(p[i+1][j],p[i+1][j-w[i]]+v[i]);
}
p[1][c]=p[2][c];
if(c>=w[1])
p[1][c]=max(p[1][c],p[2][c-w[1]]+v[1]);
}
intmain()
{
knapsack(5,5);
cout<
}
10、矩阵连乘积问题
#include
#definenum51
usingnamespacestd;
intp[]={50,10,40,30,5,20,15};
intm[num][num];
ints[num][num];
voidMatrixChain(intn)//n是矩阵的个数
{
for(inti=1;i<=n;i++)
m[i][i]=0;
for(intr=2;r<=n;r++)//r是指对角线
for(inti=1;i<=n-r+1;i++)
{
intj=i+r-1;
//计算初值,从i处断开
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
s[i][j]=i;
for(intk=i+1;k{
intt=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(t{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
voidTraceBack(inti,intj)
{
if(i==j)
cout<<"A"<
else
{
cout<<"(";
TraceBack(i,s[i][j]);
TraceBack(s[i][j]+1,j);
cout<<")";
}
}
intmain()
{
intn=6;
MatrixChain(n);
TraceBack(1,n);
}
11、最长单调递增子序列
#include
usingnamespacestd;
constintnum=100;
inta[num]={0,65,158,170,155,239,300,207,389};
intLIS(intn)
{
intb[num]={0};
b[1]=1;//以b[i]为结尾的最长单调子序列的个数
intmax=0;
for(inti=2;i<=n;i++)
{
intk=0;
for(intj=1;j
if(a[j]<=a[i]&&k
k=b[j];
b[i]=k+1;
if(max
max=b[i];
}
returnmax;
}
intmain()
{
cout<}
12、最长公共子序列问题
#include
usingnamespacestd;
constintnum=100;
intc[num][num];
intb[num][num];
voidLCSLength(intm,intn,constcharx[],chary[])
{
for(inti=1;i<=m;i++)c[i][0]=0;
for(inti=1;i<=n;i++)c[0][i]=0;
//根据递推公式构造数组c
for(inti=1;i<=m;i++)
for(intj=1;j<=n;j++)
{
if(x[i]==y[i])
{
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
}
elseif(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
b[i][j]=2;
}
else
{
c[i][j]=c[i][j-1];
b[i][j]=3;
}
}
}
voidLCS(inti,intj,charx[])
{
if(i==0||j==0)return;
if(b[i][j]==1)
{
LCS(i-1,j-1,x);
cout<}
elseif(b[i][j]==2)
LCS(i-1,j,x);
elseLCS(i,j-1,x);
}
intmain()
{
charx[]={'A','B','C','B','D','A','B'};
chary[]={'B','D','C','A','B','A'};
LCSLength(8,7,x,y);
LCS(8,7,x);
}
贪心法
13、背包问题
#include
usingnamespacestd;
structbag
{
intw;
intv;
doublec;
};
boolcmp(baga,bagb)
{
returna.c>=b.c;
}
//n是物品数量,c是书包容量,a是按性比价排列的
doubleknapsack(intn,baga[],doublec)
{
sort(a,a+n,cmp);
doublecleft=c;
inti=0;
doubleb=0;//获得的价值
//当背包还能完全装下物品i
while(i{
cleft-=a[i].w;
b+=a[i].v;
i++;
}
if(ireturnb;
}
intmain()
{
baga[15]={{10,60,6},{30,120,4},{20,100,5}};
cout<return0;
}
14、多出最优服务次序问题
#include
#include
usingnamespacestd;
doublegreedy(vectorclient,ints)//顾客等待队列为client窗口数量为s
{
vectorservice(s+1,0);
vectorsum(s+1,0);
intn=client.size();
sort(client.begin(),client.end());
inti=0;
intj=0;
while(i{
service[j]+=client[i];
sum[j]+=service[j];
++i;++j;
if(j==s)j=0;
}
doublet=0;
for(i=0;i
t+=sum[i];
t/=n;
returnt;
}
intmain()
{
cout<<"有n个顾客,s个窗口提供服务,请输入n和s"<intn;
ints;
cin>>n;
cin>>s;
cout<<"输入顾客需要的时间client"<vectorclient;
inttemp;
for(inti=0;i{
cin>>temp;
client.push_back(temp);
}
cout<}
15、活动安排问题
#include
usingnamespacestd;
structaction
{
ints;
intf;
intindex;
};
boolcmp(constaction&a,constaction&b)
{
if(a.f<=b.f)returntrue;
returnfalse;
}
voidGreedySelector(intn,actiona[],boolb[])
{
sort(a,a+n+1,cmp);
b[1]=true;
intpreEnd=1;
for(inti=2;i<=n;i++)
if(a[i].s>=a[preEnd].f)
{
b[i]=true;
preEnd=i;
}
for(inti=1;i<=n;i++)
{
if(b[i])
cout<}
}
intmain()
{
actiona[12]={{0,0,0},{1,4,1},{3,5,2},{0,6,3},{5,7,4},{3,8,5},{5,9,6},{6,10,7},{8,11,8},{8,12,9},{2,13,10},{12,14,11}};
boolb[12]={false};
GreedySelector(11,a,b);
}
16、删除问题
#include
usingnamespacestd;
voidf(stringa,intk)
{
if(k>=a.size())
a.erase();
elsewhile(k>0)
{
inti;
for(i=0;(ia.erase(i,1);
k--;
}
while(a.size()>1&&a[0]=='0')
a.erase(0,1);
cout<}
intmain()
{
stringa="123435";
intk=1;
f(a,k);
}
17、数字三角形问题
#include
usingnamespacestd;
constintnum=5;
inttri[num][num]={{9},{12,15},{10,6,8},{2,18,9,5},{19,7,10,4,16}};
inttriangle(intn)
{
inti,j;
for(i=n-2;i>=0;i--)
for(j=0;j<=i;j++)
{
if(tri[i+1][j]>tri[i+1][j+1])
tri[i][j]+=tri[i+1][j];
elsetri[i][j]+=tri[i+1][j+1];
}
returntri[0][0];
}
intmain()
{
cout<}
18、最优装载问题
#include
usingnamespacestd;
//容量一定,装载的个数最多,则优先装载轻的;
structload
{
intw;//重量
intindex;//编号
};
boolcmp(loada,loadb)
{
if(a.welsereturnfalse;
}
voidLoading(intn,loada[],intc)
{
intx[n];
sort(a,a+n+1,cmp);
if(a[1].w>c)
{
cout<<"noanser!
"<}
inti;
for(i=0;i<=n&&a[i].w<=c;i++)
{
x[a[i].index]=1;
c-=a[i].w;
}
cout<
for(i=1;i<=n;i++)
{
if(x[i]==1)
cout<
}
}
intmain()
{
loada[]={{40,1},{10,2},{40,3}};
Loading(4,a,50);
}
回溯法
19、0-1背包问题
#include
usingnamespacestd;
constintnum=100;
intc;//背包容量
intn;//物品数量
intcw;//当前重量
intcv;//当前价值
intbestv;//当前最优价值
s