代码题 — 剑指offer题目、新增题目

 1、剪绳子

  给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],...,k[m].请问k[0]*k[1]*...*k[m]可能的最大乘积是多少?

例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3的三段,此时得到的最大乘积是18.

  解题思路:
本题有动态规划算法的几个明显特征:
(1)是求最优解问题,如最大值,最小值;
(2)该问题能够分解成若干个子问题,并且子问题之间有重叠的更小子问题。
通常按照如下4个步骤来设计一个动态规划算法:
(1)刻画一个最优解的结构特征;
(2)递归地定义最优解的值;
(3)计算最优解的值,通常采用自底向上的方法;
(4)利用计算出的信息构造一个最优解。
以此题为例,我们定义长度为n的绳子剪切后的最大乘积为f(n),剪了一刀后,f(n)=max(f(i)*f(n-i));假设n为10,第一刀之后分为了4-6,而6也可能再分成2-4(6的最大是3-3,但过程中还是要比较2-4这种情况的),而上一步4-6中也需要求长度为4的问题的最大值,可见,各个子问题之间是有重叠的,所以可以先计算小问题,存储下每个小问题的结果,逐步往上,求得大问题的最优解。

 

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include <vector>
#include<string>
#include<sstream>
#include<map>
#include<set>
#include <functional> // std::greater
using namespace std;

int main()
{
    int len;
    cin >> len;
    vector<int> vec(len+1,1);
    
    int res = 0;
    if (len < 2)
        return 0;
    if (len == 2)
        return 1;
    if (len == 3)
        return 2;
    vec[0] = 0;
    vec[1] = 1; 
    vec[2] = 2;//作为绳子的一段时,本身就是最大的
    vec[3] = 3;
    for (int i = 4; i <= len; ++i)
    {
        int maxlen = 0;
        for (int j = 1; j <= i / 2; ++j)
        {
            int num = vec[j] * vec[i - j];
            maxlen = max(maxlen, num);
        }
        vec[i] = maxlen;
    }
    cout << vec[len];
    return 0;
}

 

2、

 

posted @ 2018-08-27 19:29  深度机器学习  阅读(207)  评论(0编辑  收藏  举报