Topoi(一个经常会炸的网站)

本题提交链接

很久以前的题目了, 刚开了博客,来写一波题解

先看一波提交记录:

调了好几天QAQ

唉! 要是这些高手里有我估计直接 输出1 就AC了

算法

DFS + 优化剪枝(用了一点状态压缩)

剪枝

1:求最小值很容易向导最优化剪枝

if(ws>=ans) return;  //剪枝 1:最优化剪枝 

2:若一个高手会做的题有另一个高手都会做,则这个高手没有用

for(int i=1;i<=w;i++)
for(int j=1;j<i;j++)
{;
if((a[i].sn|a[j].sn)==a[j].sn) {kk[i]=1; break;} //kk表示这个高手有没有用
//剪枝 2:若这个高手会做的题有另一个人全会做,则是废物,去掉没有用的高手 (核心剪枝)
}

3:若有一个题只有一个高手能做,则将这个高手“特招”

for(int i=1;i<=w;i++)
for(int j=1;j<i;j++)
{;
if((a[i].sn|a[j].sn)==a[j].sn) {kk[i]=1; break;} //kk表示这个高手有没有用
//剪枝 2:若这个高手会做的题有另一个人全会做,则是废物,去掉没有用的高手 (核心剪枝)
}

顺序性优化:将做题多的高手排在前面(也许没用)

bool cmp(node x,node y){return x.sum>y.sum;}
sort(a+1,a+n+1,cmp); //顺序性优化: 按会做的题数排序

加上这些优化在top上大概200多ms(第二次AC记录),应该还有其他优化,但因为太ruo想不出来

这题用二进制表示状态好像多此一举

最后,附上完整代码(有点小长)

打注释都打了半个多小时QAQ

代码

#include <bits/stdc++.h>
using namespace std;
int n,w,ans=1e9,tt;//tt记录特招人数
bool k[66],kk[66],vis[66]; //k记录是否“特招”,kk记录有木有用,vis标记访问
struct node{
long long sn,sum;
int p[66];
}a[66]; //p数组记录每个高手能做的题,sn记录状态,sum记录题数,
long long num[66],q[66][66],s[66],ss[66];
//q记录每个题能做的高手,s和ss记录每个题能做的人数(有点重复了),num记录每个题的二进制,
bool cmp(node x,node y){return x.sum>y.sum;}
void find(int x,int ws,long long ssum) //x表示当前题号, ws表示高手数, ssum用二进制存储状态
{
if(ws>=ans) return; //剪枝 1:最优化剪枝
if(x>n) {ans=ws; return;} //结束条件, 更新答案
if(((ssum>>(x-1))&1==1)) {find(x+1,ws,ssum); return;} //如果这题已做,往后搜索
for(int i=1;i<=s[x];i++)
{
if(k[q[x][i]]) continue; //判断这个高手是不是 “特招”的
int tmp=q[x][i];
if(vis[tmp]) continue; //如果这个高手已经用过了
vis[tmp]=1;
find(x+1,ws+1,ssum|a[tmp].sn); //一定要用 | 运算,防止重复
vis[tmp]=0;
}
return;
}
int main()
{
scanf("%d%d",&n,&w);
num[1]=1;
for(int i=2;i<=n;i++) num[i]=num[i-1]<<1; //用2进制来表示状态
for(int i=1;i<=w;i++)
{
int x;
scanf("%d",&x);
for(int j=1;j<=x;j++)
{
int y;
scanf("%d",&y);
s[y]++;
if((a[i].sn|num[y])!=a[i].sn) //注意这里要用 | 运算,判断这题有没有出现过
a[i].sum++,a[i].p[a[i].sum]=y; //存储每个高手能做的题
a[i].sn=a[i].sn|num[y]; //更新状态
}
}
sort(a+1,a+n+1,cmp); //顺序性优化: 按会做的题数排序
for(int i=1;i<=w;i++)
for(int j=1;j<i;j++)
{
// if(i==j||kk[j]) continue;
if((a[i].sn|a[j].sn)==a[j].sn) {kk[i]=1; break;} //kk表示这个高手有没有用
//剪枝 2:若这个高手会做的题有另一个人全会做,则是废物,去掉没有用的高手 (核心剪枝)
}
long long ttmp=0;
for(int i=1;i<=w;i++)
{
if(kk[i]) continue; //直接过滤废物高手
for(int j=1;j<=a[i].sum;j++)
{
int tmp=a[i].p[j];
q[tmp][++ss[tmp]]=i;
}
}
//记录能做每个题的高手
for(int i=1;i<=n;i++)
{
if(s[i]==1&&!k[q[i][1]]) //判断第i题是不是只有一个高手会做
{
tt++;
//printf("%d\n",q[i][1]);
int tmp=q[i][1];
ttmp=ttmp|a[tmp].sn; //ttmp记录初始的搜索状态
k[tmp]=1; //标记这个高手不用考虑
}
} //剪枝 3:若有一个题只有一个高手会做,将他“特招”进来 (这个剪枝收益蛮大的)
find(1,0,ttmp);
printf("%d",ans+tt); //注意不要忘了加上“特招”人数
return 0;
}

Topoi 测验1301, 问题C: 1959: 解题 解题报告的更多相关文章

  1. TOPOI 测验1320, 问题C: 4410: [CF41D]Pawn 解题报告

    题目链接 题目大意 在一个树阵中按一定走法取一些树,使和最大且被 k+1整除 解题思路 类似一个数塔问题 因为最后的结果要被 k+1 整除,所以可以记录到每一个点  对 k+1 取余结果不同的最优解( ...

  2. 洛谷 P4397 [JLOI2014]聪明的燕姿 / TOPOI 测验1315, 问题E: 1935: 聪明的燕姿 解题报告

    题目链接 : 1. 洛谷 2.topoi . 大致题意:输入一个数s,找出所有约数和为s的数 关于一个数的约数和求法: 一个>1的整数可以被分解为多个 质数 的乘方,设数 s = p1k1 *  ...

  3. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

  4. 怎样解题 --解题表(how to solve it)

    <怎样解题> 美.波利亚 下面是来自书中的解题表: 理解题目 第一 理解题目 你必须理解题目 未知量是什么?已知数据是什么?条件是什么? 条件有可能满足吗?条件是否可以确定未适量?或者它不 ...

  5. CodeForces 701C They Are Everywhere (滑动窗口)

    题目链接:http://codeforces.com/problemset/problem/701/C 题意:找到字符串中能包含所有元素的最短字符串长度. 利用“滑动窗口”解题 解题思路: 1. 遍历 ...

  6. 【一天一道LeetCode】#63. Unique Paths II

    一天一道LeetCode (一)题目 Follow up for "Unique Paths": Now consider if some obstacles are added ...

  7. 【一天一道LeetCode】#27. Remove Element

    一天一道LeetCode系列 (一)题目 Given an array and a value, remove all instances of that value in place and ret ...

  8. 【一天一道LeetCode】#26. Remove Duplicates from Sorted Array

    一天一道LeetCode系列 (一)题目 Given a sorted array, remove the duplicates in place such that each element app ...

  9. LeetCode7-ReverseInteger

    LeetCode7-ReverseInteger LeetCodeeasyOverflow 题目 题目所在链接为 LeetCode-7:ReverseInteger 题目描述 给出一个32位的有符号整 ...

随机推荐

  1. H264 NALU 使用PS封装 RTP发送

    最近由于项目平台需求,要将H264 NALU封装为PS再用RTP发送,PS封装按照ISO DEC-13818-1标准.一个PS包包含PS Header, PES Header, PS system h ...

  2. bzoj 2510: 弱题 概率期望dp+循环矩阵

    题目: Description 有M个球,一开始每个球均有一个初始标号,标号范围为1-N且为整数,标号为i的球有ai个,并保证Σai = M. 每次操作等概率取出一个球(即取出每个球的概率均为1/M) ...

  3. [POI 2018] Plan Metra

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=5100 [算法] 首先分两类考虑 : 1. 1 -> N的路径不经过其它节点 , ...

  4. [转]HTTP头的Expires与Cache-control

    1.概念 Cache-control用于控制HTTP缓存(在HTTP/1.0中可能部分没实现,仅仅实现了Pragma: no-cache) 数据包中的格式: Cache-Control: cache- ...

  5. 洛谷 1351 联合权值——树形dp

    题目:https://www.luogu.org/problemnew/show/P1351 对拍了一下,才发现自己漏掉了那种拐弯的情况. #include<iostream> #incl ...

  6. androidpn环境搭建

    1.下载androidpn版本.http://sourceforge.net/projects/androidpn/postdownload?source=dlp 2.下载安装tomcat 2.1 下 ...

  7. NBIOT回答

    该部分分享的是物联网各垂直应用领域里,NB-IoT技术的部署,看看适合NB-IoT技术的垂直应用场景有哪些?垂直应用服务商又该如何部署? 1 NB-IoT适合的垂直应用场景有哪些? 2 NB-IoT垂 ...

  8. Erlang generic standard behaviours -- gen_server system msg

    这是Erlang generic standard behaviors gen_server 分析的系列的最后一篇,主要分析gen_server module 辅助性的功能函数. 在gen_serve ...

  9. 杂项:Code(开源资源)

    ylbtech-杂项:Code(开源资源) 1.返回顶部 1.CSDN http://code.csdn.net/ 2.腾讯·开源 http://code.tencent.com/ 3. 4. 5. ...

  10. windows7下安装gem包---bcrypt-ruby

    在Gemfile中添加 gem 'bcrypt-ruby', '~> 3.0.0' 然后执行bundle install,rails服务启动没有问题,但是运行程序时页面报错如下: cannot ...