zoukankan      html  css  js  c++  java
  • P4317 花神的数论题(数位dp)

    这题只需要记录到当前位,之前总共有多少个1即可

    因为首先这满足记忆化的条件,也就是可以在计算过的情况下直接范围答案

    其次,我们现在需要理解的是,当我们计算出了这个之后,答案是可以直接累乘的

    因为在某个数之后计算的所有数,最大值不超过他,也就是他这位所管辖的所有答案。

    所以我们可以想到,这样其实就是把所有情况都乘起来了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    const int mod=1e7+7;
    ll n;
    vector<int> num;
    ll f[200][210][2];
    ll dfs(int u,int sum,int sign){
        if(u==(int)num.size()){
            return max(sum,1);
        }
        auto &x=f[u][sum][sign];
        if(x!=-1)
            return x;
        int v=1;
        if(sign)
            v=num[u];
        ll ans=1;
        for(int i=0;i<=v;i++){
            ans=ans*dfs(u+1,i==1?sum+1:sum,sign&&(i==v))%mod;
        }
        return x=ans;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin>>n;
        while(n){
            num.push_back(n&1);
            n>>=1;
        }
        reverse(num.begin(),num.end());
        memset(f,-1,sizeof f);
        cout<<dfs(0,0,1)<<endl;
        return 0;
    }
    View Code
    没有人不辛苦,只有人不喊疼
  • 相关阅读:
    开挂的列表与矜持的元组
    烦人的字符串
    好用的for循环与range
    浅谈编码
    流程控制与循环
    基础运算符
    python初识
    python的小介绍
    来自极客标签10款最新设计素材-系列九
    chmod----改变一个或多个文件的存取模式(mode)
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13538493.html
Copyright © 2011-2022 走看看