Count SIN Numbers
Count SIN Numbers
題目鏈接:http://codeforces.com/group/gRkn7bDfsN/contest/211954/problem/D
數(shù)位DP
定義狀態(tài):dp[當(dāng)前第i位數(shù)][當(dāng)前位上的數(shù)字j][前i位數(shù)是否與給定數(shù)s相同][當(dāng)前位上的數(shù)是否為谷值][前i位數(shù)所代表的數(shù)是否前導(dǎo)零]表示從零到長為i末尾數(shù)字為j的符合狀態(tài)的數(shù)的個(gè)數(shù)。
狀態(tài)轉(zhuǎn)移方程:
當(dāng)前位上的數(shù)為谷值且前導(dǎo)零時(shí),下一位只能為零:
dp[i+1][0][k&(0==s[i]-'0')][!m][n==1]+=dp[i][j][k][m][n];
否則可取下一位數(shù)為p,for p in range(l,r+1):
dp[i+1][p][k&(p==s[i]-'0')][!m][n==1&&p==0]+=dp[i][j][k][m][n],其中l(wèi)和r的值由前i位數(shù)是否與給定數(shù)s相同以及當(dāng)前位上的數(shù)是否為谷值共同決定。
故A到B滿足條件的數(shù)的個(gè)數(shù)=從零到B符合條件的數(shù)的個(gè)數(shù)-從零到A符合條件的數(shù)的個(gè)數(shù)+(A符合條件?1:0)
代碼如下:
1 #include <cstdio> 2 #include <iostream> 3 #include <cstring> 4 #include <string> 5 using namespace std; 6 typedef long long ll; 7 ll dp[20][10][2][2][2],ans; 8 string a,b; 9 ll js(string s){ 10 ll len=s.length(); 11 memset(dp,0,sizeof(dp)); 12 dp[0][0][1][1][1]=dp[0][0][1][0][1]=1LL; 13 for(int i=0;i<len;++i) 14 for(int j=0;j<=9;++j) 15 for(int k=0;k<2;++k) 16 for(int m=0;m<2;++m) 17 for(int n=0;n<2;++n){ 18 if(dp[i][j][k][m][n]){ 19 int l=0,r=(k==1?s[i]-'0':9); 20 if(n!=1){ 21 if(m==0)r=min(r,j-1); 22 else l=j+1; 23 } 24 if(0<=l&&r<=9&&l<=r){ 25 if(m==1&&n==1){ 26 dp[i+1][0][k&(0==s[i]-'0')][!m][n==1] 27 +=dp[i][j][k][m][n]; 28 }else{ 29 for(int p=l;p<=r;++p) 30 dp[i+1][p][k&(p==s[i]-'0')][!m][n==1&&p==0] 31 +=dp[i][j][k][m][n]; 32 } 33 } 34 } 35 } 36 ll t=0; 37 for(int j=0;j<=9;++j) 38 for(int k=0;k<2;++k) 39 for(int m=0;m<2;++m) 40 for(int n=0;n<2;++n) 41 t+=dp[len][j][k][m][n]; 42 return t-2; 43 } 44 int main(void){ 45 cin>>a>>b; 46 ans=js(b)-js(a)+1; 47 for(int i=1;i<(int)a.length();++i) 48 if((i%2==1&&a[i]<=a[i-1])||(i%2==0&&a[i]>=a[i-1])){ 49 ans--; 50 break; 51 } 52 cout<<ans<<endl; 53 } 54?
轉(zhuǎn)載于:https://www.cnblogs.com/barrier/p/6412071.html
總結(jié)
以上是生活随笔為你收集整理的Count SIN Numbers的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 各技术镜像整理
- 下一篇: SQL Server-聚焦深入理解动态S