码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 4507 吉哥系列故事——恨7不成妻 数位DP

时间:2014-08-03 15:12:55      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:blog   os   io   for   div   amp   size   log   

这个不是求的数量,而是求平方和,所以记忆化的时候不能像以前那样无脑的来。

先来看简单的情况,如果是求和,应该怎么搞。

假如我现在搜索到第3位,一共有5位,情况应该是这样的XXiXX,注意后面的X和前面的X都是不确定的,转移的时候应该是i * 10^(5-3) * (能满足的条件的数的数量) + sigma((每个分支下面满足条件的数量)* (分支和))这样的形式,然后再返回到上一层。这样子就可以记忆化了。但是除了要统计数量,还要统计和。

那么这里要统计平方和的话,如果还是上面这种情况,根据(a + b)^2 = a^2 + 2*a*b + b^2可以得出(i * 10^(5 - 3))^2 * (能满足的条件的数的数量) + 2 * sigma((每个分支下面满足条件的数量)*(分支和)) + sigma(分支平方和)。所以出了要维护分支和,还要维护分支平方和和数量。

真鬼畜

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <climits>
#include <string>
#include <iostream>
#include <map>
#include <cstdlib>
#include <list>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
const int maxn = 20;
const LL MOD = 1e9 + 7;
int lim[maxn],len = 0;
LL p10[maxn] = {1};

struct EE {
    LL sqsum,sum,cnt;
    bool vis;
    EE(LL sqsum = 0,LL sum = 0,LL cnt = 0):sqsum(sqsum),sum(sum),cnt(cnt),vis(0) {}
};

EE f[maxn][10][10];

void getlim(LL num) {
    len = 0;
    memset(lim,0,sizeof(lim));
    while(num) {
        lim[len++] = num % 10;
        num /= 10;
    }
}

EE dfs(int now,int bitsum,int rest,int bound,LL num) {
    if(now == 0) {
        if(bitsum % 7 == 0 || rest % 7 == 0) return EE(0,0,0);
        return EE(0,0,1);
    }
    EE &note = f[now][bitsum][rest];
    if(note.vis && !bound) return note;
    int m = bound ? lim[now - 1] : 9;
    EE ret(0,0,0);
    for(int i = 0;i <= m;i++) {
        if(i == 7) continue;
        int nbitsum = (bitsum + i) % 7;
        int nrest = (rest * 10 + i) % 7;
        int nbound = (i == m && bound);
        EE nret = dfs(now - 1,nbitsum,nrest,nbound,num * 10 + i);
        LL ff = p10[now - 1] * i % MOD;
        ret.cnt = (nret.cnt + ret.cnt) % MOD;
        ret.sum = ((nret.cnt * ff % MOD + nret.sum) % MOD + ret.sum) % MOD;
        ret.sqsum = ((nret.cnt * ff % MOD * ff % MOD + nret.sqsum) % MOD + 2 * ff % MOD * nret.sum % MOD + ret.sqsum) % MOD ;
    }
    if(!bound) note = ret,note.vis = true;
    return ret;
}


LL work(LL num) {
    for(int i = 0;i < maxn;i++) {
        for(int j = 0;j < 10;j++) {
            for(int k = 0;k < 10;k++) {
                f[i][j][k] = EE();
            }
        }
    }
    getlim(num);
    EE ret = dfs(len,0,0,1,0);
    return ret.sqsum;
}


int main() {
    for(int i = 1;i < maxn;i++) p10[i] = p10[i - 1] * 10;
    int T; cin >> T;
    LL n,m;
    while(T--) {
        cin >> n >> m;
        cout << (work(m) - work(n - 1) + MOD) % MOD << endl;
    }
    return 0;
}

  

HDU 4507 吉哥系列故事——恨7不成妻 数位DP,布布扣,bubuko.com

HDU 4507 吉哥系列故事——恨7不成妻 数位DP

标签:blog   os   io   for   div   amp   size   log   

原文地址:http://www.cnblogs.com/rolight/p/3888361.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!