斗地主

2015最后一题,这道题是大爆搜+贪心,先枚举四带一,三带一,单牌,etc,再枚举顺子优化解,在搜索优化的解是不是优化的(不一定是最优的,所以要递归),在递归回去,找别的顺子优化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int t,n;int s[5]; int a[9999],b[9999];int ans=23;
void dfs(int x){
if(ans<x)return ;
memset(s,0,sizeof(s));
for(int i=1;i<=14;i++)
{
if(a[i]==1||a[i]==2)
s[a[i]]++;
}//记录单张和双张
for(int i=2;i<=14;i++)
{
if(a[i]==4)
{
s[4]++;
if(s[1]>=2) s[1]-=2;
else if(s[2]>=2) s[2]-=2;
else if(s[2]>=1) s[2]--;
}
}//打出所有的四带...
for(int i=2;i<=14;i++)
{
if(a[i]==3)
{
s[3]++;
if(s[1]>=1) s[1]--;
else if(s[2]>=1) s[2]--;
}
}//打出所有的三带。。。。
int w=0;
for(int i=1;i<=4;i++)
w+=s[i];//找最优解
ans=min(ans,x+w);
int j;
for(int i=3;i<=10;i++)//找单顺子优化解
{
for( j=i;j<=14;j++)
{
a[j]--;
if(a[j]<0)break;
if(j-i>=4) dfs(x+1);//搜索
}
if(j==15)j--;
while(j>=i)a[j--]++;//回溯
}
for(int i=3;i<=12;i++)//找双顺子优化
{
for( j=i;j<=14;j++)
{
a[j]-=2;
if(a[j]<0) break;
if(j-i>=2) dfs(x+1);
}
if(j==15) j--;
while(i<=j) a[j--]+=2;
}
for(int i=3;i<=13;i++)//找三顺子优化
{
for( j=i;j<=14;j++)
{
a[j]-=3;
if(a[j]<0)break;
if(j-i>=1) dfs(x+1);
}
if(j==15) j--;
while(i<=j) a[j--]+=3;
}
return ;
}
int main(){
scanf("%d%d",&t,&n);
for(int i=1;i<=t;i++)
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
int x;
scanf("%d%d",&x,&b[i]);
if(x==1)a[14]++;
else if(x==0)a[1]++;
else a[x]++;
}
ans=14;//最大是14
dfs(0);
printf("%d\n",ans);
}
}

最近的文章

Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in …

于 继续阅读
更早的文章

跳石头

二分答案加贪心和之前一个丢瓶盖一样,对去几个石子二分,去多了就取大了,去少了就取小了 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 …

于  二分答案 贪心 继续阅读