codeforces 258B
2016-01-22 23:29
337 查看
很经典的思路啊,比赛的时候没怎么多想,其实还很简单的。
题意:有7个party,然后有m个数字,1-m,每个party可以选择其中一个数字,4和7是幸运的字符,每个数字有多个幸运字符比如4447有四个。
问你第一个party选的数字的幸运字符个数 严格大于其他party选择的数字的幸运字符个数的和 的选择方法数。
用数位dp预处理出1-m之间幸运字符个数为i数字数为c[i],然后枚举第一个party选择的i,然后深搜其他party,在满足条件的情况下,全排列即可,最后求个和
题意:有7个party,然后有m个数字,1-m,每个party可以选择其中一个数字,4和7是幸运的字符,每个数字有多个幸运字符比如4447有四个。
问你第一个party选的数字的幸运字符个数 严格大于其他party选择的数字的幸运字符个数的和 的选择方法数。
用数位dp预处理出1-m之间幸运字符个数为i数字数为c[i],然后枚举第一个party选择的i,然后深搜其他party,在满足条件的情况下,全排列即可,最后求个和
// // Created by Matrix on 2016-01-22 // Copyright (c) 2015 Matrix. All rights reserved. // // //#pragma comment(linker, "/STACK:102400000,102400000") #include <algorithm> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iomanip> #include <iostream> #include <map> #include <queue> #include <string> #include <sstream> #include <set> #include <vector> #include <stack> #define ALL(x) x.begin(), x.end() #define INS(x) inserter(x, x,begin()) #define ll long long #define CLR(x) memset(x, 0, sizeof x) using namespace std; const int inf = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1e6 + 10; const int maxv = 1e3 + 10; const double eps = 1e-9; ll pow_mod(ll a, ll n) { ll ret = 1; while(n) { if(n & 1) ret = ret * a % MOD; a = a * a % MOD; n >>= 1; } return ret; } int digit[55]; ll c[10]; ll dp[55][20][20]; ll dfs(int step, int limit, int cnt, int ju) { if(step == 0) { return cnt == ju; } if(!limit && dp[step][cnt][ju] != -1) return dp[step][cnt][ju]; ll ret = 0; int up = limit ? digit[step] : 9; for(int i = 0; i <= up; i++) { ret += dfs(step-1, limit && i == up, cnt + (i == 4 || i == 7 ? 1 : 0), ju); } if(!limit) dp[step][cnt][ju] = ret; return ret; } ll A(ll n, ll a) { ll ret = 1; if(a > n) return 0; while(a--) { ret = ret * n % MOD; n--; } return ret; } ll calc(ll n, int ju) { memset(dp, -1, sizeof dp); int top = 0; while(n) { digit[++top] = n % 10; n /= 10; } return dfs(top, 1, 0, ju); } ll res; void DFS(int step, int sum, int ju) { if(step == 6) { ll cnt = 1; for(int i = 0; i < ju; i++) { if(digit[i]) { cnt = cnt * A(c[i], digit[i]) % MOD; } } // printf("ju = %d cnt = %lld\n", ju, cnt); res += cnt; return; } for(int i = 0; i + sum < ju; i++) { if(digit[i] >= c[i]) continue; digit[i]++; DFS(step+1, sum + i, ju); digit[i]--; } } int main() { #ifdef LOCAL freopen("in.txt", "r", stdin); // freopen("out.txt","w",stdout); #endif ll m; while(cin >> m) { CLR(c); for(int i = 0; i <= 9; i++) { c[i] = calc(m, i); } c[0]--; // for(int i = 0; i <= 9; i++) { // printf("c[%d] = %lld\n", i, c[i]); // } ll ans = 0; for(int i = 1; i <= 9; i++) { if(!c[i]) continue; res = 0; CLR(digit); DFS(0, 0, i); ans = (ans + res * c[i] % MOD) % MOD; } printf("%lld\n", ans); } return 0; }
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- HP data protector软件学习1--基本角色与基本工作流程
- HP data protector软件学习2--软件组成与界面介绍
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- POJ-1695-Magazine Delivery-dp
- nyoj-1216-整理图书-dp
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray
- DP Flow