Codeforces 747F Igor and Interesting Numbers dp

Igor and Interesting Numbers

枚举每一位, 用dp去算方案数。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define ull unsigned long long
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define fio ios::sync_with_stdio(false); cin.tie(0);

using namespace std;

const int N = 20 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

LL F[18];
LL dp[16][18];

int c[16];
int ans[17];

int k, t;

LL getDp(int n, int *c) {
    if(n == 0) return 1;
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i <= c[0]; i++) dp[0][i] = 1;
    for(int i = 0; i < 15; i++) {
        for(int j = 0; j <= n; j++) {
            for(int k = 0; k <= c[i + 1]; k++) {
                if(j + k > n) continue;
                dp[i + 1][j + k] += F[j + k] / F[j] / F[k] * dp[i][j];
            }
        }
    }
    return dp[15][n];
}

char print(int x) {
    if(x <= 9) return ‘0‘ + x;
    else return ‘a‘ + (x - 10);
}

int main() {
    for(int i = F[0] = 1; i <= 17; i++) F[i] = F[i - 1] * i;
    scanf("%d%d", &k, &t);
    for(int i = 0; i <= 15; i++) c[i] = t;
    for(int len = 1; len <= 17; len++) {
        LL tot = 0;
        for(int j = 1; j <= 15; j++) {
            if(!c[j]) continue;
            c[j]--;
            int way = getDp(len - 1, c);
            if(way < k) k -= way, c[j]++, tot += way;
            else {
                ans[1] = j;
                break;
            }
        }
        if(!ans[1]) continue;
        for(int i = 2; i <= len; i++) {
            for(int j = 0; j <= 15; j++) {
                if(!c[j]) continue;
                c[j]--;
                int way = getDp(len - i, c);
                if(way < k) k -= way, c[j]++;
                else {
                    ans[i] = j;
                    break;
                }
            }
        }
        for(int i = 1; i <= len; i++) printf("%c", print(ans[i]));
        puts("");
        return 0;
    }
    return 0;
}

/*
*/

原文地址:https://www.cnblogs.com/CJLHY/p/10930100.html

时间: 2024-11-08 22:05:23

Codeforces 747F Igor and Interesting Numbers dp的相关文章

Codeforces 747F Igor and Interesting Numbers DP 组合数

题意:给你一个数n和t,问字母出现次数不超过t,第n小的16进制数是多少. 思路:容易联想到数位DP, 然而并不是...我们需要知道有多少位,在知道有多少位之后,用试填法找出答案.我们设dp[i][j]为考虑前i种字母,已经占了j个位置的方案数.那么dp[i][j] += dp[i - 1][j - k] * C[len - j + k][k],k的范围为[0, limit[k]].意思是我们暴力枚举第i个字母放多少个,然后排列组合. 这个题有一个细节需要注意,因为最高为一定不为0,所以我们试填

Codeforces 449D:Jzzhu and Numbers

Codeforces 449D:Jzzhu and Numbers 题目链接:http://codeforces.com/problemset/status?friends=on 题目大意:给出$n$个数,求有多少种组合使得$a_{i_1}\&a_{i_2}\&...\&a_{i_k}=0(0 \leqslant i < n)$,答案对$10^9+7$取模. 容斥原理+DP 设位与$(\&)$后二进制表示中有$k$个$1$的组合数为$A_k$,则有, $A_0=$所有

CodeForces 540D Bad Luck Island 概率dp

CodeForces 540D 应该是简单概率dp,由于写得少显得十分蠢萌 求期望逆推,求概率正推,大概是这么个意思,贴一发留恋 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define db double const int maxn=108; db dp[maxn][maxn][maxn]; int main() { int i,j,n,m,k,p; whi

codeforces 148E Aragorn&#39;s Story 背包DP

Aragorn's Story Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/problem/148/E Description Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who

codeforces 446C DZY Loves Fibonacci Numbers(数学 or 数论+线段树)

In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation F1 = 1; F2 = 1; Fn = Fn - 1 + Fn - 2 (n > 2). DZY loves Fibonacci numbers very much. Today DZY gives you an array consisting of n integers: a1, a2, ...,

CodeForces 21D Traveling Graph 状压dp+欧拉回路

题目链接:点击打开链接 题意: 给定n个点m条边的无向图 求从1点开始经过每条边至少一次最后回到1点的最小路程 显然就是找一条路径可重复的欧拉回路 思路: 首先对于欧拉回路的结论是:所有点的度数都为偶数 因为所有边至少经过一次,那么可以把题意转换成加最少多少条边使得图满足以上结论 而加的边目的是为了把奇度数转成偶度数,先floyd一下得到任意点间加边的最小花费 dp[i]表示状态i下度数都为偶数的最小花费. 状压dp,把i状态下,所有未选择的点中挑2个奇度数的转移即可. #include <cs

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

目录 1 问题描述 2 解决方案   1 问题描述 Problem Description We call a number interesting, if and only if: 1. Its digits consists of only 0, 1, 2 and 3, and all these digits occurred at least once. 2. Inside this number, all 0s occur before any 1s, and all 2s occur

codeforces 446C DZY Loves Fibonacci Numbers 数论+线段树成段更新

DZY Loves Fibonacci Numbers Time Limit:4000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-14) Description In mathematical terms, the sequence Fn of Fibonacci numbers is defi

Codeforces 67C Sequence of Balls 编辑距离 dp

题目链接:点击打开链接 有一个交换操作比较特殊,所以记录每个点距离自己最近的那个字符的位置 然后交换就相当于把第一行要交换的2个字符 之间的字符都删掉 把第二行要交换的2个字符 之间的字符都插入第一行的2个字符之间 然后再进行交换. #include <cstdio> #include <cstring> #include<iostream> using namespace std; #define inf 10000000 #define N 4005 #define