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. 剑指 offer set 8 树的子结构

    总结 1. 解法分为两步, 一是定位树的头结点, 二是两棵树作比较 2. 两个数作比较, 包括比较两棵树是否相等, 或者两个数是否镜像, 算法的框架类似 bool comp(root1, root2)

  2. mysql博客

    http://blog.csdn.net/mchdba/article/details/9190771 本帖最后由 mchdba 于 2014-2-10 17:15 编辑 公司招聘MySQL DBA, ...

  3. Nginx的一些基本功能极速入门

    本文主要介绍一些Nginx的最基本功能以及简单配置,但不包括Nginx的安装部署以及实现原理. 1.静态HTTP服务器 首先,Nginx是一个HTTP服务器,可以将服务器上的静态文件(如HTML.图片 ...

  4. WPF 之 利用Visibility属性进行Item模板切换

    前台Xaml如下: <Grid.Resources> <xx:AccountStatusToVisibility x:Key="AccountStatusToVisibil ...

  5. Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件

    1. 引言: RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一 ...

  6. 沈逸老师PHP魔鬼特训笔记(5)

    接上一节课,我们专门新建了一个godconfig类,设置了两个属性prj_name(项目名),prj_author(作者),然后我们获取标准输入(stdin)把结果保存在了类里面. 好吧,这节课的名字 ...

  7. 【Linux/Ubuntu学习6】unbuntu 下载android源码

    在Windows下安装Cygwin,通过Cygwin也可在Windows里通过本文的下载步骤下载Android源码. 以下为在Ubuntu下下载Google Android4.4源码的步骤: 1. 安 ...

  8. 【Shell脚本学习2】Shell脚本语言与编译型语言的差异

    大体上,可以将程序设计语言可以分为两类:编译型语言和解释型语言. 编译型语言 很多传统的程序设计语言,例如Fortran.Ada.Pascal.C.C++和Java,都是编译型语言.这类语言需要预先将 ...

  9. Android小项目之五 splash动画效果

    ------- 源自梦想.永远是你IT事业的好友.只是勇敢地说出我学到! ---------- 按惯例,写在前面的:可能在学习Android的过程中,大家会和我一样,学习过大量的基础知识,很多的知识点 ...

  10. CF Soldier and Cards (模拟)

    Soldier and Cards time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...