HDU6156 Palindrome Function[数位DP]

来源:互联网 发布:win共享mac桌面 编辑:程序博客网 时间:2024/05/22 07:47

Palindrome Function

 HDU - 6156






 

题意:

给T组数据,每组数据含有 L,R,l,r, 求出函数

其中f(i,j)表示


题解:

这很容易把思维转向知道R里面有多少个回文数,L-1(因为范围包括了L)里面有多少个回文数,减去差值然后乘上权值j,,再加上[L,R]之间不能构成回文数的个数,就可以得到答案了。

其中,十进制的回文数判断,在LightOJ1205出现过,如果没做过的,可以现去做做这题。

我们用同样的方法,只要多一维记录下当前进制。

那么最后我们可以得到dp[k][i][j][2] 第一维表示k进制下,第二维表示当前位置,第三维表示回文数的长度(从0开始,理解为起点也可以),第四维表示是否能构成回文串。

每次记录下当前枚举的数。

判断过程中,对前导0作处理,也就是说当当前位置与回文数长度一致时,而当前枚举为0,那么回文数长度跟着当前位置减一,然后再继续往下找。

当当前位置距离回文数的长度,超过了一半的时候,开始判断后面枚举的数是否与前面已经枚举了的数出现回文。

最后根据f(i,j)的值,对回文数的个数处理一下就好。


T_T 一开始我还傻傻的以为自己算错算错,其实只是算了回文数的个数。



#pragma comment(linker, "/STACK:102400000,102400000")#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<string>#include<algorithm>#include<queue>#include<stack>#include<set>#include<map>#include<vector>using namespace std;typedef long long ll;const int M=40;ll dp[M][M][M][2];int num[M],tmp[M];ll dfs(int pos,int k,int cnt,bool state,bool limit){    if (pos==-1)        return state;    if (!limit && dp[k][pos][cnt][state]!=-1)        return dp[k][pos][cnt][state];    int up=limit?num[pos]:k-1;    ll res=0;    for (int i=0 ; i<=up ; ++i)    {        tmp[pos]=i;        if (pos==cnt && !i)            res+=dfs(pos-1,k,cnt-1,state,limit && i==num[pos]);        else if (state && pos<(cnt+1)/2)            res+=dfs(pos-1,k,cnt,i==tmp[cnt-pos],limit && i==num[pos]);        else            res+=dfs(pos-1,k,cnt,state,limit && i==num[pos]);    }    if (!limit)        dp[k][pos][cnt][state]=res;    return res;}ll solve(int x,int k){    int pos=0;    while (x)    {        num[pos++]=x%k;        x/=k;    }    ll ans=dfs(pos-1,k,pos-1,1,1);    return ans;}int main(){    memset(dp,-1,sizeof(dp));    int T;    scanf("%d",&T);    for (int test=1 ; test<=T ; ++test)    {        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 rn=solve(R,i);            ll ln=solve(L-1,i);            ans+=(rn-ln)*i;            ans+=(R-rn-(L-1-ln));        }        printf("Case #%d: %lld\n",test,ans);    }    return 0;}





原创粉丝点击