• 【剑指offer】剪绳子


    题目链接:剪绳子

     

    题意:给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m]。请问k[0]xk[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

     

    题解:

    1、dp做法。每段绳子都能分割成它的乘积。因此,动态转移方程dp[i] = max{dp[i],dp[j] * dp[i-j]}.

    这里要注意的是,绳长 = 2 / 3时,它们是必须要分割的(m>1),所以特殊讨论。

    len = 2,分割就是 1 1,所以乘积为1。

    len = 3,分割就是 1 2,所以乘积为2 。

    一旦len>3了,那前面的就相当于是作为len里的分割元素,也就是dp[2]=2,dp[3]=3.

    2、贪心。每个数字(>3)都能分解成有n个2和n个3的相加。举例,

    4:2+2

    5:2+3

    6:3+3

    7:2+2+3

    8:2+2+2+2

     所以我们直接贪心,看数字里含多少个3再去看除去3以后含多少个2。

    要考虑一下有4的情况,此时要分解成2+2而不是1+3。因此对于像7,10这种数,做一个特判。

    代码:

     1 class Solution {
     2 public:
     3     int dp[105]={0};
     4     int cutRope(int number) {
     5         if(number == 2)    return 1;
     6         if(number == 3)    return 2;
     7         dp[0] = 0; dp[1] = 1;
     8         dp[2] = 2; dp[3] = 3;
     9         for(int i = 4 ;i <= number; i++){
    10             for(int j = 1; j <= i/2; j++){
    11                 dp[i] = max(dp[i],dp[j]*dp[i-j]);
    12             }
    13         }
    14         return dp[number];
    15     }
    16 };
    17 
    18 
    19 OR
    20 
    21 
    22 class Solution {
    23 public:
    24     int cutRope(int number) {
    25         if(number == 2)    return 1;
    26         if(number == 3)    return 2;
    27         int cnt = number/3;    //含3的个数
    28         if(number - cnt*3 == 1)    //保证最后有4的情况是2*2
    29             cnt--;
    30         int cntt = (number - 3*cnt)/2;    //2的个数
    31         int ans = pow(3,cnt)*pow(2,cntt);
    32         return ans;
    33     }
    34 };
  • 相关阅读:
    11.变分推断
    10.高斯混合模型GMM
    9.EM 算法
    8.指数族分布
    7.概率图模型(表示/推断/学习)
    6.核方法
    二分查找
    2.3 数据结构---数组(连续)
    C#开发Windows服务的基础代码
    C#与C++之间类型的对应{转}
  • 原文地址:https://www.cnblogs.com/Asumi/p/12431518.html
Copyright © 2020-2023  润新知