动态规划也是一种分治思想,但与分治算法不同的是,分治算法是把原问题分解为若干子问题,自顶向下,求解各子问题,合并子问题的解从而得到原问题的解。动态规划也是自顶向下把原问题分解为若干子问题,不同的是,然后自底向上,先求解最小的子问题,把结果存储在表格中,在求解大的子问题时,直接从表格中查询小的子问题的解,避免重复计算,从而提高算法效率。 什么时候要用动态规划? 如果要求一个问题的最优解(通常是最大值或者最小值),而且该问题能够分解成若干个子问题, 并且小问题之间也存在重叠的子问题,则考虑采用动态规划。 怎么使用动态规划? 1. 判题题意是否为找出一个问题的最优解 2. 从上往下分析问题,大问题可以分解为子问题,子问题中还有更小的子问题 3. 从下往上分析问题 ,找出这些问题之间的关联(状态转移方程) 4. 讨论底层的边界问题 5. 解决问题(通常使用数组进行迭代求出最优解) 例题:给你一根长度为 n 的金条,请把金条剪成 m 段 (m 和 n 都是整数,n>1 并且 m>1)每断金条的长度记为 k[0],k[1],…,k[m].请问 k[0] k[1]…*k[m]可能的最大乘积是多少? 思路:1.首先,根据题意我们可以知道金条的长度和段数都要大于1,也就是说段数要从2开始;2.又因为金条的长度和段数都是整数,所以段数的范围是2~n,比如一根10cm的金条,最多能分成10段,每段1cm;3.接下来我们找找关联的子问题,当金条的长度小于2时,无法继续划分,最大的乘积返回0;当金条的长度为2时,可分为2段,每段的长度为1,最大的乘积即为1;当金条的长度为3时,可分为2段,一段长度为1,一段长度为2,最大的乘积即为2;4.最后我们来找找当金条长度大于3时的最大的乘积有何规律。
#include <iostream> #include <Windows.h> using namespace std; long long getMaxMul(int n) { if (n < 2) return 0; if (n == 2) return 1; if (n == 3) return 2; long long * k = new long long[n+1]; k[0] = 0; k[1] = 1; k[2] = 2; k[3] = 3; for (int i = 4; i <= n; i++) { long long max = 0; for (int j = 1; j <= i / 2; j++) { long long ret = k[j] * k[i-j]; if (max < ret) { max = ret; } } k[i]=max; } return k[n]; delete[] k; } int main() { int n = 0;//n为金条长度 cout << "请输入金条的长度:"; cin >> n; cout << "可能的最大乘积是:" << getMaxMul(n) << endl; system("pause"); return 0; }标签:问题,乘积,long,金条,算法,长度 From: https://www.cnblogs.com/smartlearn/p/17602798.html