题目描述
打牌过程中可以出单张,对子,五张顺子,三组连对,问最少多少次出完牌。
题解:
#include <iostream>
#include <vector>
using namespace std;
void dfs(vector<int> &cards, int times, int &least, vector<vector<int>> &path, vector<vector<int>> &res){
if(times > least) return; // 剪枝
int first=0;
for(; first<cards.size(); first++)
if(cards[first])
break;
if(first== cards.size()){ // 到达叶子结点
if(times<least) {
least = times;
res = path;
}
return;
}
// 出单牌
cards[first]--;
path.push_back(vector<int> {first});
dfs(cards, times+1, least, path, res);
path.pop_back();
cards[first]++;
// 出对子
if(cards[first]>=2){
cards[first]-=2;
path.push_back(vector<int> {first, first});
dfs(cards, times+1, least, path, res);
path.pop_back();
cards[first] +=2;
}
// 出顺子
if(first+4<cards.size()){
if(cards[first]&&cards[first+1]&&cards[first+2]&&cards[first+3]&&cards[first+4]){
for(int i=first; i<=first+4; i++)
cards[i]--;
path.push_back(vector<int> {first, first+1,first+2, first+3,first+4});
dfs(cards, times+1, least, path, res);
path.pop_back();
for(int i=first; i<=first+4; i++)
cards[i]++;
}
}
// 出连对
if(first+2<cards.size()){
if(cards[first]>=2 && cards[first+1]>=2&&cards[first+2]>=2){
for(int i=first; i<=first+2; i++)
cards[i]-=2;
path.push_back(vector<int> {first, first,first+1, first+1,first+2,first+2});
dfs(cards, times+1, least,path, res);
path.pop_back();
for(int i=first; i<=first+2; i++)
cards[i]+=2;
}
}
}
int main() {
vector<int> cards(10,0);
for(int i=0;i<10;i++)
cin>>cards[i];
int least=INT_MAX;
vector<vector<int>> res;
vector<vector<int>> path;
dfs(cards, 0, least, path, res);
cout<<least<<endl;
for(int i=0;i<res.size();i++)
{
for(int j=0;j<res[i].size(); j++)
cout<<res[i][j]<<',';
cout<<endl;
}
return 0;
}