UVA - 11361 Investigating Div-Sum Property(数位dp/记忆化搜索板子)
生活随笔
收集整理的這篇文章主要介紹了
UVA - 11361 Investigating Div-Sum Property(数位dp/记忆化搜索板子)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目:https://vjudge.net/problem/UVA-11361
思路:數位dp,用記憶化搜索寫,dp[pos][i][j][limit] 代表剩余有pos位,每位上的數字和模k 等于i, 當前總數值模k等于j,limit代表限制位。
本題還要注意的是當k》100時 答案為0,要加個特判,不然k=100000會導致內存不夠。
代碼(含注釋):
#include<bits/stdc++.h> #define INF 0x3f3f3f3f3f3f3f3f #define inf 0x3f3f3f3f #define FILL(a,b) (memset(a,b,sizeof(a))) #define re register #define lson rt<<1 #define rson rt<<1|1 #define lowbit(a) ((a)&-(a)) #define ios std::ios::sync_with_stdio(false);std::cin.tie(0);std::cout.tie(0); #define fi first #define rep(i,n) for(int i=0;(i)<(n);i++) #define rep1(i,n) for(int i=1;(i)<=(n);i++) #define se secondusing namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int > pii; int dx[4]= {-1,1,0,0},dy[4]= {0,0,1,-1}; const ll mod=1000000000; const ll N =1e5+10; const double eps = 1e-4; const double pi=acos(-1); ll gcd(int a,int b){return !b?a:gcd(b,a%b);} ll dp[20][100][11000][5]; int sum[100]; int l,r,k; int idx; ll dfs(int pos,int i,int j,int limit) {if(pos==0){if(i==0&&j==0)//兩者都成立時 才找到一個答案return 1;return 0;}if(dp[pos][i][j][limit]>=0) return dp[pos][i][j][limit];//之前已經搜過了ll ans=0;for(int q=0;q<(limit?sum[pos]:10);q++){ans+=dfs(pos-1,(i+q)%k,(j*10+q*)%k,0);//pos位的數比sum【pos】小,下一位沒有limit}if(limit)//有limit時pos位選擇最大的那個,下一位也應該有limit{ans+=dfs(pos-1,(sum[pos]+i)%k,(j*10+sum[pos])%k,1);}return dp[pos][i][j][limit]=ans; } ll work(int x)//把每一位上的數字保存起來 {idx=0;while(x>0){sum[++idx]=x%10;x/=10;}return dfs(idx,0,0,1); } void slove() {cin>>l>>r>>k;if(k>100) {//大于100時直接輸出cout<<0<<endl;return;}FILL(dp,-1);cout<<work(r)-work(l-1)<<endl;//經典算法了,兩前綴相減等于區間和。// cout<<fixed<<setprecision(7)<<dp[n]<<endl; } int main() {iosint t=1;cin>>t;fun();while(t--){slove();}return 0; }總結
以上是生活随笔為你收集整理的UVA - 11361 Investigating Div-Sum Property(数位dp/记忆化搜索板子)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 红枣莲藕排骨汤 红枣莲藕排骨汤做法
- 下一篇: UVA - 10253 Series-P