• 吉哥系列故事――恨7不成妻 HDU


    思路  和普通的DP不一样的是 这里求的是满足条件的数的平方的和 而数位DP只跟数每位是什么密切相关  所以要开一个结构 (多加一个 数的和sum 和平方和qsum)存一下各个状态的和的情况  

    dp[pos][state1][state2].num  满足该状态的数有几个

    dp[pos][state1][state2].sum 满足该条件的数的和是多少

    dp[pos][state1][state2].qsum 满足该条件的数的平方的和是多少

    详见注解 主要是状态转移是 和 和 平方和 的转移公式

    ∑(Y + xi)^2 = ∑(Y^2 + 2 * Y * xi + xi^2) = n * Y^2 + 2 * Y * ∑xi + ∑ xi^2  利用该公式 可以实现 状态转移

    tips:先写好公式再疯狂% 不然容易乱

    参考:https://blog.csdn.net/qq_37025443/article/details/78472991

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include<vector>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const long long  MOD=(1e9)+7;
    typedef long long ll;
    ll sum;
    int cnt;
    ll a[100];
    int t[300];
    struct Node{
     ll num,sum,qsum;
     Node(ll a=0,ll b=0,ll c=0):num(a),sum(b),qsum(c){
    
     }
    }dp[20][200][10];
    
    ll c[25];
    void init(){
     c[0]=1;
     for(int i=1;i<=20;i++)c[i]=(c[i-1]*10)%MOD;
    }
    
    Node dfs(int pos,int state1,int state2,bool limit ){         
        if(pos==-1){    
       return Node(state1&&state2,0,0);
        }
        if(!limit&&dp[pos][state1][state2].qsum!=0)return dp[pos][state1][state2];
        int up=limit?a[pos]:9;
        Node ans;
        for(int i=0;i<=up;i++){
        //    cout<<i<<endl;
            if(i==7)continue;
            Node tmp=dfs(pos-1,(state1+i)%7,(state2*10+i)%7,limit&&i==up);
        //    cout<<111<<endl;
            ans.num=(ans.num+tmp.num)%MOD;//满足的数求和
            ans.sum=(ans.sum+(((i*c[pos])%MOD*tmp.num)%MOD+tmp.sum)%MOD)%MOD;//tmp.num*i*c[pos] 表示当前位pos的数的大小 乘以 一共有多少个满足条件数  tmp.sum表示pos-1的数的和 
            ans.qsum+=((tmp.qsum+(2*i*c[pos])%MOD*tmp.sum)%MOD)%MOD;//  平方和公式实现状态转移 tmp.qsum 就是a^2 2*i*c[pos]*tmp.sum 就表示 2*a*b
            ans.qsum%=MOD;
            ans.qsum+=(((i*c[pos]*i)%MOD*c[pos])%MOD*tmp.num)%MOD;//  i*i*c[pos]*c[pos] b^2 由上面的注解可以知道还需要求和 (n就是tmp.num)   
            ans.qsum%=MOD;
            
        }
        if(!limit) dp[pos][state1][state2]=ans;
        return ans;
    }
    
    
    ll solve(ll x){
      int pos=0;
      while(x){                                    
          a[pos++]=x%10;
          x/=10;
      }
     return  dfs(pos-1,0,0,1).qsum; 
    }
    
    int main()
    {
    ll a,b;
    int t;
    cin>>t;
    int kase=1;
    init();
        while(t--){
            cin>>a>>b;
            printf("%I64d
    ",(solve(b)-solve(a-1)+MOD)%MOD);
        }
    
        return 0;
    }
  • 相关阅读:
    java的访问控制修饰符
    js将一个数组分割成二维子数组
    java的数组
    Java 变量类型
    java
    java的 %和 ^
    Python第三方库 -> 由于是ipynb格式,所以没有对应的输出结果
    获取浏览器历史记录 browserhistory
    虚拟机 CentOS 6.8 安装
    解决 django.db.utils.OperationalError: (1051, "Unknown table 'mydorm.users_studen t'")
  • 原文地址:https://www.cnblogs.com/ttttttttrx/p/9756867.html
Copyright © 2020-2023  润新知