记忆化搜索(Function,天下第一)

2024-03-01 04:36

本文主要是介绍记忆化搜索(Function,天下第一),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Function

这是一道很直观的递归题目,但是使用递归会导致时间超限,所以需要使用记忆化搜素。
首先把坑点讲一下:出题人会给出负数,而我们知道数组下标是不能有负数的,如果是二维数组还可以用map数组进行储存,但是这个函数是有三个变量,所以就只能使用三维数组了,这也就意味着在dfs函数的最前面我们需要进行特判,看这个数组下标是否处于正数,如果是正数我们就直接返回数组的值,如果是负数那么我们就用递归来搞定

代码如下:

#include<iostream>
#include<cstdio>
#include<stdlib.h>using namespace std;
typedef  long long ll;
ll wa[40][40][40];
ll w(ll a,ll b,ll c)
{if(a<=20&&b<=20&&c<=20&&a>=0&&b>=0&&c>=0)if(wa[a][b][c]){return wa[a][b][c];}if(a<=0||b<=0||c<=0)return 1;if(a>20||b>20||c>20)return w(20,20,20);if(a<b&&b<c)return wa[a][b][c]=w(a,b,c-1)+w(a,b-1,c-1)-w(a,b-1,c);return wa[a][b][c]=w(a-1,b,c)+w(a-1,b-1,c)+w(a-1,b,c-1)-w(a-1,b-1,c-1);
}
int main()
{ll a,b,c;while(1){cin>>a>>b>>c;if(a==-1&&b==-1&&c==-1)return 0;elseprintf("w(%lld, %lld, %lld) = %lld\n",a,b,c,w(a,b,c));}return 0;
}

 天下第一

这个题目是个什么意思呢? 在最开始我写这道题的时候看不懂。

就是在我们递归的时候,第一个函数变量放的是(x+y)%mod;  这个就为新的x 那么新的y就是((x+y)%mod+y)%mod 所以是不需要进行分奇偶讨论的,直接这样。

刚刚讲的是这个题目的坑点之一,接下来是第二个坑点:

数据大小,这个的数据大小比较小,而题目卡这个数据很死,所以我们就将最耗空间的二维数组开为short类型。

第三就是error的判断:如果一个数已经出现过了,那么再一次出现就说明进入了死循环,这个时候就分不出胜负了,所以将重复出现的数进行标记,标记为-1,将这个特判条件放在第一位,如果为-1,直接返回-1,再在主函数进行分类讨论

代码如下

#include<iostream>
#include<cstdio>
using namespace std;
int n,mod;short a[10010][10010];
int dfs(int x,int y)
{if(a[x][y]==-1) return -1;if(a[x][y]) return a[x][y];a[x][y]=-1;if(x==0) return a[x][y]=1;if(y==0) return a[x][y]=2;int tmp=(x+y)%mod;return a[x][y]=dfs(tmp,(tmp%mod+y)%mod);
}
int main()
{cin>>n>>mod;int x,y;for(int i=1;i<=n;i++){cin>>x>>y;if(dfs(x,y)==1)printf("%d\n",1);if(dfs(x,y)==2)printf("%d\n",2);if(dfs(x,y)==-1)printf("error\n");}return 0;
}

这篇关于记忆化搜索(Function,天下第一)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/761231

相关文章

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

C# ComboBox下拉框实现搜索方式

《C#ComboBox下拉框实现搜索方式》文章介绍了如何在加载窗口时实现一个功能,并在ComboBox下拉框中添加键盘事件以实现搜索功能,由于数据不方便公开,作者表示理解并希望得到大家的指教... 目录C# ComboBox下拉框实现搜索步骤一步骤二步骤三总结C# ComboBox下拉框实现搜索步骤一这

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

AutoGen Function Call 函数调用解析(一)

目录 一、AutoGen Function Call 1.1 register_for_llm 注册调用 1.2 register_for_execution 注册执行 1.3 三种注册方法 1.3.1 函数定义和注册分开 1.3.2 定义函数时注册 1.3.3  register_function 函数注册 二、实例 本文主要对 AutoGen Function Call

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

js私有作用域(function(){})(); 模仿块级作用域

摘自:http://outofmemory.cn/wr/?u=http%3A%2F%2Fwww.phpvar.com%2Farchives%2F3033.html js没有块级作用域,简单的例子: for(var i=0;i<10;i++){alert(i);}alert(i); for循环后的i,在其它语言像c、java中,会在for结束后被销毁,但js在后续的操作中仍然能访