http://acm.nbut.cn:8081/Problem/view.xhtml?id=1545
很裸的数位dp....按习惯用了预处理,代码很长
但是看看人家用记忆化搜索写的如此简单,也试着写了下
写的真是搓........代码反而更长了,各种特判....
预处理:
#include<iostream>
using namespace std;
typedef long long LL;
LL dp[19][16];
int bit[19];
int len;
void init()
{
for(int i=1;i<=18;i++)
{
if(i==1)
{
for(int j=0;j<10;j++)
dp[i][j]=1;
continue;
}
for(int j=0;j<10;j++)
{
for(int k=0;k<16;k++)
{
if((j^k)<16)
dp[i][j^k]+=dp[i-1][k];
}
}
}
}
void get_bit(LL n)
{
len=0;
while(n)
{
bit[++len]=n%10;
n/=10;
}
}
LL cal(LL n,int c)
{
LL ans=0;
int t=0;
for(int i=len;i>1;i--)
{
for(int j=0;j<bit[i];j++)
for(int k=0;k<16;k++)
{
if((t^j^k)==c)
ans+=dp[i-1][k];
}
t^=bit[i];
}
for(int k=0;k<=bit[1];k++)
{
if((t^k)==c)
ans+=dp[1][k];
}
if(c==0)
ans--;
return ans;
}
int main()
{
ios::sync_with_stdio(false);
init();
LL n;
int k;
while(cin>>n>>k)
{
if(n==0||k>15)
{
cout<<0<<endl;
continue;
}
get_bit(n);
cout<<cal(n,k)<<endl;
}
return 0;
}
记忆化搜索:
#include<iostream>
using namespace std;
typedef long long LL;
LL dp[19][1<<4];
int bit[19];
int len;
void get_bit(LL n)
{
len=0;
while(n)
{
bit[++len]=n%10;
n/=10;
}
}
LL dfs(int l,int k,bool flag)
{
if(dp[l][k]!=-1&&flag)
return dp[l][k];
if(l==1)
{
if(flag)
{
if(k<=9)
return 1;
else
return 0;
}
else
{
if(k<=bit[1])
return 1;
else
return 0;
}
}
LL ans=0;
if(flag)
for(int i=0;i<=9;i++)
ans+=dfs(l-1,i^k,1);
else
for(int i=0;i<=bit[l];i++)
ans+=dfs(l-1,i^k,i==bit[l]?0:1);
if(flag)
dp[l][k]=ans;
return ans;
}
int main()
{
ios::sync_with_stdio(false);
LL n;
int k;
while(cin>>n>>k)
{
if(n==0||k>=1<<4)
{
cout<<0<<endl;
continue;
}
memset(dp,-1,sizeof(dp));
get_bit(n);
LL ans=dfs(len,k,0);
if(k==0)
ans--;
cout<<ans<<endl;
}
return 0;
}