[BZOJ4207]Can
[BZOJ4207]Can
试题描述
输入
输出
对于每个case,输出一行,"Case #x: y z",x表示case标号(从1开始),y和z是答案区间的第一个和最后一个元素的下标。
输入示例
输出示例
- Case #:
- Case #:
- Case #:
- Case #:
数据规模及约定
题解
这是一道分治 + 暴搜的好题。
做法是这样的,我们在分治时考虑每次分治跨中点的部分,可以从中点开始向两边扩展,一旦遇到当前选的 k’ 个数不能搞掉的 roll set,就枚举一下选择这个 roll set 中的哪一个 die roll,然后接着向左右扩展。
最优性剪枝能剪掉不少情况。
- #include <iostream>
- #include <cstdio>
- #include <algorithm>
- #include <cmath>
- #include <stack>
- #include <vector>
- #include <queue>
- #include <cstring>
- #include <string>
- #include <map>
- #include <set>
- using namespace std;
- const int BufferSize = 1 << 16;
- char buffer[BufferSize], *Head, *Tail;
- inline char Getchar() {
- if(Head == Tail) {
- int l = fread(buffer, 1, BufferSize, stdin);
- Tail = (Head = buffer) + l;
- }
- return *Head++;
- }
- int read() {
- int x = 0, f = 1; char c = Getchar();
- while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
- while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
- return x * f;
- }
- #define maxn 100010
- int n, D, K, A[maxn][4], num[maxn<<2];
- bool has[maxn<<2];
- int al, ar;
- bool can(int p) {
- for(int i = 0; i < D; i++) if(has[A[p][i]]) return 1;
- return 0;
- }
- void dfs(int l, int r, int ql, int qr, int k) {
- while(l >= ql && can(l)) l--;
- while(r <= qr && can(r)) r++;
- // printf("dfs: %d %d\n", l, r);
- int len = r - l - 1;
- if(len > ar - al + 1) al = l + 1, ar = r - 1;
- if(len == ar - al + 1 && l + 1 < al) al = l + 1, ar = r - 1;
- if(k == K) return ;
- if(l < ql && r > qr) return ;
- for(int i = 0; i < D; i++) {
- if(l >= ql) has[A[l][i]] = 1, dfs(l - 1, r, ql, qr, k + 1), has[A[l][i]] = 0;
- if(r <= qr) has[A[r][i]] = 1, dfs(l, r + 1, ql, qr, k + 1), has[A[r][i]] = 0;
- }
- return ;
- }
- void solve(int l, int r) {
- if(ar - al + 1 > r - l + 1 || l > r) return ;
- int mid = l + r >> 1;
- // printf("[%d, %d] %d\n", l, r, mid);
- dfs(mid, mid, l, r, 0);
- solve(l, mid - 1); solve(mid + 1, r);
- return ;
- }
- int main() {
- int T = read();
- for(int kase = 1; kase <= T; kase++) {
- n = read(); D = read(); K = read();
- int cnt = 0;
- for(int i = 0; i < n; i++)
- for(int j = 0; j < D; j++) num[++cnt] = A[i][j] = read();
- sort(num + 1, num + cnt + 1);
- for(int i = 0; i < n; i++)
- for(int j = 0; j < D; j++) A[i][j] = lower_bound(num + 1, num + cnt + 1, A[i][j]) - num;
- al = ar = 0;
- solve(0, n - 1);
- printf("Case #%d: %d %d\n", kase, al, ar);
- }
- return 0;
- }
[BZOJ4207]Can的更多相关文章
随机推荐
- (020)[虚拟系统]Win7网络连接红叉(无解决)
该虚拟机在重装主系统前是可以连接网络的,主系统重新安装以后,导入新安装的VM以后,网络图标显示红叉. 查看设备管理,显示没有安装以太网驱动. 重新安装 Vmware Tools,未果.VMware官网 ...
- 关于发布WP 8.1应用信息不匹配问题的解决办法
错误提示: 与此更新关联的程序包标识符与已上传程序包中的标识符不匹配: The package identity associated with this update doesn't match ...
- 微服务熔断限流Hystrix之流聚合
简介 上一篇介绍了 Hystrix Dashboard 监控单体应用的例子,在生产环境中,监控的应用往往是一个集群,我们需要将每个实例的监控信息聚合起来分析,这就用到了 Turbine 工具.Turb ...
- AJPFX简述Java中this关键字的使用
Java中this关键字的使用主要有两处: 1.构造方法 this指的是调用构造方法进行初始化的对象. //有参构造public Human(String name, int age) { this( ...
- PKU_campus_2018_D Chocolate
思路: 题目链接http://poj.openjudge.cn/practice/C18D/ kruskal过程中使用乘法原理计数. 实现: #include <bits/stdc++.h> ...
- EventBus 报“Subscriber class already registered to event class”错误
这句子的话意思也很容易理解,“接收者类已经被注册为事件类了”. 之前我是这么写: 事件注册是写在onStart()里面的 @Override protected void onStart() { su ...
- ubuntu下安装mongo扩展
安装openssl apt-get install openssl libssl-dev libssl0.9.8 libgtk2.0-dev 安装php-pear apt-get install ph ...
- .NET多线程总结
1.不需要传递参数,也不需要返回参数 我们知道启动一个线程最直观的办法是使用Thread类,具体步骤如下: public void test() { ThreadStart threadStart = ...
- while循环(break、continue)
while循环 流程:判断条件是否为真,如果条件为真,执行代码块,然后再次判断条件是否为真,如果为真,执行代码块,直到条件判断为假,结束循环 格式 while 条件: 代码块(循环体) else:- ...
- Qt 之 QApplication
1.QApplication QApplication类管理GUI程序的控制流和主要设置,是基于QWidget的,为此特化了QGuiApplication的一些功能,处理QWidget特有的初始化和结 ...