Codeforces 259 D 数位DP + 搜索
2013-01-16 15:16
295 查看
http://www.codeforces.com/contest/259/problem/D
数位DP可以写成递归和非递归两种:
递归:
非递归:
数位DP可以写成递归和非递归两种:
递归:
#include <cstdio> #include <cstring> #include <algorithm> #define LL __int64 const LL mod = 1000000007; LL dp[11], ans; int len; char a[11]; void add(int dep, int dig, int num) { if(!dep) { dp[dig] += num; return; } add(dep-1, dig+1, num*2); add(dep-1, dig, num*8); } void dfs(int dep, int sum, int tot) { int i; if(sum >= len) return; if(dep == 6) { for(i = sum+1; i <= len; i++) ans = (ans + tot*dp[i])% mod; return; } for(i = 0; i < len; i++) { if(dp[i]) { dp[i]--; dfs(dep+1, sum+i, tot*(dp[i]+1)%mod); dp[i]++; } } } int main() { int i, j, t = 0; len = strlen(gets(a)); for(i = 0; i < len; i++) { for(j = 0; j < a[i] - '0'; j++) { if(j == 4 || j == 7) add(len-1-i, t+1, 1); else add(len-1-i, t, 1); } if(a[i] == '4' || a[i] == '7') t++; } dp[t]++, dp[0]--; // for(i = 0; i <= 9; i++) // printf("%d\n", dp[i]); dfs(0, 0, 1); printf("%I64d\n", ans); return 0; }
非递归:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define LL __int64 LL dp[11][11], f[11]; int a[11], n; const LL mod = 1000000007; void init() { int i, j, k; dp[1][1] = 2; dp[1][0] = 8; for(i = 2; i <= 9; i++) { for(j = 1; j <= i; j++) dp[i][j] = (dp[i-1][j] * 8 + dp[i-1][j-1] * 2) % mod; dp[i][0] = dp[i-1][0] * 8 % mod; } // for(i = 2; i <= 9; i++) // for(j = 0; j <= i; j++) // printf("dp[%d][%d] = %I64d\n", i, j, dp[i][j]); } LL ans; int l; void dfs(int dep, int sum, LL tot) { int i; if(dep == 6) { for(i = sum+1; i <= l; i++) ans = (ans + tot * f[i]) % mod; return; } if(sum >= l) return; for(i = 0; i <= l; i++) if(f[i]) { f[i]--; dfs(dep+1, sum+i, tot*(f[i]+1)%mod); f[i]++; } } int main() { init(); int i, j, k; scanf("%d", &n); while(n) {a[l++] = n % 10; n /= 10;} //处理位数< l 的 数 for(j = 0; j <= l-1; j++) f[j] = (f[j] + dp[l-1][j]) % mod; // for(i = 0; i <= 9; i++) // printf("f[%d] = %I64d\n", i, f[i]); LL cnt = 0; for(i = l-1; i >= 0; i--) // 每一位降位处理 { for(j = (i == l-1 ? 1 : 0); j < a[i]; j++) // 注意首位不能为0,很容易出错 { if(j==4 || j==7) for(k = cnt+1; k <= cnt+i+1; k++) // 注意lucky number 的 范围 f[k] = (f[k] + (i ? dp[i][k-1-cnt] : 1)) % mod; else for(k = cnt; k <= cnt+i; k++) // 注意lucky number 的 范围 f[k] = (f[k] + (i ? dp[i][k-cnt] : 1)) % mod; } // for(j = 0; j <= 9; j++) // printf("i = %d f[%d] = %I64d\n", i, j, f[j]); cnt += (a[i]==4 || a[i]==7); } f[cnt]++; if(l > 1)f[0]--; //特别注意 输入的数只有一位的时候, 我们没有 把 0 算进去,所以不用去零。 // for(i = 0; i <= 9; i++) // printf("f[%d] = %I64d\n", i, f[i]); dfs(0, 0, 1); printf("%I64d\n", ans); return 0; }
相关文章推荐
- [Codeforces 258B & 259 D]Little Elephant and Elections 数位dp+dfs
- CodeForces 55D Beautiful numbers (数位DP+状态简化,5级)
- Codeforces 431 D. Random Task 数位dp单调性
- CodeForces 258B Little Elephant and Elections 数位DP
- codeforces 560E Gerald and Giant Chess (dp + 组合数)
- CodeForces 164A Variable, or There and Back Again(搜索)
- codeforces 776C Molly's Chemicals(前缀和 二分搜索)
- codeforces 55D Beautiful numbers(数位DP)
- CodeForces 55D Beautiful numbers (数位DP)
- CodeForces 55D Beautiful numbers (数位dp+搜索)★
- Codeforces 55d 数位dp
- Codeforces Div. 2 #259-C. Little Pony and Expected Maximum
- CodeForces 813A|813B|813C|813D - 搜索|DP
- codeforces 509C C. Sums of Digits(数位dp+贪心+枚举)
- Codeforces 621E Wet Shark and Block【dp + 矩阵快速幂】
- 【数位DP】 Codeforces 55D Beautiful numbers
- 【搜索】【并查集】Codeforces 691D Swaps in Permutation
- Arthur and Walls - CodeForces 525 D 搜索
- 【codeforces】55D. Beautiful numbers 数位DP
- 【数位DP】 codeforces 55D && FZU chriswho