日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces - 628D Magic Numbers(数位dp)

發(fā)布時間:2024/4/11 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 628D Magic Numbers(数位dp) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:首先規(guī)定一個不含前導(dǎo)零的數(shù)字如果滿足:

  • 從最高位開始,偶數(shù)位置全為 ddd
  • 從最高位開始,奇數(shù)位置不能出現(xiàn) ddd
  • 則稱該數(shù)字為 d?magicd-magicd?magic 數(shù)字。現(xiàn)在給出一個區(qū)間 [l,r][ l , r ][l,r] ,問區(qū)間內(nèi)有多少個可以整除 mmmd?magicd-magicd?magic 數(shù)字,lllrrr 同階且 l,r∈[1,102000]l,r \in [ 1 , 10^{2000} ]l,r[1,102000]

    題目分析:數(shù)位 dp,因為題目中規(guī)定了 lllrrr 同階,所以降低了些許難度(不用考慮前導(dǎo)零的影響了),所以比較顯然的一個狀態(tài)就是 dppos,sumdp_{pos,sum}dppos,sum?為當(dāng)前數(shù)位為 pospospos,對 mmm 取余后的結(jié)果為 sumsumsum 時的 d?magicd-magicd?magic 數(shù)字的個數(shù),不需要考慮前導(dǎo)零的話直接帶上一個 limitlimitlimit 去轉(zhuǎn)移就好了

    那么考慮一下如果 lllrrr 不同階,也就是需要考慮前導(dǎo)零的話該如何去做呢?其實加上兩維即可:dppos,sum,lead,evendp_{pos,sum,lead,even}dppos,sum,lead,even?,新增的 leadleadlead 意義為是否含有前導(dǎo)零,eveneveneven 實質(zhì)上是調(diào)節(jié)奇偶的,因為前導(dǎo)零的個數(shù)會影響最高位的奇偶性,所以需要一個變量調(diào)節(jié)一下,關(guān)于轉(zhuǎn)移的話對前導(dǎo)零實現(xiàn)一下細(xì)節(jié)就好了

    代碼:
    不含前導(dǎo)零

    // #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2100;const int mod=1e9+7;LL dp[N][N];string b;int m,d;LL dfs(int pos,int sum,int limit)//當(dāng)前的位置,%m的余數(shù) {if(pos==(int)b.size())return sum%m==0;if(!limit&&dp[pos][sum]!=-1)return dp[pos][sum];int up=limit?b[pos]-'0':9;LL ans=0;for(int i=0;i<=up;i++){if((pos&1)&&i!=d)//偶數(shù)位置必須為dcontinue;if(!(pos&1)&&i==d)//奇數(shù)位置不能為dcontinue;ans=(ans+dfs(pos+1,(sum*10+i)%m,limit&&i==up))%mod;}if(!limit)dp[pos][sum]=ans;return ans; }LL solve(string num) {b=num;return dfs(0,0,1); }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);memset(dp,-1,sizeof(dp));scanf("%d%d",&m,&d);string a,b;cin>>a>>b;auto check=[&](string num){int sum=0;for(int i=0;i<a.size();i++){sum=(sum*10+a[i]-'0')%m;if(i&1)//even{if(a[i]!='0'+d)return false;}else{if(a[i]=='0'+d)return false;}}return sum==0;};printf("%I64d\n",(check(a)+solve(b)-solve(a)+mod)%mod);return 0; }

    含有前導(dǎo)零

    // #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2100;const int mod=1e9+7;LL dp[N][N][2][2];//dp[pos][sum][lead][even]string b;int m,d;LL dfs(int pos,int sum,int limit,int lead,int even)//當(dāng)前的位置,%m的余數(shù) {if(pos==(int)b.size())return sum%m==0;if(!limit&&dp[pos][sum][lead][even]!=-1)return dp[pos][sum][lead][even];int up=limit?b[pos]-'0':9;LL ans=0;for(int i=0;i<=up;i++){if(((pos-even)&1)&&i!=d)//偶數(shù)位置必須為dcontinue;if(!((pos-even)&1)&&i==d)//奇數(shù)位置不能為dcontinue;if(lead&&i==0)//前導(dǎo)零ans=(ans+dfs(pos+1,(sum*10+i)%m,limit&&i==up,true,even^1))%mod;elseans=(ans+dfs(pos+1,(sum*10+i)%m,limit&&i==up,false,even))%mod;}if(!limit)dp[pos][sum][lead][even]=ans;return ans; }LL solve(string num) {b=num;return dfs(0,0,1,1,0); }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);memset(dp,-1,sizeof(dp));scanf("%d%d",&m,&d);string a,b;cin>>a>>b;auto check=[&](string num){int sum=0;for(int i=0;i<(int)a.size();i++){sum=(sum*10+a[i]-'0')%m;if(i&1)//even{if(a[i]!='0'+d)return false;}else{if(a[i]=='0'+d)return false;}}return sum==0;};printf("%I64d\n",(check(a)+solve(b)-solve(a)+mod)%mod);return 0; }

    總結(jié)

    以上是生活随笔為你收集整理的CodeForces - 628D Magic Numbers(数位dp)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。