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) {
11         for (int i=0; i<chosen.size(); ++i)
12             printf("%d ", chosen[i]);
13         cout<<endl;
14         return;
15     }
16     calc(x+1);
17     chosen.push_back(x);
18     calc(x+1);
19     chosen.pop_back();
20 }
21 int main() {
22     cin>>n;
23     calc(1);
24     return 0;
25 }

【例题】CH0302 递归实现组合型枚举

在前面的基础上加入以下代码即可:

if (chosen.size()>m||chosen.size()+(n-x+1)<m)
    return;

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 using namespace std;
 7 int n, m;
 8 vector<int> chosen;
 9 void calc(int x) {
10     if (chosen.size()>m||chosen.size()+(n-x+1)<m)
11         return;
12     if (x==n+1) {
13         for (int i=0; i<chosen.size(); ++i)
14             printf("%d ", chosen[i]);
15         cout<<endl;
16         return;
17     }
18     chosen.push_back(x);
19     calc(x+1);
20     chosen.pop_back();
21     calc(x+1);
22 }
23 int main() {
24     cin>>n>>m;
25     calc(1);
26     return 0;
27 }

【例题】CH0303 递归实现排列型枚举

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 using namespace std;
 7 int n;
 8 int order[20];
 9 int chosen[20];
10 void calc(int k) {
11     if (k==n+1) {
12         for (int i=1; i<=n; ++i)
13             printf("%d ", order[i]);
14         puts("");
15         return;
16     }
17     for (int i=1; i<=n; ++i) {
18         if (chosen[i]) continue;
19         order[k]=i;
20         chosen[i]=1;
21         calc(k+1);
22         order[k]=0;
23         chosen[i]=0;
24     }
25 }
26 int main() {
27     cin>>n;
28     calc(1);
29     return 0;
30 }

【例题】费解的开关

容易发现3个性质:

1.每个位置最多点击一次

2.固定了第一行,满足题意的点击方案只有一种,如第i行已被固定,第i位为1,则第i+1行该位置需要被点击

3.点击先后顺序不影响最终结果

所以用位运算枚举第一行的点击方案,再递推出2~5行的点击,最后判断第5行是否满足题意即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int g[10][10];
char nex[5][2]={{0,0},{0,-1},{-1,0},{1,0},{0,1}};

void turn(int x, int y) {
    for (int i=0; i<5; ++i) {
        int tx=x+nex[i][0];
        int ty=y+nex[i][1];
        if (tx>0&&tx<=5&&ty>0&&ty<=5)
            g[tx][ty]^=1;
    }
}

void print() {
    /*for (int i=1; i<=5; ++i) {
        for (int j=1; j<=5; ++j)
            printf("%1d", g[i][j]);
        printf("\n");
    }
    puts("");*/
}

int solve() {
    int ans=0x3f3f3f3f;
    for (int i=0; i<32; ++i) {
        int flag=1, tot=0;
        int tmp[10][10];
        memcpy(tmp, g, sizeof(tmp));
        for (int j=0; j<5; ++j)
            if ((i>>j)&1)    //如果第j位为1,则第一排的第j位需要被按一下
                { turn(1, j+1); tot++; print();/*printf("a\n");*/}
        for (int j=1; j<5; ++j) {
            for (int k=1; k<=5; ++k)
                if (g[j][k]==0)
                    { turn(j+1, k); tot++; print();/*printf("b\n");*/}
        }
        for (int j=1; j<=5; ++j)
            if (g[5][j]==0) flag=0;
        memcpy(g, tmp, sizeof(g));
        if (flag) ans=min(ans, tot);
        else continue;
    }
    if (ans>6) return -1;
    return ans;
}

int main() {
    //freopen("1.txt", "w", stdout);
    int T;
    scanf("%d", &T);
    while (T--) {
        for (int i=1; i<=5; ++i)
        for (int j=1; j<=5; ++j)
            scanf("%1d", &g[i][j]);
        printf("%d\n", solve());
    }
    return 0;
}
/*
1
11101
11101
11110
11111
11111
*/

原文地址:https://www.cnblogs.com/kkkstra/p/11104554.html

时间: 2024-10-05 03:33:52

0x02 递推与递归的相关文章

递推与递归

递归:函数调用自身的行为叫做递归. 递推:找到前一项与后一项的关系并且清楚其初始条件或者最终结果问题就可以解决问题,这种方法叫做递推. 递推的一般形式: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

递推与递归专题练习

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(isdi