• P4317 花神的数论题


    P4317 花神的数论题

    题解

    关于二进制的数位DP

    dfs 套路

    问题在于哪里,在于 存二进制的时候数组只开了20,现实是输入的数据可能会达到比二十长,此时就拿了个错误 的数据在计算 不WA才怪   数组开大一点没关系啊只要不RE就好了

    问题是求1~n中每个数二进制表示中1的乘积

    其实问题也就转化成:枚举1的个数k,然后统计有多少个数字含有k个1

           k=log2

    ans=   ∏      k sum(k)

             k=1

    我们可以先把 n 二进制拆分,然后枚举  1  的个数,比如二进制表示中有 1 个 1 的数字有几个,2个的有几个,....,然后快速幂乘起来,二进制表示中有1个1的就不用算了,乘了还是原数

    代码

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    
    using namespace std;
    
    typedef long long ll;
    
    inline ll read()
    {
        ll ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const ll mod=1e7+7;
    ll n;
    ll x[80],len=0;
    ll dp[80][80][80][20];
    
    void cl(ll n)
    {
        while(n)
        {
            x[++len]=n%2;
            n/=2;
        }
    /*    printf("%lld
    ",len);
        for(ll i=len;i>0;i--)
          printf("%lld ",x[i]);
        printf("
    ");*/
    }
    
    ll dfs(ll pos,ll already,ll need,bool limit)
    //当前填到了第几位,已经有几个1了,需要几个1,是否顶上界 {
    if(pos<=0) return already==need; if(!limit&&dp[pos][already][need][limit]!=-1) return dp[pos][already][need][limit]; ll ans= 0; ll up=limit?x[pos]:1; for(ll i=0;i<=up;i++) ans+=dfs(pos-1,already+(i==1),need,limit&&(i==up)); if(!limit) dp[pos][already][need][limit]=ans; return ans; } ll ksm(ll a,ll b) { ll res=1; while(b) { if(b%2==1) res=res*a%mod; a=a*a%mod; b/=2; } return res; } int main() { n=read(); cl(n); memset(dp,-1,sizeof(dp)); ll ans=1; for(ll i=len;i>=2;i--) ans=ans*ksm(i,dfs(len,0,i,1))%mod; printf("%lld ",ans); return 0; }

    附上听课笔记:

    ◦ 这题的关键就是发现一的个数的情况比较少可以枚举再转化为另一种情
    况计算其实,这题本质就是转化一下,注意在模型难以建立的情况下,
    通过转化,可以将题目简化 

  • 相关阅读:
    Linux下分析某个进程CPU占用率高的原因
    Linux下查看某一进程所占用内存的方法
    jbd2导致系统IO使用率高问题
    Linux iotop命令详解
    1.Redis详解(一)------ redis的简介与安装
    Redis详解(十三)------ Redis布隆过滤器
    12.Redis详解(十二)------ 缓存穿透、缓存击穿、缓存雪崩
    面试问题总结
    算法与数据结构基础<二>----排序基础之插入排序法
    CarSim、Adams、Cruise和Simulink四款仿真软件的对比
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11454310.html
Copyright © 2020-2023  润新知