牛牛玩牌 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