CodeForces 258B Little Elephant and Elections 数位DP

前面先用数位DP预处理,然后暴力计算组合方式即可。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int maxn = 20;
const LL MOD = 1e9 + 7;
int M,lim[maxn],len;
bool vis[maxn][maxn];
struct EE {
    LL cnt[maxn];
    EE() {
        memset(cnt,0,sizeof(cnt));
    }
};
EE f[maxn][maxn], ans;

void getlim(int num) {
    len = 0;
    memset(lim,0,sizeof(lim));
    while(num) {
        lim[len++] = num % 10;
        num /= 10;
    }
}

EE dfs(int now,int cnt,int bound) {
    if(now == 0) {
        EE ret;
        ret.cnt[cnt] = 1;
        return ret;
    }
    if(!bound && vis[now][cnt]) return f[now][cnt];
    int m = bound ? lim[now - 1] : 9;
    EE ret;
    for(int i = 0;i <= m;i++) {
        EE nret = dfs(now - 1,cnt + (i == 4 || i == 7),bound && i == m);
        for(int i = 0;i <= len;i++) ret.cnt[i] += nret.cnt[i];
    }
    if(!bound) {
        f[now][cnt] = ret;
        vis[now][cnt] = true;
    }
    return ret;
}

LL A(LL m,LL n) {
    LL ret = 1;
    for(int i = 1;i <= n;i++) {
        ret *= m; m--; ret %= MOD;
    }
    return ret;
}

LL rest[maxn],rcnt[maxn];
LL dfs1(int now,int sum,int limm) {
    if(sum >= limm) return 0;
    if(now == 7) {
        LL ret = 1;
        for(int i = 0;i < limm;i++) if(rcnt[i]) {
            ret = (ret * A(ans.cnt[i],rcnt[i])) % MOD;
        }
        return ret;
    }
    LL ret = 0;
    for(int i = 0;i < limm;i++) if(rest[i]) {
        rcnt[i]++; rest[i]--;
        ret = (ret + dfs1(now + 1,sum + i,limm)) % MOD;
        rcnt[i]--; rest[i]++;
    }
    return ret;
}

void solve() {
    memset(vis,0,sizeof(vis));
    getlim(M);
    ans = dfs(len,0,1);
    ans.cnt[0]--;
    LL out = 0;
    for(int i = 1;i <= len;i++) if(ans.cnt[i]) {
        memcpy(rest,ans.cnt,sizeof(rest));
        memset(rcnt,0,sizeof(rcnt));
        out = (dfs1(1,0,i) * ans.cnt[i] % MOD + out) % MOD;
    }
    cout << out << endl;
}

int main() {
    cin >> M;
    solve();
    return 0;
}

  

CodeForces 258B Little Elephant and Elections 数位DP

时间: 2024-08-16 19:15:46

CodeForces 258B Little Elephant and Elections 数位DP的相关文章

[Codeforces 258B &amp; 259 D]Little Elephant and Elections 数位dp+dfs

http://codeforces.com/problemset/problem/258/B 题目大意: 说七个party选择数字(各不相同) 而规定的小象的party选择的数字之中所拥有的数字4和7的个数要比其他六个party拥有的个数之和还要严格多,询问方案数. 如m=7时其余的随意选择至少会拥有一个4或7,与题意矛盾,故方案数为0 m=8时,7 1 2 3 5 6 8是一种合法方案 思路: 由于小象的party选到的数字所含4和7的个数至多和m的位数一样多,则枚举小象的party所含4和7

CodeForces 204A Little Elephant and Interval 数位DP

#include <cstdio> #include <cstring> using namespace std; typedef __int64 LL; int a[33]; LL dp[33][10]; LL dfs(int x, int s, int e, int flag, int first) { if(x == -1) return s == e; if(!flag && dp[x][s]!= -1) return dp[x][s]; int end =

Codeforces Beta Round #51---D. Beautiful numbers(数位dp, 巧妙)

Volodya is an odd boy and his taste is strange as well. It seems to him that a positive integer number is beautiful if and only if it is divisible by each of its nonzero digits. We will not argue with this and just count the quantity of beautiful num

Codeforces Round #157 (Div. 1)B 数位dp

//枚举有几个(7或4),用数位dp的记忆化搜索找有i个(7或4)的数又多少个 //暴力搜索在第i个中选几个 #include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int mod = 1e9 + 7; int dp[20][20];//第i位有 j个数(7或者4) int bit[20] ; int temp[20]; int luck[20]; int dfs

CodeForces - 1073E :Segment Sum (数位DP)

You are given two integers l l and r r (l≤r l≤r ). Your task is to calculate the sum of numbers from l l to r r (including l l and r r ) such that each number contains at most k k different digits, and print this sum modulo 998244353 998244353 . For

CF 258B Little Elephant and Elections [dp+组合]

给出1,2,3...m 任取7个互不相同的数a1,a2,a3,a4,a5,a6,a7 一个数的幸运度是数位上4或7的个数 比如244,470幸运度是2. 44434,7276727,4747,7474,幸运度都是4. 求出满足a1,a2,a3,a4,a5,a6,a7这样的前6个数的幸运度之和严格小于第七个数的幸运度排列共有多少种 1.先求出数组t t[i]代表1-m中幸运度为i的数的个数. 2.有了t数组后,问题变为一个排列组合问题(枚举a7幸运度,求有多少排列满足前6幸运度之和小于a7幸运度,

Codeforces Round #387 (Div. 2) 747F(数位DP)

题目大意 给出整数k和t,需要产生一个满足以下要求的第k个十六进制数 即十六进制数每一位上的数出现的次数不超过t 首先我们先这样考虑,如果给你了0~f每个数字可以使用的次数num[i],如何求长度为L且满足要求的十六进制数有多少个 dp[i][l]表示使用了前i个数字,已经将L的空位填上了l个的数有多少个 转移方程 dp[i][l] = sigma(dp[i-1][l-j]*C[len-l+j[j]) 其中j是枚举填新的数的个数,C是组合数(选出j个空位填上新数) 有了这个dp后,现在的问题就变

Little Elephant and Elections CodeForces - 258B

Little Elephant and Elections CodeForces - 258B 题意:给出m,在1-m中先找出一个数x,再在剩下数中找出6个不同的数y1,...,y6,使得y1到y6中数字4和7出现的总次数严格小于x中数字4和7出现的总次数.求方案数. 方法:先数位dp分别预处理出:1到m之间,数字4和7出现的总次数为0到9的数.(总共最多10个数字,第一个最大1,因此4和7出现的总次数最多9次)然后枚举x,再暴力dfs枚举6个数,统计方案数. 问题(细节): 1.(13行)数位

codeforces Hill Number 数位dp

http://www.codeforces.com/gym/100827/attachments Hill Number Time Limits:  5000 MS   Memory Limits:  200000 KB 64-bit interger IO format:  %lld   Java class name:  Main Description A Hill Number is a number whose digits possibly rise and then possibl