递推与递归专题练习

CH0301 递归实现指数型枚举

搜索与回溯,指数级算法。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;
vector<int>chosen;
int n;
void dfs(int x){
    if(x==n+1){
        for(unsigned i=0;i<chosen.size();++i)
            printf("%d ",chosen[i]);
        puts("");
        return;
    }
    dfs(x+1);
    chosen.push_back(x);
    dfs(x+1);
    chosen.pop_back();
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);
    dfs(1);
    return 0;
}

CH0302 递归/非递归实现组合型枚举

搜索与回溯。要字典序最小,所以优先往加入当前节点的分支搜索。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;
vector<int> chosen;
unsigned n,m;
void dfs(unsigned x){
    if(chosen.size()>m||chosen.size()+(n-x+1)<m)
        return;
    if(x==n+1){
        for(unsigned i=0;i<chosen.size();++i)
            printf("%d ",chosen[i]);
        puts("");
        return;
    }
    chosen.push_back(x);
    dfs(x+1);
    chosen.pop_back();
    dfs(x+1);
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n),read(m);
    dfs(1);
    return 0;
}

CH0303 递归实现排列型枚举

搜索与回溯

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
int n,order[11];
bool chosen[11];
void dfs(int x){
    if(x==n+1){
        for(int i=1;i<=n;++i)
            printf("%d ",order[i]);
        puts("");
        return;
    }
    for(int i=1;i<=n;++i)if(!chosen[i]){
        chosen[i]=1,order[x]=i;
        dfs(x+1);
        chosen[i]=0;
    }
}
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(n);
    dfs(1);
    return 0;
}

CH0201 费解的开关

描述

你玩过“拉灯”游戏吗?25盏灯排成一个5x5的方形。每一个灯都有一个开关,游戏者可以改变它的状态。每一步,游戏者可以改变某一个灯的状态。游戏者改变一个灯的状态会产生连锁反应:和这个灯上下左右相邻的灯也要相应地改变其状态。

我们用数字“1”表示一盏开着的灯,用数字“0”表示关着的灯。下面这种状态

10111
01101
10111
10000
11011

在改变了最左上角的灯的状态后将变成:

01111
11101
10111
10000
11011

再改变它正中间的灯后状态将变成:

01111
11001
11001
10100
11011

给定一些游戏的初始状态,编写程序判断游戏者是否可能在6步以内使所有的灯都变亮。

做法

游戏有三个性质:

  1. 每个位置至多被点击一次。
  2. 若固定的第一行的点法,则满足题意的方案至多有一种。
  3. 点击的顺序不影响最终结果。

于是枚举第一行的点法,从第一行开始递推。

时间复杂度\(O(2^n n^2)\)。

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
co int N=10;
int g[N][N],n,ans,tmp[N][N];
void change(int x,int y){
    tmp[x][y]^=1;
    if(x-1) tmp[x-1][y]^=1;
    if(y-1) tmp[x][y-1]^=1;
    if(y+1<=n) tmp[x][y+1]^=1;
    if(x+1<=n) tmp[x+1][y]^=1;
}
int t;
char s[N];
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    read(t);
    n=5;
    while(t--){
        ans=25;
        for(int i=1;i<=n;++i){
            scanf("%s",s+1);
            for(int j=1;j<=n;++j)
                g[i][j]=(s[j]-'0')^1;
        }
        for(int s=0;s<(1<<n);++s){
            for(int i=1;i<=n;++i)
                for(int j=1;j<=n;++j)
                    tmp[i][j]=g[i][j];
            bool ok=1;
            int tmp=s,k=1,cnt=0;
            while(tmp){
                if(tmp&1) change(1,k),++cnt;
                ++k,tmp>>=1;
            }
            for(int j=2;j<=n;++j)
                for(k=1;k<=n;++k)if(::tmp[j-1][k])
                    change(j,k),++cnt;
            for(int j=1;j<=n;++j) if(::tmp[n][j]){
                ok=0;
                break;
            }
            if(ok) ans=std::min(ans,cnt);
        }
        if(ans>6) puts("-1");
            else printf("%d\n",ans);
    }
    return 0;
}

POJ1958 Strange Towers of Hanoi

题意:解出n个盘子4座塔的汉诺塔问题最少需要多少步?

  • 3塔问题的递推公式:
    \[
    d[n]=2*d[n-1]+1
    \]
    表示n-1个从A到B,第n个到C,n-1个从B到C。
  • 4塔问题的递推公式:
    \[
    f[n]=\min_{i=1}^{n-1}\{2*f[i]+d[n-i]\}
    \]
    表示i个从A到B,n-i个从A到D,i个从B到D。

可推广至n盘m塔的计算。

#include<cstdio>
#include<iostream>
#include<cstring>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
co int N=13;
int n=12,d[N],f[N];
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    for(int i=1;i<=n;++i)
        d[i]=2*d[i-1]+1;
    memset(f,0x3f,sizeof f);
    f[0]=0;
    for(int i=1;i<=n;++i)
        for(int j=0;j<i;++j)
            f[i]=std::min(f[i],2*f[j]+d[i-j]);
    for(int i=1;i<=n;++i)
        printf("%d\n",f[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/autoint/p/10386686.html

时间: 2024-10-12 23:44:47

递推与递归专题练习的相关文章

递推与递归

递归:函数调用自身的行为叫做递归. 递推:找到前一项与后一项的关系并且清楚其初始条件或者最终结果问题就可以解决问题,这种方法叫做递推. 递推的一般形式:f(n)=a1f(n-1)+a2f(n-2)+...anf(1)+an+1 转: 一般步骤: 1.设函数f(i)的含义 2.从逻辑上寻找f(i)与f(i-1),f(i-2)等等之间的关系 3.写出递推式 4.写出目标f(n) 5.写出初始值(边界)f(0) 6.验证正确性 递推与递归的 相似点: 1.都是把问题拆分成可以解决的子问题 2.一般分析

【递推与递归】极值问题

[递推与递归]极值问题 题目描述 已知m.n为整数,且满足下列两个条件: (1)m.n∈1,2,3,……,k,即1≤m,n≤k (2)(n2-mn-m2)2=1 你的任务是:编程由键盘输入正整数k(1≤k≤109),求一组满足上述两个条件的m.n,并且使m2+n2的值最大. 输入 一个正整数k 输出 按照格式输出对应的m和n的值 样例输入 1995 样例输出 m=987 n=1597 分析:斐波那契数(可归纳证明)代码: #include <iostream> #include <cst

对递推和递归的理解

对递推和递归的理解 1.此问题能否用递推解决 我们以斐波拉契数列问题为例进行阐述,斐波拉契数列为0.1.1.2.3.5.8.13.21.-表现斐波拉契数列为瘦柱状图的形式,如下 我们现在所要解决的问题是求取第n个位置的数值,下面我们正式开始考虑能否用递推解决这个问题(关于递推和递归的区别,将会在下文阐述): 我们考察3号位置,我们发现3号位置的值依赖于1号位置和2号位置,即在1号位置的值和2号位置的值的基础上,我们再进行一些(一个)操作就可以得到3号位置的值.在本例中,这个操作为加法运算. 我们

JC2:递推,递归与分治

递推,递归与分治[待完成] 递推的定义 定义:已知初始值F1,通过递推关系式Fn=g(Fn-1)求出最终结果Fn的递推方式称为顺推法:同理,把已知最终结果为Fn,通过递推关系式Fn-1=g'(Fn)求出初始值F1的递推方式称为倒推法. 模板: f[0]=0; f[1]=1; for(int i=1; i<=n; i++) f[i]=f[i-1]+f[i-2]; 具体步骤 找到初始状态 找到递推公式 开始循环算 经典问题 抽屉原理 加法原理 乘法原理 容斥原理 卡特兰数 递归 递归算法 设一个未知

从一道NOI练习题说递推和递归

一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可以一步上2阶,也可以一步上3阶,编程计算共有多少种不同的走法. 这个问题可以用递归来进行解决,但是解题时间1秒明显不够用.怎么办呢,可以考虑找到“规律”,然后推导公式解决问题,开始画图分析: 这是4个台阶时的全部7种走法,记作f(4)=7.现在观察右侧绿色走过的部分,1234四种情况是3个台阶时的4种走,法记

递推和递归

一.递推算法基本思想: 递推算法是一种理性思维模式的代表,其根据已有的数据和关系,逐步推导而得到结果.递推算法的执行过程如下: 1)根据已有的·结果和关系,求解中间结果 2)判定是否达到要求,如果没有达到,则继续根据已知结果和关系求解中间结果:如果满足要求,则表示寻找到一个正确的答案. 递推算法往往需要用户知道答案和问题之间的逻辑关系.在许多数学问题中,都有着明确的计算公式可以遵循,因此往往可以采用递推来实现. 2.递推算法示例 如果一对两个月大的兔子以后每个月可以生一对兔子,而一对新生的兔子出

使用递推和递归解决斐波那契数列问题~~~

/** * 使用递推的方式处理斐波那契数列 * @param sum * @param i * @return */ public static int findValue(int n){ if(n==1) { return 1; } if(n==2) { return 2; } int sum=1; int pre=1; for(int i=3;i<=n;i++) { int temp=sum; sum+=pre; pre=temp; } return sum; } /** * 采用递归的方式

poj1163 - DP递推、递归写法

本题超链接:http://poj.org/problem?id=1163 The Triangle Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 50977   Accepted: 30888 Description 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5(Figure 1) Figure 1 shows a number triangle. Write a program that calculat

0x02 递推与递归

[例题]CH0301 递归实现指数型枚举 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <vector> 6 using namespace std; 7 int n; 8 vector<int> chosen; 9 void calc(int x) { 10 if (x==n+1) {