您的位置:首页 > 其它

[noip2015]斗地主(dfs+贪心)

2017-10-22 21:29 585 查看

题目:

我是超链接

题解:

一开始就照着大暴力的方向去写,然后华丽丽的T了,只有45pts

然后幡然醒悟:这不是一个普通的暴力!这是一个贪心!

先不考虑顺子的情况,贪心算出连带和单出的情况,按照出的牌从多到少来贪心

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int to[20]={0, 13, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};//大小序
int m,n,p[20],c[20],ans;
int calc()
{
int res=0;
memset(c,0,sizeof(c));
for (int i = 0; i <= 13; ++i) ++c[p[i]];
while (c[4]>0 && c[2]>1) c[4]-=1,c[2]-=2,++res;
while (c[4]>0 && c[1]>1) c[4]-=1,c[1]-=2,++res;
while (c[4]>2) c[4]-=2,++res;
while (c[4]>0 && c[2]>0) c[4]-=1,c[2]-=1,++res;
while (c[3]>0 && c[2]>0) c[3]-=1,c[2]-=1,++res;
while (c[3]>0 && c[1]>0) c[3]-=1,c[1]-=1,++res;
return res + c[1] + c[2] + c[3] + c[4];
}
void ss(int s)
{
int pos,tot;
if (s>=ans) return;
ans=min(ans,s+calc());//不带顺子贪心考虑
for (int i=2;i<=13;i++)//3-A
for (int j=1;j<=3;j++)//1-3顺
if (p[i]>=j)//能成为开始
{
tot=0;
for (pos=i;p[pos]>=j;pos++) p[pos]-=j,tot+=j;
for (;--pos>=i;p[pos]+=j,tot-=j)//可以发现不管是什么顺子,至少是5张牌
if (tot>=5) ss(s+1);
}
}
int main()
{
int T,n;
scanf("%d%d",&T,&n);
while (T--)
{
int x,y;
memset(p,0,sizeof(p));
for (int i=1;i<=n;i++)
scanf("%d%d",&x,&y),++p[to[x]];
ans=100;ss(0);
printf("%d\n", ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: