zoukankan      html  css  js  c++  java
  • hdu4507 吉哥系列故事——恨7不成妻[数位DP]

    这题面什么垃圾玩意儿


    首先看到问题格式想到数位DP,但是求的是平方和。尝试用数位DP推出。

    先尝试拼出和。设$f[len][sum][mod]$表示填到$len$位,已填位置数位和$sum$,数字取余为$mod$时候的方案数,$g[len][sum][mod]$表示在这种情况下的所有满足要求的数的和(指的是后面剩余空位部分的数的和,前面填好的是不算的)。

    那么枚举所填的数$i$,对于每一个满足要求的$x$,填上一个$i$之后变为

    $10^{len-1}i+x$

    (下$f[len-1][(sum+i)mod 7][(10mod+i)mod 7]$简记$f'$,$g,h$同理)

    于是对于每一个$i$都有一次累加作用,这些$x$的和推过来应当是

    $g[len][sum][mod]=sumlimits_{i} (10^{len-1}if'+g')$

    于是就完成了$g$的递推。$h$表示后面空位的数的平方和,也类似推法。

    $h[len][sum][mod]=sumlimits_{i} (10^{len-1})^2 i^2 f' + sumlimits_{i} 2 imes 10^{len-1} i f' + g'$

    然后再每一次$i$的dfs完成之后进行递推。

    注意这里的实现有一个小技巧,把$f,g,h$全部放结构体里,这样dp完一次之后直接取get他的整个包$f,g,h$,就不用考虑什么卡上界或者费事记录额外的东西了。

    WA1:longlong输入又忘了。。

    WA2:取模好好写。。不要老想着减少取模,不然会漏考虑的,万一真的要避免取模应当严格讨论加减乘除数的范围。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define dbg(x) cerr << #x << " = " << x <<endl
     7 using namespace std;
     8 typedef long long ll;
     9 typedef double db;
    10 typedef pair<int,int> pii;
    11 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    12 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    16 template<typename T>inline T read(T&x){
    17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    19 }
    20 const int P=1e9+7;
    21 int bin[20],bin2[20];
    22 struct thxorz{
    23     int f,g,h;
    24     thxorz(int f=-1,int g=0,int h=0):f(f),g(g),h(h){}
    25 }f[20][7][7];
    26 int b[20];
    27 int T;
    28 ll L,R;//mistake
    29 thxorz dp(int len,int sum,int mod,int limit){
    30     if(!len)return thxorz(sum&&mod,0,0);
    31     if(!limit&&~f[len][sum][mod].f)return f[len][sum][mod];
    32     int num=limit?b[len]:9;
    33     thxorz ret,tmp;ret.f=0;
    34     for(register int i=0;i<=num;++i)if(i^7){
    35         tmp=dp(len-1,(sum+i)%7,(mod*10+i)%7,limit&&i==num);//mistake2
    36         ret.f+=tmp.f;ret.f>=P&&(ret.f-=P);
    37         ret.g=(tmp.g+bin[len-1]*1ll*tmp.f%P*i+ret.g)%P;
    38         ret.h=(bin2[len-1]*1ll*tmp.f%P*i*i+tmp.h+2*bin[len-1]*1ll*tmp.g%P*i+ret.h)%P;
    39     }
    40     return limit?ret:f[len][sum][mod]=ret;
    41 }
    42 inline int solve(ll x){
    43     int len=0;while(x)b[++len]=x%10,x/=10;
    44     return dp(len,0,0,1).h;
    45 }
    46 
    47 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    48     for(register int i=0,res=1;i<=18;++i,res=res*1ll*10%P)bin[i]=res,bin2[i]=res*1ll*res%P;
    49     read(T);while(T--)read(L),read(R),printf("%d
    ",(solve(R)-solve(L-1)+P)%P);
    50     return 0;
    51 }
    View Code
  • 相关阅读:
    集合类... 分类: java 20091102 14:22 193人阅读 评论(0) 收藏
    全选复选框 分类: 网页编程【html、js】 20091102 20:56 257人阅读 评论(0) 收藏
    数组自带的push方法 分类: 网页编程【html、js】 20091102 20:51 235人阅读 评论(0) 收藏
    Scanner类 分类: java 20091102 14:18 188人阅读 评论(0) 收藏
    计算阶乘之和 分类: java 20091102 14:12 206人阅读 评论(0) 收藏
    冒泡排序... 分类: java 20091102 14:09 224人阅读 评论(0) 收藏
    获得html 属性值的集中方法 分类: 网页编程【html、js】 20090908 12:32 861人阅读 评论(1) 收藏
    OpenAPI系列:汇总
    OpenAPI系列: 二、资源
    软件生存周期文档系列 之 9.开发进度月报
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11531621.html
Copyright © 2011-2022 走看看