http://codeforces.com/contest/747/problem/F

cf #387 div2 problem f

非常好的一道题。看完题,然后就不知道怎么做,感觉是dp,但是不知道怎么枚举。还有就是一般求第k小的思路一般是什么?对这类题目理解的不是很好。

这道题,跟上一篇的题解里面写的hdu 1002 递增数的题目的解法差不多,但是底层的求解需要花一些时间去推敲!

不会做,就看官方题解,看不懂说的什么。就从下面的讨论找大神的题解。

I can describe my solution
Binary search on what is the answer(mi). So, the problem reduces to counting number of numbers <= mi such that each digit occurs <= t times.
In fact, we solve a more general problem — find number of numbers of length i such that each digit j occurs <= b[j] times. 0 complicates the matter somewhat but for the time assume that 0 can be placed anywhere and obeys constraint like the normal digits. Then formulate dp[i][j] = number of numbers with i digits and place only digits <= j. Iterate k = how many j digits will be there — 0 to min(i,b[j]) then dp[i][j] = sum((i choose k)*dp[i-k][j-1]). Base cases are simple to write.
Overall count can be calculated by fixing highest digit(depends on mi) and then a dp call, then next digits etc.. similar to what we do in offline digits dp solution. The prefix digits that are fixed decide what array b is(t — number of times digit has occurred till now).
Finally for 0, simply calculate for lesser lengths using a similar logic. Checkout my solution for more details.
Time complexity = O(p^3*d^3) where p=max digits in answer=9 and d=16 and = runs in 15 ms :)

看完这个之后,思路就清晰很多了,然后接下来就是二分的判断条件,对于给定mi,如何判断比它小的满足要求的数的个数呢? 这个求解思路跟上面写的hdu的1002思路一致, 按长度进行累加和, 因为一个数的长度很小,这里int的16进制表示,最大长度为32/4 = 8, 这个长度很短, 可以通过预处理来快速求解。所以,首先需要解决,长度为k的满足要求的数的个数这个问题!由于题目要求的是每个数出现次数小于等于t, 所以如果按位枚举的话,需要记住每一个数的出现次数,这个好像不容易解决,然后考虑可以使用的数的最大值,使用排列组合的方式,就是上面的思路进行解决。这个问题解决之后, 然后就是对于一个数,先求长度比它小的数的个数,然后求解跟他长度一致的数的个数,依次从高位到低位, 进行求解,枚举每一个数字的方式进行。讲的好乱,我都听不懂了!

注意上面的复杂度分析:代码运行速度非常快。

又掌握一种套路,就是上面的dp求解的过程,这个不好思考,求解每个数字出现此小于等于t的数字的个数,使用组合的方式,注意对0的单独处理。

 #include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <string.h>
#include <fstream>
#include <cassert>
using namespace std; #define boost ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define sz(a) int((a).size())
#define rep(i, s, n) for(int i = s; i <= (n); ++i)
#define rev(i, n, s) for(int i = (n); i >= s; --i)
#define fore(x, a) for(auto &&x : a)
typedef long long ll;
const int mod = ;
const int N = ; int a[];
int t;
int b[];
ll dp[][];
ll c[][]; ll go(int p, int x) {
if (p == -) return ;
if (x == ) {
if (t - b[x] >= p + ) return ;
return ;
}
ll &res = dp[p][x];
if (res >= ) return res;
res = ;
rep(i, , min(p + ,t-b[x])) {
res += c[p+][i]*go(p - i, x - );
}
return res;
} char hex(int x) {
if (x >= ) return 'a' + (x - );
return '' + x;
} ll g[]; ll f(int x) {
ll res = ;
memset(b, , sizeof(b));
rep(i, , ) {
memset(dp, -, sizeof(dp));
b[i]++;
res += go(x - , );
b[i]--;
}
return res;
} int main() {
#ifdef loc
if (!freopen((string(FOLDER) + "inp.txt").c_str(), "r", stdin)) {
assert();
}
freopen((string(FOLDER) + "out.txt").c_str(), "w", stdout);
#endif
boost;
ll k;
cin >> k >> t;
rep(i, , ) {
c[i][] = ;
rep(j, , i) {
c[i][j] = c[i - ][j] + c[i - ][j - ];
}
}
rep(i, , ) {
g[i] = f(i);
if (i > ) g[i] += g[i - ];
}
ll lo = , hi = (1LL << ) - ;
while (lo < hi) {
ll mi = (lo + hi) / ;
ll p = mi + ;
int td = ;
rep(i, , ) {
a[i] = p % ;
p /= ;
td = i;
if (p == ) {
break;
}
}
ll tot = td > ? g[td - ] : ;
memset(b, , sizeof(b));
rev(i, td, ) {
rep(j,(i==td)?:, a[i] - ) {
b[j]++;
if (b[j] <= t) {
memset(dp, -, sizeof(dp));
tot += go(i - , );
}
b[j]--;
}
b[a[i]]++;
if (b[a[i]] > t) break;
}
if (tot >= k) hi = mi;
else lo = mi + ;
}
vector<int> ans;
while (lo > ) {
ans.push_back(lo % );
lo /= ;
}
reverse(ans.begin(), ans.end());
fore(x, ans) {
cout << hex(x);
}
cout << endl;
return ;
}

F. Igor and Interesting Numbers的更多相关文章

  1. CF747F Igor and Interesting Numbers

    我佛了,这CF居然没有官方题解. 题意:给定k,t,求第k小的16进制数,满足每个数码的出现次数不超过t. 解: 每个数都有个出现次数限制,搞不倒.一开始想到了排序hash数位DP,不过写了写觉得不胜 ...

  2. Codeforces 747F Igor and Interesting Numbers DP 组合数

    题意:给你一个数n和t,问字母出现次数不超过t,第n小的16进制数是多少. 思路:容易联想到数位DP, 然而并不是...我们需要知道有多少位,在知道有多少位之后,用试填法找出答案.我们设dp[i][j ...

  3. ural 2070. Interesting Numbers

    2070. Interesting Numbers Time limit: 2.0 secondMemory limit: 64 MB Nikolay and Asya investigate int ...

  4. 算法笔记_093:蓝桥杯练习 Problem S4: Interesting Numbers 加强版(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 Problem Description We call a number interesting, if and only if: 1. Its d ...

  5. java实现 蓝桥杯 算法提高 Problem S4: Interesting Numbers 加强版

    1 问题描述 Problem Description We call a number interesting, if and only if: 1. Its digits consists of o ...

  6. F Find the AFei Numbers

    链接:https://ac.nowcoder.com/acm/contest/338/F来源:牛客网 题目描述 AFei loves numbers. He defines the natural n ...

  7. CSU 2018年12月月赛 F(2218): Finding prime numbers

    Description xrdog has a number set. There are 95 numbers in this set. They all have something in com ...

  8. URAL 2070 Interesting Numbers (找规律)

    题意:在[L, R]之间求:x是个素数,因子个数是素数,同时满足两个条件,或者同时不满足两个条件的数的个数. 析:很明显所有的素数,因数都是2,是素数,所以我们只要算不是素数但因子是素数的数目就好,然 ...

  9. 【线性筛】【筛法求素数】【约数个数定理】URAL - 2070 - Interesting Numbers

    素数必然符合题意. 对于合数,如若它是某个素数x的k次方(k为某个素数y减去1),一定不符合题意.只需找出这些数. 由约数个数定理,其他合数一定符合题意. 就从小到大枚举素数,然后把它的素数-1次方都 ...

随机推荐

  1. C语言待研究问题

    1.内存分配 变量的静态分配和静态变量的区别: 变量的静态分配和动态分配 2.堆和栈的区别 3.CPU的并发性 4.变量和参数的区别

  2. Android开发数据存储之ContentProvider详解

    转载:十二.ContentProvider和Uri详解 一.使用ContentProvider(内容提供者)共享数据 ContentProvider在android中的作用是对外共享数据,也就是说你可 ...

  3. iPhone重绘机制drawRect

    如何使用iPhone进行绘图.重绘操作iPhone的绘图操作是在UIView类的drawRect方法中完成的,所以如果我们要想在一个UIView中绘图,需要写一个扩展UIView 的类,并重写draw ...

  4. 10 ways to be a faster code reviewer--reference

    reference:http://blog.codacy.com/top-10-faster-code-reviews/ This is a blog post of our Code Reading ...

  5. Java最重要的21个技术点和知识点之JAVA多线程、时间处理、数据格式

    (四)Java最重要的21个技术点和知识点之JAVA多线程.时间处理.数据格式  写这篇文章的目的是想总结一下自己这么多年JAVA培训的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能 ...

  6. SQL Server 中的事务和锁(三)-Range S-U,X-X 以及死锁

    在上一篇中忘记了一个细节.Range T-K 到底代表了什么?Range T-K Lock 代表了在 SERIALIZABLE 隔离级别中,为了保护范围内的数据不被并发的事务影响而使用的一类锁模式(避 ...

  7. 【阿里云产品公测】离线归档OAS,在也不用备份担心空间了

    作者:阿里云用户 莫须有3i 1 起步 1.1 初识OAS 啥是OAS,请看官方说明: 引用 开放归档服务(Open Archive Service,简称OAS),致力于提供低成本.高可靠的数据归档服 ...

  8. mybatis--MapperProxy事务

    上篇 详细分析了org.mybatis.spring.mapper.MapperScannerConfigurer 和 org.mybatis.spring.SqlSessionFactoryBean ...

  9. duplicate symbol _OBJC_METACLASS_$ 报错记录

    duplicate symbol _OBJC_METACLASS_$_TabbarButton in: /Users/hw201406/Library/Developer/Xcode/DerivedD ...

  10. js验证连续两位数字递增或递减和连续三位数字相同

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...