牛牛

牛牛玩牌 Cow Solitaire


题目描述:用NxN张扑克牌排成一个方阵。每块牌的点阵形成一个NxN的整数网格A,从左下角A[N,1]漫游(每一步只能向上或者向右行走一步)到右上角A[N,N],要求漫游路径上各个格子中整数之和最大。这是一个组合优化问题。从网格左下角A[N,1]到右上角A[N,N]有很多路径,每条路径上2N-1个数之和为该条路径的目标值,目的是找到一条目标值最大的路径的目标值。

算法思路

这是我写的第一个动态规划的题目,之前看了一个知乎Live的关于算法的经验交流,live的时候大部分人都是很关心DP如何提高,感觉DP非常困难的样子,所以我一直不敢接触DP。这个学期刚好开始学习算法基础与分析了,我就慢慢接触DP,我个人感觉这个题目还是比较简单的,最优子结构也比较好找,有点像组合数学里面找递推关系,但是这个递推关系又有点不同,因为是取子结构中最优解。

该题目还是比较比较好看出递推关系,如果当前的牌大小为S[R][C]的话,递归的函数名称为int Cow_Solitaire的话,当前的最优解是前一个状态的最优解再加上当前卡牌的数字,即Cow_Solitaire[R][C]=max(Cow_Solitaire[R+1][C],Cow_Solitaire[R][C-1])+S[R][C]这是最关键的最优子结构递推式,而且当行数到了N之后,再递归,其行数为N+1或者列数为0时需要返回,因为这两个坐标根本没有卡牌。

Matrix.cpp

#include "Matrix.hpp"


void Matrix::twoDimensionStringArray(string **&card,int **&Maze){
    card=new string* [row+1];
    Maze=new int* [row+1];
    for(int i=0;i<row+1;i++){
        card[i]=new string [column+1];
        Maze[i]=new int [column+1];
    }
}

void Matrix::create_Matrix(string **&card,int **&Maze){
    for(int i=0;i<=row;i++){
        for(int j=0;j<=column;j++){
            Maze[i][j]=0;
            if(j==0||i==row)
                card[i][j]="bc";
            else
                cin>>card[i][j];
        }
    }
}

void Matrix::display_Matrix(string **&card){
    for(int i=0;i<=row;i++){
        for(int j=0;j<=column;j++){
            //if(j==0||i==row)
                cout<<card[i][j]<<" ";
            //else
                //cin>>card[i][j];
        }
        cout<<endl;
    }
}

void Matrix::display_Maze(int **Maze){
    for(int i=0;i<=row;i++){
        for(int j=0;j<=column;j++){
            //if(j==0||i==row)
                cout<<Maze[i][j]<<" ";
            //else
                //cin>>card[i][j];
        }
        cout<<endl;
    }
}


int Matrix::card_Number(string s){
    if(s[0]>='2'&&s[0]<='9')
        return s[0]-'0';
    switch(s[0]){
        case 'A':
            return 1;
        case 'T':
            return 10;
        case 'J':
            return 11;
        case 'Q':
            return 12;
        case 'K':
            return 13;
    }
}

int Matrix::cow_Solitaire(string **&card,int **&Maze,int R,int C){
    int a,b;
    if(R==row||C==0)
        return 0;

    a=cow_Solitaire(card,Maze,R+1,C);
    b=cow_Solitaire(card,Maze,R,C-1);
    Maze[R][C]=1;
    return (a>b?a:b)+card_Number(card[R][C]);
}

Matrix.hpp

#pragma once
#include<string>
#include <iostream>
using namespace std;

class Matrix
{
    public:
        Matrix(){
            cin>>row>>column;
        }
        //Matrix(string **card);
        Matrix(int m,int n);
        void create_Matrix(string **&card,int **&Maze);
        void display_Matrix(string **&card);
        void display_Maze(int **Maze);
        int cow_Solitaire(string **&card,int **&Maze,int row,int column);
        int card_Number(string s);
        void twoDimensionStringArray(string **&card,int **&Maze);
    private:
        int row;
        int column;
};

main.cpp

#include "Matrix.hpp"


int main()
{
    int **Maze;
    string **card;
    Matrix matrix;
    matrix.twoDimensionStringArray(card,Maze);
    matrix.create_Matrix(card,Maze);
    cout<<matrix.cow_Solitaire(card,Maze,0,5)<<endl;
    matrix.display_Matrix(card);
    return 0;
}

测试结果

Input Line

4
5
AA 2B 3C 4D 5D
5A 6B 7C 8D AA
9A TB JC QD AA
KA AB 2C 3D AA

Output Line

72

谢谢大家,希望对大家有帮助!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值