生活随笔
收集整理的這篇文章主要介紹了
HDU - 6156 Palindrome Function(数位dp)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一段區間 [ l , r ] ,問十進制下的 [ l , r ] 內在 k 進制下有多少個回文串
題目分析:對于每個進制下求數位 dp 即可,dp[ pos ][ len ][ k ] 記錄的是在第 pos 位上,回文串的長度為 len ,在 k 進制下有多少個回文串,根據數位dp空間復雜度來計算時間復雜度,大概就是 40^3 * 36 ,1e6左右的級別,通過該題目還是綽綽有余的
代碼:
?
//#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=2e5+100;LL dp[40][40][40];int b[40],t[40];LL dfs(int pos,int len,int k,bool limit)
{if(pos==0)return 1;if(!limit&&dp[pos][len][k]!=-1)return dp[pos][len][k];int up=limit?b[pos]:k-1;LL ans=0;for(int i=0;i<=up;i++){t[pos]=i;if(pos==len&&i==0)//前導0 ans+=dfs(pos-1,len-1,k,limit&&i==up);else if(pos>len/2)//前半段隨便選 ans+=dfs(pos-1,len,k,limit&&i==up);else if(t[len-pos+1]==i)//后半段只能選回文 ans+=dfs(pos-1,len,k,limit&&i==up);}if(!limit)dp[pos][len][k]=ans;return ans;
}LL solve(LL n,int k)
{int cnt=0;while(n){b[++cnt]=n%k;n/=k;}return dfs(cnt,cnt,k,true);
}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));int w;cin>>w;int kase=0;while(w--){int l,r,L,R;scanf("%d%d%d%d",&l,&r,&L,&R);LL ans=0;for(int i=L;i<=R;i++){LL t=solve(r,i)-solve(l-1,i);ans+=r-l+1-t+t*i;}printf("Case #%d: %lld\n",++kase,ans);}return 0;
}
?
總結
以上是生活随笔為你收集整理的HDU - 6156 Palindrome Function(数位dp)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。