Little Elephant and Elections CodeForces - 258B
阿新 • • 發佈:2017-09-30
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