暴力方法——打表求解

  有时候在竞赛中我们可能会碰到一种比较棘手的题目,这种题目数据较大且运算量较大,如果直接写解可能会致使时间复杂度变得很大,少则O(n2),多则O(nn),于是问题就来了,如何设计高效解法。但是在设计高效算法之前我们一般会考虑暴力求解,今天介绍一种方法——打表。什么是打表呢?打表按个人理解就是将要用到的尽可能多的数据先储存起来,在需要时再查询调用,查询调用的复杂度一般为O(C)(C for costant),比如说枚举阶乘,运算量及大,那么就可以直接打表储存。但是哲学观点告诉我们,这样的方法是有代价的,而打表的代价就是内存会非常非常大。不过联赛的内存限制一般是128M,是可以打表的。但一些高级的比赛会有spj(特判,如内存限制,长度限制,数据限制之类),因此打表只是一种就急的办法,平时做题最好还是考虑高效算法。

  下面举一个小例子——打素数表:

  一般来说我们判断素数的方法是使用谓词函数is_prime(详见LRJ《算法竞赛入门经典》)

1 int is_prime(int n)
2 {
3     if(n<2)return 0;
4     for(int i=2;i<=sqrt(n);++i)
5         if(n%i==0)return 0;
6     return 1;
7 } 

这种方法复杂度O(n),不过题目中加了条件需要枚举的话一般是O(n2)。

打一个素数表:

#define maxn 1000000
bool v[maxn];
int prime[maxn];
void input_prime(int n)
{
    memset(v,true,sizeof(v));
    int num = 0;
    for(int i=2;i<=n;++i)
    {
        if(v[i]==true)
        {
            num++;
            prime[num]=i;
        }
        for(int j=1;((j<=num)&&(i*prime[j]<=n));++j)
        {
            v[i*prime[j]] = false;
            if(i%prime[j]==0)break;
        }
    }
}

素数表就打好了,不过当数据比较小的时候两种算法复杂度是差不多的甚至筛法判定要容易,由数学知识易得:

f(x)=x2(x>0)与g(x)=C(C>0)由导数知识可知在(0,√c)时g(x)的变化率是大于f(x)的,在(√c,+∞)时f(x)变化率大于g(x)。

再拿一道题目来看看——某次苦逼的信息组考试题之人赢传说:

题目概况如下:看来是可以打表的,但是学长为了防止我们打表特意加了spj TAT。。。

题目描述如下:

乍一看这题目貌似很简单的样子,可以考虑维护(这个词看起来很有b格)一个递推数列,然后注意用一点快速幂的思想来取模即可,但看看这数据范围就吓尿了,

反正我是直接递推做的,只过了几个点。

显然这种数据范围真是太好打表了。。

这里还是把BBG学长的标准解法贴上来——

以及其std:

void numqueue()
{
    a%=MOD;b%=MOD;c%=MOD;n%=MOD;
    x=1;y=n;
    z=((((n*n)%MOD+n)%MOD)*5004)%MOD;
    p=(((2*(n*n)%MOD)*n)%MOD);
    q=((3*n*n)%MOD);
    w=(((p+q+n)%MOD)*1668)%MOD;
    ans=(((a*x)%MOD)+((b*y)%MOD)+((c*z)%MOD)+((d*w)%MOD))%MOD;
}

所谓的乘法逆元就体现在中间的对含除号的取模上。

时间: 2024-10-14 16:59:41

暴力方法——打表求解的相关文章

jquery的attr方法禁用表单元素

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <ti

使用val()方法设置表单中的默认选中项

有时候我们展示给用户的表单中的checkbox,radio,selec等标签的一些项是默认选中的.比方:当用户改动文章的时候,假设相应的栏目为下拉框的话,那么它的默认选中值应该是原来的栏目位置. 能够使用jquery中的val()方法给select.checkbox.radio设置默认选中项. 对于multiple类型的select和checkbox还能够设置多个默认值. 效果图: 方法: $("select#multiple").val(["选择2号","

表单的属性和方法, 获取表单和表单的元素, 验证表单

表单的属性和方法 一. 表单字段的属性(id/name/value/form),这里用value属性来举例 上面的form属性代表获取表单字段的父级表单对象 1. 属性的获取         console.log(document.myform.username.value); 2. 属性的设置            document.myform.username.value="123"; 3. 获取表单字段的父级表单对象 console.log(document.myform.u

MVC中使用内建的HTML辅助方法产生表单元素提交表单与button按钮事件的陷阱

网站模板页有个登陆的退出按钮,当点击时跳转到登陆页面. <button onclick="logout()" >退出</button> $("#logOut").click(function () { location.href = "@Url.Action("Logout", "Account")"; }); 然后再某个页面楼主用了HTML辅助方法产生表单元素,代码如下所示: @H

jQuery form插件的使用--使用 fieldValue 方法校验表单

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>jQuery form插件的使用--使用 fieldValue 方法校验表单.</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-

jQuery使用serialize(),serializeArray()方法取得表单数据+字符串和对象类型两种表单提交的方法

原始form表单值获取方式(手动): $.ajax({ type: "POST", url: "ajax.php", data: "Name=摘取天上星&position=IT技术", success: function(msg){alert(msg);}, error: function(error){alert(error);} }); JQ serialize()方法取值: $.ajax({ type: "POST&quo

在自定义的js验证规则中调用magento的VarienForm方法验证表单

js部分<script type="text/javascript"> //<![CDATA[ var loginForm = new VarienForm('login-form', true); $('login-email').observe('keypress', bindLoginPost); $('login-password').observe('keypress', bindLoginPost); function bindLoginPost(evt)

django1.11如何用post方法提交表单

django为了帮助应对跨站脚本攻击,在以POST方法提交表单时,要求将其内置的CSRF中间件添加到setting.py的中间件设置中(django.middleware.csrf.CsrfViewMiddleware,默认已添加),并且在<form>标签后添加{% csrf_token %},即表单元素变为: <form action="" method="post">{% csrf_token %} 同时,表单提交对应的视图函数也要调用R

jquery中$.ajax方法提交表单

function postdata(){                        //提交数据函数 $.ajax({                                //调用jquery的ajax方法 type: "POST",                       //设置ajax方法提交数据的形式 url: "ok.php",                      //把数据提交到ok.php data: "writer=