100 likes | 191 Views
1-5 防守阵地. 学号: 130321047 姓名:刘涛涛. 问题描述. 部队中共有 N 个士兵,每个士兵有各自的能力指数 Xi ,在一次演练中,指挥部确定了 M 个需要防守的地点,按重要程度从低到高排序,依次以数字 1 到 M 标注每个地点的重要程度,指挥部将选择 M 个士兵依次进入指定地点进行防守任务,能力指数为 X 的士兵防守重要程度为 Y 的地点将得到 X*Y 的参考指数。现在士兵们排成一排,请你选择出 连续 的 M 个士兵依次参加防守 , 使得总的参考指数值最大。. 问题案例说明. 我们先取 6 个士兵、 3 个防守地点简单分析下该问题
E N D
1-5 防守阵地 学号:130321047 姓名:刘涛涛
问题描述 • 部队中共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,按重要程度从低到高排序,依次以数字1到M标注每个地点的重要程度,指挥部将选择M个士兵依次进入指定地点进行防守任务,能力指数为X的士兵防守重要程度为Y的地点将得到X*Y的参考指数。现在士兵们排成一排,请你选择出连续的M个士兵依次参加防守,使得总的参考指数值最大。
问题案例说明 我们先取6个士兵、3个防守地点简单分析下该问题 3个防守地点重要度分别为:1、2、3 6个士兵的能力指数分别为:1、3、2、3、4、2 则会有4组总参考指数: S1=1*1+2*3+3*2=13; S2=1*3+2*2+3*3=16; S3=1*2+2*3+3*4=20; S4=1*3+2*4+3*2=17;
问题分析 • 从上面的案例中,我们可以看出,这个问题就是用M个有序数值(1、2、3…M)去遍历N个数值(X1、X2…Xn),数值相乘后取最大和,即求Smax最大值。 • Smax=X1+2*X2+3*X3+…+M*Xm
一般解题方法 Int Smax=0; Int Si=0; For (int i=1;i<N-M+1;i++) { Si=X1+2*X2+3*X3+…+M*Xi; If (Si>Smax)Smax=Si; } (该方法核心算法中包含M-1个乘法,M-1个加法,并循环N-M+1次)
根据我们第一节课的内容,知道可以通过减少乘法运算减少时间复杂度,现在我们尝试一下是否能够做到。根据我们第一节课的内容,知道可以通过减少乘法运算减少时间复杂度,现在我们尝试一下是否能够做到。 Si=Xi+2*Xi+1+3*Xi+2+…+M*Xi+m; Si+1= Xi+1+2*Xi+2+3*Xi+3+…+M*Xi+m+1 推出:Si+1-Si=(Xi+1+2*Xi+2+3*Xi+3+…+M*Xi+m+1)-(Xi+2*Xi+1+3*Xi+2+…+M*Xi+m) =M*Xi+m+1-( Xi+ Xi+1+..+ Xi+m) 所以:Si+1=Si+M* Xi+m+1-( Xi+..+ Xi+m) 设Li= Xi+..+ Xi+m=> Li+1= Li+Xi+m+1-Xi 所以:Si+1=Si+M* Xi+m+1-( Li+Xi+m+1-Xi);
优化后的算法 • // nM阵地数,nN士兵数 • for(intj=1;j<=nM;j++) • {//第一个防御指数 • nX+=p[j-1]*j; • nL+=p[j-1]; • } • nMax=nX; • for(i=1;i<nN-nM+1;i++) • { //循环中5个加法,1个乘法 • nX=nX+ nM*p[i+nM-1 ]-nL; • nL=nL+p[i+nM-1]-p[i-1]; • if(nMax<nX) • nMax=nX; • nD=0; • } • cout<<nMax<<endl;
2个算法简单对比 • 我们仅比较for循环中的算法 • 算法1: M-1个乘法,M-1个加法 • 算法2:循环中5个加法,1个乘法 • 从上面看出,当M取值较大时,算法2优化明显。
完整代码 • #include <iostream> int nD = 0; • #include <string> for (int j=1; j<=nM; j++) • using namespace std; {// 先计算第一个防御指数 • int main(int argc, char* argv[]) nX += p[j-1] * j; • { nL+=p[j-1]; • int nN = 0; } • int nM = 0; nMax = nX; • int nL=0; for (i=1; i<nN-nM+1; i++) • cin >> nN; { • cin >> nM; nD= nM*p[i+nM-1]; • int* p = new int[nN]; nX= nX+nD- nL; • for (int i=0; i<nN; i++) nL = nL +p[i+nM-1]-p[i-1]; • { if (nMax < nX) • cin >> p[i]; nMax= nX; • } nD = 0; • } • int nX = 0; • int nMax = 0; cout << nMax<<endl; • return 0; • }
算法的优缺点分析和改进 但是在提交程序中,仍然有6组测试超时,初步怀疑cin在大数据输入下效率低。后面大数据输入时,我会尝试用scanf 。 谢谢大家!