[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的更多相关文章
随机推荐
- Spark MLlib编程API入门系列之特征选择之向量选择(VectorSlicer)
不多说,直接上干货! 特征选择里,常见的有:VectorSlicer(向量选择) RFormula(R模型公式) ChiSqSelector(卡方特征选择). VectorSlicer用于从原来的特征 ...
- 日常博客----rem,em的恩怨相杀
基本知识: 使用 em 和 rem 单位可以让我们的设计更加灵活,能够控制元素整体放大缩小,而不是固定大小. 我们可以使用这种灵活性,使我们在开发期间,能更加快速灵活的调整,允许浏览器用户调整浏览器大 ...
- STM32 modbus CRC16校验
typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef int int32_t; const uint16_t ...
- React-Native 开发问题整理
1.内嵌WebView,点击输入框后页面不自动上滚 <activity android:name=".MainActivity" android:label="@s ...
- 【数据分析 R语言实战】学习笔记 第五章 数据的描述性分析(下)
5.6 多组数据分析及R实现 5.6.1 多组数据的统计分析 > group=read.csv("C:/Program Files/RStudio/002582.csv") ...
- 64位系统上32位进程拷贝文件到System32目录时的重定向
64位系统上,32位进程拷贝文件到"System32"目录时,会被文件系统重定向到"SysWOW64"目录 要禁用这种重定向,需要用到下面2个API: Wow6 ...
- Cognos报表验证(添加字段)
1.打开后台Cognos 链接远程后台Cognos 2.打开要验证的报表 3.给右边的sql语句加个空格或者换行点击验证 4.查看业务视图中是否已经添加该字段 双击维度或者度量(添加字段所在的分类) ...
- LINUX 安装tsung 对OPENFIRE 进行压力测试
参考资料: http://www.centoscn.com/image-text/install/2014/0818/3503.html http://my.oschina.net/jieluck ...
- IOS OS X 中集中消息的传递机制
1 KVO (key-value Observing) 是提供对象属性被改变是的通知机制.KVO的实现实在Foundation中,很多基于 Foundation 的框架都依赖与它.如果只对某一个对象的 ...
- 一行命令杀掉defunct进程
一行命令杀掉defunct进程 今天在杀掉defunc过程中一直搞不完,索性写一行命令,注意先看懂谨慎使用 ps -ef|grep defunct|awk '{print " ps -ef| ...