回溯算法-胡牌问题[组合问题的进阶]

原始题目:雀魂启动

题目的大致意思就是,有13张排,加一张,就能胡,用贵州话讲就是一对将,然后加四坎牌。
一坎牌可以是三个一样的碰,也可以是顺子。现在,让你用程序去判定任意一组13排是否能胡,并给出需要哪个牌来胡牌。

这个显然是一个经典的回溯问题,但是和我们常见的回溯问题又有一些区别,比如:组合问题

class Solution {
public:
    vector<vector<int>> arrs;
    map<string,int> maps;
    vector<vector<int>> subsets(vector<int>& nums) {
        vector<int> path;
        sort(nums.begin(),nums.end());
        help(nums, path,0);
        return arrs;
    }
    void help(vector<int>& nums,vector<int>& path,int begin){
        sort(path.begin(),path.end());
        stringstream ss;    
        for (auto k: path){
            ss<<k<<",";
        }
        if(maps[ss.str()] == 0){
            arrs.push_back(path);
            maps[ss.str()]++;
        }
    
        if(path.size()==nums.size()){
            return;
        }
        
        for(int i =begin;i<nums.size();i++){
            if(find(path.begin(),path.end(),nums[i]) == path.end()){
                path.push_back(nums[i]);
                help(nums,path,i);
                path.pop_back();
            }
        }
    }
};

差别在哪呢?胡牌问题里面侧重一个胡字,对于哪个牌能胡,只是一个简单的暴力for循环就行,换句话说:

for(int i =1;i<=9;i++){
	if(胡牌(i)){
		cout<<i<<" ";
	}
}

你就能完成这道题。
但是,这个胡牌,不是一个简单的事情,它也是回溯,但是细节和常规的组合问题不一样

组合问题:我希望找到一条路径,使得这条路径满足某种规则。

胡牌能不能当成寻路问题?
答案是不能简单的当成,但本身也是一个寻路过程,因为直接通过一条路[字符串]径直接判断能否胡牌是很困难的事情,但是组合问题本身只是期待获取这条路径。但是两者本身却都基于回溯进行操作。胡牌问题的难点在于怎么确定胡牌,使用回溯是一个好方法,先确定第一坎牌,然后确定第二坎牌,第三…,突然发现无法完成第n坎牌,回溯,第一次试探时,尝试的是碰!操作,那第二次试探时,则采用顺子操作,当顺子能成功时,则下面又可以碰,或者是顺子

在这里插入图片描述
组合问题:
在这里插入图片描述
可以看到,前面的胡牌问题已经变成一个二叉树,而后面的组合问题则是一个多叉树,不管是多插还是二叉,使用回溯都会很简单。而编程二叉树的胡牌问题在使用回溯时,可以直接通过后序遍历确定是否达成条件

//二叉树的后序

bool help(Node* root){
    //op
    bool f1 = help(root.left);
	bool f2 = help(root.right);
	if(f1){
		return f1;
	}
	if(f2){
		return f2;
	}
}

源代码:

#include <map>
#include <iostream>
#include <vector>
using namespace std;
bool isSuccess(int n,map<int,int>& maps,vector<int>& path);

int main(){
    
    map<int,int> maps;
    vector<int> path;
    int* arr = new int[13];
    for(int i =0;i<13;i++){
        cin>>arr[i];
        maps[arr[i]]++;
    }
    for (int i =1;i<=9;i++){
        if (maps[i]<4){
            map<int,int> m2  = maps;
            m2[i]++;
            if(isSuccess(0,m2,path) == true){
                cout<<i<<" ";
            }
        }
    }
    return 0;
}
bool isSuccess(int n,map<int,int>& maps,vector<int>& path){
    if(n == 4){
        for (auto k: maps){
            if(k.second == 2){
                return true;
            }
        }
        return false;
    }
    for(int i =0;i<9;i++){
        int pos = i+1;
        if(maps[pos]>=3){
            maps[pos] -= 3;
            path.push_back(pos);
            bool reback = isSuccess(n + 1,maps,path);
            pos = path[path.size() - 1];
            maps[pos] += 3;
            path.pop_back();
            if(reback){
                return true;
            }
        }
        if(maps[pos]>0&&maps[pos+1]>0&&maps[pos+2]>0){
                maps[pos] -= 1;
                maps[pos+1]-=1;
                maps[pos+2]-= 1;
                path.push_back(pos);
                bool reback = isSuccess(n+1, maps,path);
                pos = path[path.size() - 1];
                path.pop_back();
                maps[pos] += 1;
                maps[pos+1] +=1;
                maps[pos+2] +=1;
                if(reback){
                    return true;
                }
            }
        
    }
    return false;
}

关于碰的操作:for循环,如果发现存在key>3的情况,则碰
关于顺子的操作,for循环,如果发现连续3个value>0的情况则顺子

觉得有人要吐槽:这特么算二叉树我倒立洗头
哎,我也是瞎讲的,从抽象层面上,确实就是一个二叉树,图都出来了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
神经网络算法胡牌算法中的应用是比较常见的。下面我介绍一下基于深度学习技术的神经网络算法胡牌算法。 1. 数据预处理 首先,需要对数据进行预处理。收集游戏中的牌局数据,包括每个玩家的手牌、明牌和已经打出的牌,以及每个玩家的操作(吃、碰、杠、胡等)。 2. 特征提取 接下来,需要对数据进行特征提取。对于每个牌局,可以将每个玩家的手牌表示为一个向量。这个向量包含每种牌的数量和是否有将牌(即是否有对子)。然后,将这些向量作为神经网络的输入。 3. 神经网络模型 在神经网络模型方面,可以使用卷积神经网络(CNN)或递归神经网络(RNN)等深度学习模型。这些模型可以学习到不同的牌型和操作之间的关系。 4. 训练模型 使用收集到的数据训练神经网络模型。在训练过程中,需要定义一个损失函数,并且通过反向传播算法来更新模型的权重。 5. 测试模型 使用测试数据来测试训练好的模型的准确率。如果准确率达到预期,则可以使用该模型来预测玩家的操作,并且根据这些操作来判断是否胡牌。 6. 优化模型 最后,可以对模型进行优化,例如添加更多的特征提取器或增加神经网络的层数。通过不断地优化,可以提高模型的准确率和鲁棒性。 以上就是基于深度学习技术的神经网络算法胡牌算法的主要步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值