栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

算法设计分析之------ 递推与递归篇二

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

算法设计分析之------ 递推与递归篇二

递推与递归篇二
  • 递归
    • Secret Cow Code S
    • 黑白棋子的移动
  • 递推(动态规划)
    • 覆盖墙壁

递归 Secret Cow Code S

题目链接:Secret Cow Code S

解题思路
如果我们按照正常的递归思路写,如下代码,由于n太大,会tle。

void solve(string ss){
    long long len = ss.size();
    if(len >= n){
        ans = ss[n-1];
        return ;
    }
    tp = ss[len-1];
    tp += ss.substr(0,len - 1);
    ss += tp;
    solve(ss);
}

因此我们需要换一个思路,由题目我们知道生成的字符的后半段与前一半是有联系的。因此我们可以思考如何将位置n的字符减小到原字符串中的位置。首先我们先不考虑增加字符串的额外操作,就只是把前半部分复制到后半部分,如果n在后半部分的话,如果总长度是T,那么将n 与 n - T/2 位置的子符串是一样的。由于题目是先将最后的字符串移到最前边,因此就是 n - 1 - T/2 . 同时还有一个特殊情况,如果n是后半部分的第一个位置,那么就应该是 n = T/2;

代码:

#include
#include
#include
using namespace std;

string s,tp;
long long n ,len ,t;

int main(){
    cin>>s>>n;
     len = t = s.size();
    while(t < n )t <<= 1;
    while(t != len){
        t >>= 1;
        if(n <= t)continue;
        if(t + 1 == n) n = t;
        else n = n - 1 - t;
    }
    cout< 
黑白棋子的移动 

题目链接:白棋子的移动
解题思路:
首先我们能找到规律,但是当最后四行也就是棋子各有两个的时候是没有规律的因此我们可以利用打表的方法来解决。
规律就是我们总是先将连续部分白棋的最后一个棋子与连续部分黑棋的第一个棋子与后边的空格互换之后,再将空格与连续部分黑棋的最后两个互换。递归进行,一直到各剩余两个连续棋子。

实现技巧

  • 我们需要在递归的时候记录两个变量一个是白棋连续部分最后的位置与黑棋连续部分最后的位置。

代码:

#include
#include
#include
using namespace std;

string s;
int n ,cnt,endb,enda;
string out[4] = {"ooo*o**--*", "o--*o**oo*", "o*o*o*--o*", "--o*o*o*o*"};
int a,b,c,d;

void solve(int endb,int enda){
    cnt++;
    if(enda  == 2){ // 处理最后两个是没有规律的打表输出
        for(int i = 0 ; i < 4 ; ++i){
            out[i] += s.substr(10);
            cout<
        a = enda , b = enda + 1 , c = endb - 1 , d = endb ;
        solve(endb - 2,enda);
    }
    else//将空格放到尾部
     {
         c = endb-1 , d = endb;
         solve(endb,enda - 1);
     }
    return;
}

void init(){
    for(int i = 0 ; i < n ; ++i)s += "o";
    for(int j = 0 ; j < n ; ++j) s += "*";
    s += "--";
    cout<
    cin>>n;
    init();
    solve(endb,enda);
    return 0;
}
递推(动态规划) 覆盖墙壁

题目链接:覆盖墙壁

解题思路:

上面说的意境乘以2指的是其中一个F0 + … + F{n-3} 与 F{n-2} , F{n-1}化简为了前一个表达式。

代码

#include
#include
using namespace std;

const int N = 1000010,mod = 1e4;

int f[N];
int pre[N];

int n;

int main(){
    cin>>n;
    pre[0] = f[0] = 1;
    for(int i = 1 ; i <= n ; ++i){
        f[i] = n >= 3 ? pre[i-1] + pre[i-3] : pre[i-1];
        f[i] %= mod;
        pre[i] = pre[i-1] + f[i];
        pre[i] %= mod;
    }
    cout<
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/890055.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号