UVa1374 快速幂计算——解答树

该博客通过UVa1374题目深入探讨快速幂计算,并结合解答树阐述问题解决思路,旨在帮助读者更好地理解和应用这两种算法。


前言

我认为这个题目可以很深刻地理解好解答树,更好地理解好树状的搜索。


一、看题解前后我的思路

在没有看题解之前虽然很容易判断这应该是涉及到解答树,利用迭代加深方法,但是一是没有想好怎么剪枝,二是把每一次深度加深之后得到的新的数都全部塞进数组,认为下一个深度都有可能用到,所以我一开始创建一个二维数组,行表示深度,列表示上一行的所有数可以通过加减(指数乘即是加,除即是减)得到。但完全没有意识到把状态看成结点,每个结点在每一个深度都只有一次加或者减运算,也就是说,从根到特定的叶是唯一的路径,因此完全只用一维数组即可,一维数组的每个序位表示那个深度下的该路径上的结点的值(该结点的状态可以看成是这条路径上到改结点为止的所有结点值组成的一个不定长数组),而且可以运用到八皇后问题里面的思想,即上面深度的数值之间的加减不用再去考虑,只需考这一层新增的结点值(通过上一层递归传入参数)与上面深度的加减,每一个结点下面可以有很多儿子,每一个儿子都是这一个结点与上面同一条路径上的其他结点的加减值,可以看出结点的儿子数随深度递增。但是可以想象的出这颗解答树会有多么庞大,因此必须要剪枝,那么如何剪枝呢,看完题解之后,我认为可以用到乐观函数(经常和迭代加深一起使用),思路主要是当前路径所经过的结点上(因为有减所以不一定是最深的结点值最大)最大的结点倍增(即与自己相加),多少次呢,是当前结点深度离maxd的距离,因为如果这样都不能达到目标值,这条路径肯定不能得到目标值(大+大都不能得到,大+小更不能得到)。因此这就是整体思路,我认为这个思路中最重要的有三点:①树的思想,路径的思想②八皇后问题思想,即上面结点之间的关系再也不用去考虑③乐观函数剪枝,这经常和迭代加深一起使用。

二、代码

代码如下:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import  ssl
ssl._create_default_https_context = ssl._create_unverified_context

2.读入数据

代码如下(示例):

#include<iostream>
#include<cstdio>
#include<queue>
#include<set>
#define maxn 1000
print(data.head())

using namespace std;

int n, maxd, num[maxn];
bool dfs(int now, int dep)
{
 if (now < 0)
  return false;
 if (now == n)
  return true;
 if (dep == maxd)
  return false;
   num[dep] = now;
 int maxv = num[0];
 for (int i = 0; i <= dep; i++)
  maxv = maxv > num[i] ? maxv : num[i];
 if((maxv<<(maxd-dep))<n)
  return false;
 for (int i = dep; i >= 0; i--)
 {
  if (dfs(now + num[i], dep + 1))
   return true;
  if (dfs(now - num[i], dep + 1))
   return true;
 }
 return false;
}

void solve()
{
 num[0] = 1;
 for (maxd = 1; !dfs(1, 0); maxd++);
}

int main()
{
 scanf_s("%d", &n);
 solve();
 printf("%d", maxd);
 return 0;
}

总结

加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值