最大乘数

44 篇文章 0 订阅
17 篇文章 0 订阅

 

题目:给出N个1-9的数字(v1,v2,…,vN),不改变它们的相对位置,在中间加入K个乘号和N-K-1个加号,(括号随便加)使最终结果尽量大。因为乘号和加号一共就是N-1个了,所以恰好每两个相邻数字之间都有一个符号。并说明其具有优化子结构性质及子问题重叠性质。(20分)

例如: N=5, K=2,5个数字分别为1、2、3、4、5,可以加成:

1*2*(3+4+5)=24

1*(2+3)*(4+5)=45

(1*2+3)*(4+5)=45

 

S(T,start,len)表示在T序列中从start位置开始 len个元素的和

 F(T,start,len,num)表示在序列T中,从start位置开始len个长度的的元素中插入num个乘号的最大值


F(T,start,len,num) = max{ S(T,start,leftlen) * F(T, leftlen,len-leftlen,mulcount-1) }

 

最优子结构性质: F(T,start,len,num) = max{S(T,start,leftlen) * F(T, leftlen,len-leftlen, mulcount-1) }    假设F(T, leftlen,len-leftlen,mulcount-1) 不是最大的 则存在

F’ (T, leftlen,len-leftlen,mulcount-1)> F(T, leftlen,len-leftlen, mulcount-1)

S(T,start,leftlen)* F’(T, leftlen,len-leftlen, mulcount-1)> S(T,start,leftlen) * F(T, leftlen,len-leftlen,mulcount-1)

则存在F’(T,start,len,num)> F(T,start,len,num)  则 F(T,start,len,num)不是最大的与条件矛盾 所以F(T, leftlen,len-leftlen,mulcount-1)是最大的 所以具有最优子结构的性质

 

 

                           F(T,1,5,2)

 

  F(T,2 ,5,1)               F(T,3,5,1)                      F(T,4,5,1)

 


F(T,3,5,0)     F(T,4,5,0)  F(T,5,5,0)

 

 

 

所以具有子问题的重叠性

// maxnum.cpp : Defines the entry point for the console application.

//

//F(start,len,multinum) 代表从start位置开始 len个元素长度multinum个乘号的的最大值

//S(start,len)代表从start位置开始len个元素的和

//Fstart,len,multinum=max{S(start,leftlen)*F(start+leftlen,len-leftlen,multinum-1)1<=leftlen<=len

// 如果len-1<multinum F(start,len,multinum)=0 

//如果multinum=0 Fstart ,len,multinum=S(start,len)

#include "stdafx.h"

// maxnum.cpp : Defines the entry point for the console application.

//

//F(start,end,multinum) 代表从start位置开始到end位置结束multinum个乘号的的最大值

//S(start,end)代表从start位置开始到end位置结束的和

//Fstart,end,multinum=max{S(start,middle)*F(middle+1,end,multinum-1)start=<middle<=end;

//如果multinum=0 Fstart ,end,multinum=S(start,end)

#include "stdafx.h"

#include <iostream>

#include <cstdlib>

#include <vector>

using namespace std;

 

class SeekMax

{

public:

    SeekMax(int num );

    SeekMax(SeekMax&s);//copy constructor

    ~SeekMax();

    int Seek();//Seek the max multiplication number

private:

    vector <int> list;

    int multinum;

    int S(int start, int end);

    int F(int start, int end, int m);

};

 

SeekMax::SeekMax(int num )

{

    multinum = num;

    int temp;

    while (1)

    {

        cin >> temp;

        if (temp == -1)break;

        list.push_back(temp);

    }

}

 

SeekMax::SeekMax(SeekMax&s)

{

    multinum = s.multinum;

    list.clear();

    for (auto a = s.list.begin(); a != s.list.end(); a++)

        list.push_back(*a);

}

 

SeekMax::~SeekMax()

{

    list.clear();

}

 

int SeekMax::Seek()

{

    return F(0, list.size()-1, multinum);

}

 

int SeekMax::S(int start, int end)

{

    int sum = 0;

    for (int i = start; i <=end; i++)

    {

        sum += list[i];

    }

    return sum;

}

int SeekMax::F(int start, int end, int m)

{

    if (start >end)return 0;

    if (end-start+1-1< m)return 0;//从下标start 开始到下标end 最多能放下end-start+1-1个乘法符号 

    int middle, temp, max;

   

    if (m == 0)//没有乘号的话直接计算加法的总值

        return S(start, end);

   

    max = 0;

    for ( middle= start; middle<=end; middle++)

    {

        temp = S(start,middle)*F(middle+1, end, m - 1);

            if (temp > max)

                max = temp;

       

    }

    return max;

}

int main(int argc, char **argv)

{

    SeekMax myseek(2);

    cout << "the max multiplication is" << myseek.Seek() << endl;

    system("pause");

    return 0;

}

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hebastast

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值