1. 程式人生 > >Little Elephant and Elections CodeForces - 258B

Little Elephant and Elections CodeForces - 258B

clu == ttl 10個 最大值 ant ref 題意 col

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 }

Little Elephant and Elections CodeForces - 258B