UOJ 147 & 151 [NOIP2015]斗地主
来源:互联网 发布:eureka服务注册源码 编辑:程序博客网 时间:2024/06/04 23:55
暴搜DFS
当初在NOIP2015考场上的时候还是too young,这题只拿了15分,那时候什么都不懂……
考虑到如果不出任何顺子,那么我们可以贪心地出牌,肯定能得到最优解。于是我们在DFS爆搜的时候只要考虑顺子就好了。这样确实可以A掉UOJ147(因为数据比较弱?)然而UOJ151是数据加强(果然好强…),交上去就跪了。原因是有一些点是类似于把两个炸弹拆成四带二来打之类的……加了好多特判才A……
下面是151的代码,在判火箭的地方改一下应该就是147的代码了吧……
#include<cstdio>#include<cstring>#include<algorithm>#define N 16using namespace std;int n, a[N], ans, cnt[5];int calc(){ int ret=0, temp; memset(cnt,0,sizeof(cnt)); for(int i = 0; i <= 14; i++) cnt[a[i]]++; if(cnt[4]) { temp=min(cnt[4],cnt[2]/2); ret+=temp; cnt[4]-=temp; cnt[2]-=2*temp; temp=min(cnt[4],cnt[1]/2); ret+=temp; cnt[4]-=temp; cnt[1]-=2*temp; } if(cnt[3]) { temp=min(cnt[3],cnt[2]); ret+=temp; cnt[3]-=temp; cnt[2]-=temp; temp=min(cnt[3],cnt[1]); ret+=temp; cnt[3]-=temp; cnt[1]-=temp; } for(int i = 1; i <= 4; i++) ret+=cnt[i]; if(cnt[1]>=2 && a[0] && a[1]) ret--;//火箭 return ret;}void dfs(int step){ if(step>=ans)return; ans=min(ans,step+calc()); for(int i = 3; i <= 14; i++) if(a[i]>=3) for(int j = i+1; j <= 14; j++) { if(a[j]<3)break; for(int k = i; k <= j; k++)a[k]-=3; dfs(step+1); for(int k = i; k <= j; k++)a[k]+=3; } for(int i = 3; i <= 14; i++) if(a[i]>=2) for(int j = i+1; j <= 14; j++) { if(a[j]<2)break; if(j-i<2)continue; for(int k = i; k <= j; k++)a[k]-=2; dfs(step+1); for(int k = i; k <= j; k++)a[k]+=2; } for(int i = 3; i <= 14; i++) if(a[i]>=1) for(int j = i+1; j <= 14; j++) { if(a[j]<1)break; if(j-i<4)continue; for(int k = i; k <= j; k++)a[k]--; dfs(step+1); for(int k = i; k <= j; k++)a[k]++; } for(int i = 2; i <= 14; i++) { if(a[i]==4) { for(int j = 2; j <= 14; j++) { if(j==i)continue; if(a[j]==4) { a[i]=a[j]=0; dfs(step+1); a[i]=a[j]=4; } if(a[j]>=3) for(int k = 2; k <= 14; k++) { if(k==i||k==j)continue; if(a[k]>=2) { a[i]-=4; a[j]-=2; a[k]-=2; dfs(step+1); a[i]+=4; a[j]+=2; a[k]+=2; } } if(a[j]>=2) { for(int k = 2; k <= 14; k++) { if(k==i||k==j)continue; if(a[k]>=1) { a[i]-=4; a[j]-=1; a[k]-=1; dfs(step+1); a[i]+=4; a[j]+=1; a[k]+=1; } } a[i]-=4; a[j]-=2; dfs(step+1); a[i]+=4; a[j]+=2; } } } if(a[i]==3) { for(int j = 2; j <= 14; j++) { if(j==i)continue; if(a[j]>=2) { a[i]-=3; a[j]-=1; dfs(step+1); a[i]+=3; a[j]+=1; } if(a[j]>=3) { a[i]-=3; a[j]-=2; dfs(step+1); a[i]+=3; a[j]+=2; } } } }}int main(){ int T; scanf("%d%d",&T,&n); while(T--) { memset(a,0,sizeof(a)); for(int i = 1, x, y; i <= n; i++) { scanf("%d%d",&x,&y); if(x==1)x=14; else if(x==0 && a[0])x=1; a[x]++; } ans=calc(); dfs(0); printf("%d\n",ans); }}
0 0
- UOJ 147 & 151 [NOIP2015]斗地主
- UOJ NOIP2015 斗地主 [搜索]
- UOJ #151. 【NOIP2015】斗地主“加强”版【搜索+贪心
- [bzoj4325][NOIP2015]斗地主
- [BZOJ4325]NOIP2015 斗地主
- noip2015 day1 斗地主
- NOIP2015斗地主
- 【noip2015】【搜索】斗地主
- 【NOIP2015】Day1T3 斗地主
- NOIP2015斗地主
- 【NOIP2015】斗地主
- 【NOIP2015】斗地主
- 【NOIP2015】斗地主题解
- NOIP2015 斗地主(回溯)
- NOIP2015 斗地主
- [NOIP2015] 斗地主
- [NOIP2015] 斗地主 大爆搜
- NOIP2015斗地主
- jsp、servlet和tomcat的关系
- 新增linux账户来使用深度学习框架-caffe
- 题目1019:简单计算器
- 51Nod-扔盘子(O(n)解法)
- C++ Primer(第五版)练习3.22
- UOJ 147 & 151 [NOIP2015]斗地主
- 递归与尾递归(Tail Recursion)
- 【DP 训练】Cake Slicing, ACM/ICPC Nanjing 2007, UVa1629
- 数组的4个基本操作:找出最大元素、平均值、复制、反转。
- PHP 线程安全与非线程安全版本的区别深入解析
- Java的动态代理
- 求两个数的最大公约数
- hdoj5978Sequence I【kmp】
- HC-05使用介绍