洛谷题目传送门

顺便提一下题意有一个地方不太清楚,就是如果输出No还要输出最少需要添加多少张牌才能满足要求。蒟蒻考完以后发现四个点Too short on line 2。。。

比较需要技巧的搜索

既然是同一个花色要连续,那就枚举每一个花色在哪一段区间连续并选中四个区间,累计每个点数的选中次数。

最后来一个\(O(13)\)的\(\text{check}\),首先每个点数选中次数要不少于已有的个数。接着,只有所有点数的选中次数和已有点数相等时,才能判为'Yes',然后统计某张牌的花色的区间未包含这张牌的总数更新答案。否则判为'No',然后统计每个点数选多了的总数更新答案。

总复杂度\(\binom{13}{2}^4* 13=481195728\),超过了\(10^8\),肯定需要剪枝。

可行性剪枝:每个点数选中次数之和不少于原有牌的总数。

最优性剪枝:实时统计选多了的总数,在No的状态下,如果超过答案则剪掉;在Yes的状态下,只要不为\(0\)就剪掉。

700+ms比标程快多了。可能标程比较良心没加什么剪枝。

#include<bits/stdc++.h>
#define R register int
using namespace std;
const int N=99;
int a[N],b[N],l[N],r[N],cnt[N],n,now1,ans=N,ans1=N;
char s[N];
void dfs(R h,R lef){//lef为n-当前已选中总次数
if(h==5){
R now=0;
for(R i=1;i<=13;++i){
if(cnt[i]>0)return;//不合法
now|=cnt[i]<0;
}
if(now){ans1=now1;return;}//No状态
for(R i=1;i<=n;++i)//Yes状态,统计答案
if((l[a[i]]>b[i]||r[a[i]]<b[i])&&++now==ans)return;
ans=now;ans1=1;return;//注意ans1=1的剪枝作用
}
for(R i=max(lef-(4-h)*13,0),j,rr;i<=13;++i){//枚举区间长度,可行性剪枝
if(i==0){l[h]=r[h]=0;dfs(h+1,lef);continue;}
for(rr=i;rr<=13;++rr){//枚举右端点
for(j=rr-i+1;j<=rr;++j)now1+=--cnt[j]<0;//动态维护当前选多了的总数
if(now1<ans1)l[h]=(r[h]=rr)-i+1,dfs(h+1,lef-i);//最优性剪枝
for(j=rr-i+1;j<=rr;++j)now1-=++cnt[j]<=0;
}
}
}
int main(){
scanf("%d",&n);
for(R i=1;i<=n;++i){
scanf("%d%s",&a[i],s);
if(s[0]=='A')b[i]=1;//把点数处理一下
else if(s[0]=='1')b[i]=10;
else if(s[0]=='J')b[i]=11;
else if(s[0]=='Q')b[i]=12;
else if(s[0]=='K')b[i]=13;
else b[i]=s[0]-'0';
++cnt[b[i]];
}
dfs(1,n);
if(ans!=N)printf("Yes\n%d\n",ans);
else printf("No\n%d\n",ans1);
return 0;
}

随机推荐

  1. Redis Sentinel 集群搭建常见注意事项

    我的配置: 1个master,1个slave,3个sentinel 搭建的过程网上已经有很多了,这里列几个重点关注: 修改sentinel.conf的protected-mode与redis.conf ...

  2. windows下linux子系统安装

    1.打开Windows功能中的使用于linux的Windows子系统 2.应用商店中下载需要的linux 3.下载完成后运行等待安装并输入用户名密码  4.查看系统信息 先后 sudo apt-get ...

  3. linux虚拟机桥接网络配置

    版权声明:经验之谈,不知能否换包辣条,另,转载请注明出处. https://blog.csdn.net/zhezhebie/article/details/75035997 前言:我是最小化安装cen ...

  4. MySQL查询优化注意下面的四个细节

    原文:http://bbs.landingbj.com/t-0-244231-1.html 在任何一个数据库中,查询优化都是不可避免的一个话题.对于数据库工程师来说,优化工作是最有挑战性的工作.MyS ...

  5. # 【Python3练习题 007】 有一对兔子,从出生后第3个月起每个月都生一对兔子, # 小兔子长到第三个月后每个月又生一对兔子, # 假如兔子都不死,问每个月的兔子总数为多少?

    # 有一对兔子,从出生后第3个月起每个月都生一对兔子,# 小兔子长到第三个月后每个月又生一对兔子, # 假如兔子都不死,问每个月的兔子总数为多少?这题反正我自己是算不出来.网上说是经典的“斐波纳契数列 ...

  6. Object.prototype.toString.call()

    源码中有这样一段: class2type = {}, toString = class2type.toString,   function type(obj) { //obj为null或者undefi ...

  7. hadoop分布式系统架构详解

    hadoop 简单来说就是用 java写的分布式 ,处理大数据的框架,主要思想是 “分组合并” 思想. 分组:比如 有一个大型数据,那么他就会将这个数据按照算法分成多份,每份存储在 从属主机上,并且在 ...

  8. class面向对象-1

    一.基本定义 class cl(object): def __init(self,var) self.var=var def func(self,i) print('%s is in %s'%(i,s ...

  9. Python深入类和对象

    一. 鸭子类型和多态 1.什么是鸭子类型: 在程序设计中,鸭子类型(英语:Duck typing)是动态类型和某些静态语言的一种对象推断风格."鸭子类型"像多态一样工作,但是没有继 ...

  10. GlusterFS卷的种类

    1.分布卷 在分布式卷中,文件随机扩展到卷中的砖块中. 使用分布式卷,需要扩展存储和冗余不是很重要,或由其他硬件/软件层提供. 创建语法:gluster volume create [transpor ...