题解在代码中

Amount of Degrees[loj 10163]

/*
此题可以转换成将10进制转成b进制后有k个1其他都为0的个数
所以用记忆化dfs
dp[pos][sum]表示将要处理第pos位,前面已有sum个一的数量 
*/ 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
inline long long read()
{
    long long f=1,ans=0;char c;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
    return ans*f;
}
int x,y,k,b,dg[31],ans,dp[101][101];
long long dfs(long long pos,long long sum,long long done,long long sry)
{
//    cout<<"位置:"<<pos<<" 一的个数:"<<sum<<"  小于等于:"<<done<<"  原来的数:"<<sry<<endl;
    if(sum>k) return 0;
    if(pos==0) 
    {
        if(sum==k) return 1;
        return 0;
    }
    if(done==0&&dp[pos][sum]!=-1) return dp[pos][sum];
    long long end;
    if(done==0) end=1;
    else end=min(1,dg[pos]);
    long long maxn=0;
    for(long long i=0;i<=end;i++)
    {
        if(i==1) maxn+=dfs(pos-1,sum+1,done&&i==dg[pos],i);
        else maxn+=dfs(pos-1,sum,done&&i==dg[pos],i); 
    }
    if(done==0) dp[pos][sum]=maxn;
    return maxn;
}
long long solve(long long x)
{
    ans=0;memset(dg,0,sizeof(dg));
    while(x!=0)
    {
        dg[++ans]=x%b;
        x/=b;
    }
//    for(long long i=ans;i>=1;i--) cout<<dg[i]<<" ";
//    cout<<endl;
    return dfs(ans,0,1,2<<30-1);
 } 
int main()
{
    memset(dp,-1,sizeof(dp));
     x=read(),y=read(),k=read(),b=read();
     cout<<solve(y)-solve(x-1);
}
View Code

相关文章:

  • 2021-11-27
  • 2022-12-23
  • 2021-05-23
  • 2022-12-23
  • 2021-07-03
  • 2021-11-21
猜你喜欢
  • 2022-12-23
  • 2021-12-06
  • 2022-12-23
  • 2021-07-21
  • 2022-12-23
  • 2021-06-08
  • 2022-02-24
相关资源
相似解决方案