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行)数位dp时,如果p<0则需要直接return0,否则导致数组越界WA。

2.(55-61行)并非只需要枚举x,然后在出现4和7总次数小于x的数中任意取6个即可。要求不是6个数的最大值小于x,而是6个数的和小于x。

3.(62-70行)逻辑错误,对比72-78行

还可以写成

1 for(i=1;i<=10;i++)
2 {
3     if(ans1[i]==0)    continue;
4     nowmax=i;
5     dfs(0,0,ans1[i]);
6 }

4.失败的dfs(不能按照从小到大的顺序取)

 1 void dfs(LL num,LL maxn,LL maxnum,LL sum,LL nowans)
 2 {
 3     if(sum>=nowmax)    return;
 4     if(num==6)
 5     {
 6         anss=(anss+nowans)%md;
 7         return;
 8     }
 9     if(maxnum+1<=ans1[maxn])
10     {
11         dfs(num+1,maxn,maxnum+1,sum+maxn,nowans*(ans1[maxn]-maxnum)%md);
12     }
13     LL i;
14     for(i=maxn+1;i<nowmax;i++)
15         if(ans1[i]>0)
16         {
17             dfs(num+1,i,1,sum+i,nowans*ans1[i]%md);
18         }
19 }

程序:

 1 #include<cstdio>
 2 #include<cstring>
 3 #define md 1000000007
 4 typedef long long LL;
 5 LL ans[100][20][2];
 6 LL w[20];
 7 LL ans1[20];
 8 LL m,ttt,anss,low,anst;
 9 LL a[10];
10 LL nowmax;
11 LL dp(LL p,LL pos,bool pre0,bool limit)
12 {
13     if(p<0)    return 0;//曾经忘记,导致下面15行数组越界以及无用的dfs,导致WA
14     if(pos<1)    return p==0&&!pre0;
15     if(!limit&&ans[p][pos][pre0]!=-1)
16         return ans[p][pos][pre0];
17     LL i,res=0,end=limit?w[pos]:9;
18     for(i=0;i<=end;i++)
19         res+=dp(p-(i==4||i==7),pos-1,pre0&&i==0,limit&&i==w[pos]);
20     return limit?res:(ans[p][pos][pre0]=res);
21 }
22 LL get(LL x,LL tt)
23 {
24     LL g;
25     for(g=0;x>0;x/=10)    w[++g]=x%10;
26     return dp(tt,g,1,1);
27 }
28 void dfs(LL num,LL sum,LL nowans)
29 {
30     if(sum>=nowmax)    return;
31     if(num==6)
32     {
33         anss=(anss+nowans)%md;
34         return;
35     }
36     LL i;
37     for(i=0;i<nowmax;i++)
38     {
39         if(ans1[i]==0)    continue;
40         ans1[i]--;
41         dfs(num+1,sum+i,nowans*(ans1[i]+1)%md);
42         ans1[i]++;
43     }
44 }
45 int main()
46 {
47     LL i;
48     memset(ans,-1,sizeof(ans));
49     scanf("%I64d",&m);
50     for(i=0;i<=10;i++)
51     {
52         //printf("%I64d  %I64d\n",i,get(m,i));
53         ans1[i]=get(m,i);
54     }
55 //    for(i=1;i<=10;i++)
56 //    {
57 //        low+=ans1[i-1];
58 //        ttt=low*(low-1)%md*(low-2)%md*(low-3)%md*(low-4)%md*(low-5)%md;
59 //        if(ttt<0)    ttt=0;
60 //        anss=(anss+ttt*ans1[i])%md;//此版本错误
61 //    }
62 //    for(i=1;i<=10;i++)
63 //    {
64 //        if(ans1[i]==0)    continue;
65 //        nowmax=i;
66 //        //ans1[i]--;
67 //        dfs(0,0,1);
68 //        //ans1[i]++;
69 //        anss=(anss*ans1[i])%md;//此版本错误
70 //    }
71     for(i=1;i<=10;i++)
72     {
73         if(ans1[i]==0)    continue;
74         nowmax=i;
75         anss=0;
76         dfs(0,0,1);
77         anst=(anst+anss*ans1[i])%md;
78     }
79     //printf("%I64d",anss);
80     printf("%I64d",anst);
81     return 0;
82 }
时间: 2024-11-10 07:03:53

Little Elephant and Elections CodeForces - 258B的相关文章

[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 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

Little Elephant and Elections小象选举

在我正看着roll神的博客的时候发现了自己的错误 #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include &

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 258B】 Sort the Array

[题目链接] http://codeforces.com/contest/451/problem/B [算法] 模拟 在序列中找到一段单调递增的子序列,将这段序列反转,然后判断序列是否变得单调递增,即可 [代码] #include<bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 10; int i,n,l,r; bool flag; int a[MAXN]; int main() { scanf("%d"

ACM总结——dp专辑(转)

感谢博主——      http://blog.csdn.net/cc_again?viewmode=list       ----------  Accagain  2014年5月15日 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. 本人动态规划博客地址:http://blog.csdn.net/cc_again/article/category/1261899 ***********************

【DP专辑】ACM动态规划总结

转载请注明出处,谢谢.   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15日 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. 本人动态规划博客地址:http://blog.csdn.net/cc_again/article/category/1261899 ******************

(转)dp动态规划分类详解

dp动态规划分类详解 转自:http://blog.csdn.NET/cc_again/article/details/25866971 动态规划一直是ACM竞赛中的重点,同时又是难点,因为该算法时间效率高,代码量少,多元性强,主要考察思维能力.建模抽象能力.灵活度. ****************************************************************************************** 动态规划(英语:Dynamic programm

这个是转的。学完就删_(:з」∠)_

原文链接:http://blog.csdn.net/cc_again/article/details/25866971 好多dp:http://blog.csdn.net/cc_again/article/category/1261899 一.简单基础dp 这类dp主要是一些状态比较容易表示,转移方程比较好想,问题比较基本常见的.主要包括递推.背包.LIS(最长递增序列),LCS(最长公共子序列),下面针对这几种类型,推荐一下比较好的学习资料和题目. 1.递推: 递推一般形式比较单一,从前往后,