本周进行了贪心&DP2的学习与训练。说是训练,其实是在本来模糊的概念上进行了理解以及思考,对于此部分内容还需要进一步的学习。
贪心算法
贪心算法位一种求最优解的方法,将复杂的问题层层分解为各个子问题,并对子问题进行分析,求取最优解。
贪心算法并不是从整体上考虑问题,而是局部最优解,且问题本身特性适用于贪心算法时可以得到最优解。(如果一个问题可以同时用几种方法解决,贪心算法应该是最好的选择之一)
当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。贪心算法对每个子问题的解决方案都做出选择且不能回退。
动态规划DP
动态规划是解决多阶段决策问题的一种方法。如果一类问题的求解过程可以分为若干个互相联系的阶段,在每一个阶段都需作出决策,并影响到下一个阶段的决策,则称其为“多阶段决策问题”。
其思想为:以每一步都是最优的来保证全局是最优的。
在解决DP问题时,关键需找到状态转移方程(递推关系式),同时思考如何以代码形式实现其过程。
1.都是一种推导算法
2.都是分解成子问题来求解,都需要具有最优子结构
1.贪心:每一步的最优解一定包含上一步的最优解,上一步之前的最优解则不作保留;
动态规划:全局最优解中一定包含某个局部最优解,但不一定包含前一个局部最优解,因此需要记录之前的所有的局部最优解
2.贪心:如果把所有的子问题看成一棵树的话,贪心从根出发,每次向下遍历最优子树即可(通常这个“最优”都是基于当前情况下显而易见的“最优”);这样的话,就不需要知道一个节点的所有子树情况,于是构不成一棵完整的树;
动态规划:动态规划则自底向上,从叶子向根,构造子问题的解,对每一个子树的根,求出下面每一个叶子的值,最后得到一棵完整的树,并且最终选择其中的最优值作为自身的值,得到答案
3.根据以上两条可以知道,贪心不能保证求得的最后解是最佳的,一般复杂度低;而动态规划本质是穷举法,可以保证结果是最佳的,复杂度高。
4.针对0-1背包问题:这个问题应比较选择该物品和不选择该物品,然后再作出最好选择,由此就导出许多互相重叠的子问题,所以用动态规划。
#include
#include
#include
#include
#include
#include
#include
#include
//#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
ll q,x[1000+10];
ll calculate(ll x)
{
q=0;
while(x%2==0)
{
x /= 2;
q++;
}
while(x%3==0)
{
x /= 3;
q+=2;
}
while(x%5==0)
{
x /= 5;
q+=3;
}
if(x==1)return q;
return -1;
}
int main()
{
ll n;
cin>>n;
for(int i=0;i>x[i];
for(int i=0;i
#include
using namespace std;
long long n,ans;
int main(){
int T;
cin >> T;
while(T--){
cin >> n;
ans = 0;
while(n % 2 == 0)n /= 2,ans++;
while(n % 3 == 0)n /= 3,ans += 2;
while(n % 5 == 0)n /= 5,ans += 3;
if(n == 1) cout << ans << endl;
else cout << -1 << endl;
}
return 0;
}
两种方法思路一致,但第二种方法无法实现输入全部数据后输出,不过也符合题目要求。
面对形形色色的问题,总是不知所措不知道代码该如何下手,其实解决问题的方法应由“寻找方法”为突破口,找到题目特征并分析,之后找到算法解决路径,最后由代码实现。现在的我们还是太菜了,接触问题少、下的功夫不够、缺乏原始积累,这都是所存在的问题,包括所学方法并没有完全掌握,还是处于一知半解的状态,并且与同学间还存在较大差距TAT。。。希望接下来的学习能提升自己的能力,不要成为拖后腿的那一员,加油。