Hdu 4507 吉哥系列故事——恨7不成妻
来源:互联网 发布:java字符串替换某一位 编辑:程序博客网 时间:2024/05/17 13:09
求
1 整数中某一位是7
2 整数的每一位加起来的和是7的整数倍
3 这个整数是7的整数倍;
一眼看去又是一个数位dp,但是怎么统计平方和呢?
假设我们在统计最高位为x的n个数的平方和
有
其中和x相关的贡献是前两项。也就是说,我们统计能接在当前前缀后面的后缀的个数和后缀的和,就可以计算出x对整个平方和的贡献。
怎么统计后缀和呢?
也需要统计后缀的个数。
那么照着这个统计下去就好了。
因为一开始写的时候没有想太多就强行写了三遍dfs。。。
有空重写一遍
#include<bits/stdc++.h>using namespace std;#define LL long long const int maxn = 20,mod = 1e9 + 7;int num[maxn];LL ten[maxn * 2];LL cnted[maxn][2][7][7];LL count(int pos,bool bnd,int left,int sumer){ if(pos < 0) return left != 0 && sumer != 0; LL & ncnt = cnted[pos][bnd][left][sumer]; if(~ncnt) return ncnt; ncnt = 0; int bound = bnd ? num[pos] : 9; for(int i=0;i<=bound;i++){ if(i == 7) continue; (ncnt += count(pos-1 ,bnd && bound == i ,(left * 10 + i ) % 7 ,(sumer + i ) % 7 ) ) %= mod; } return ncnt;}LL sumed[maxn][2][7][7];LL sum(int pos,bool bnd,int left,int sumer){ if(pos < 0) return 0; LL & nsum = sumed[pos][bnd][left][sumer]; if(~nsum) return nsum; nsum = 0; int bound = bnd ? num[pos] : 9; for(int i=0;i<=bound;i++){ if(i == 7) continue; (nsum += sum (pos-1 ,bnd && bound == i ,(left * 10 + i ) % 7 ,(sumer + i ) % 7 ) ) %= mod; (nsum += (count(pos-1 ,bnd && bound == i ,(left * 10 + i ) % 7 ,(sumer + i ) % 7 ) * i * ten[pos]) % mod ) %= mod; } return nsum;}LL dp[maxn][2][7][7];LL dfs(int pos,bool bnd,int left,int sumer){ if(pos < 0) return 0; LL & ndp = dp[pos][bnd][left][sumer]; if(~ndp) return ndp; ndp = 0; int bound = bnd ? num[pos] : 9; for(int i=0;i<=bound;i++){ if(i == 7) continue; (ndp += dfs(pos-1 ,bnd && bound == i ,(left * 10 + i ) % 7 ,(sumer+ i ) % 7 ) ) %= mod; (ndp += ((count(pos-1 ,bnd && bound == i ,(left * 10 + i ) % 7 ,(sumer+ i ) % 7 ) * i * i ) % mod * ten[pos * 2]) % mod ) %= mod; (ndp += ((sum(pos-1 ,bnd && bound == i ,(left * 10 + i ) % 7 ,(sumer+ i ) % 7 ) * i * 2 ) % mod * ten[pos]) % mod ) %= mod; } return ndp;}LL cal(LL x){ int len = 0; while(x){ num[len++] = x % 10; x /= 10; } memset(cnted,-1,sizeof(cnted)); memset(sumed,-1,sizeof(sumed)); memset(dp,-1,sizeof(dp)); return dfs(len-1,true,0,0);}int main(){ ten[0] = 1; for(int i=1;i<maxn * 2;i++) ten[i] = (ten[i-1] * 10 ) % mod; int T; scanf("%d",&T); LL l,r; while(T-- && ~scanf("%I64d %I64d",&l,&r)){ printf("%I64d\n",(cal(r) - cal(l-1) + mod) % mod); } return 0;}
重写之后果然短了不少
#include<bits/stdc++.h>using namespace std;#define LL long long const int maxn = 20,mod = 1e9 + 7;LL dp[maxn][2][7][7];LL sum[maxn][2][7][7];LL cnt[maxn][2][7][7];bool vis[maxn][2][7][7];int num[maxn];LL ten[maxn * 2];LL cnter(int pos,bool bnd,int lef,int mor,int nex){ lef = (lef * 10 + nex) % 7; mor = (mor + nex) % 7; if(pos == 0) return mor != 0 && lef != 0; return cnt[pos-1][bnd && nex == num[pos]][lef][mor];}LL sumer(int pos,bool bnd,int lef,int mor,int nex){ if(pos == 0) return 0; lef = (lef * 10 + nex) % 7; mor = (mor + nex) % 7; return sum[pos-1][bnd && nex == num[pos]][lef][mor];}#define nexter pos,bnd,lef,mor,iLL dfs(int pos,bool bnd,int lef,int mor){ if(pos < 0) return 0; if(vis[pos][bnd][lef][mor]) return dp[pos][bnd][lef][mor]; LL & ndp = dp [pos][bnd][lef][mor]; LL & ncnt = cnt[pos][bnd][lef][mor]; LL & nsum = sum[pos][bnd][lef][mor]; ndp = ncnt = nsum = 0; int bound = bnd ? num[pos] : 9; for(int i=0;i<=bound;i++){ if(i == 7) continue; (ndp += dfs(pos-1,bnd && i == bound,(lef*10+i)%7,(mor+i)%7)) %= mod; (ncnt += cnter(nexter) ) %= mod; (nsum += sumer(nexter) ) %= mod; (nsum += ((cnter(nexter) * i ) % mod * ten[pos] ) % mod ) %= mod; (ndp += ((cnter(nexter) * i * i ) % mod * ten[pos * 2]) % mod ) %= mod; (ndp += ((sumer(nexter) * i * 2 ) % mod * ten[pos] ) % mod ) %= mod; } vis[pos][bnd][lef][mor] = true; return ndp;}LL cal(LL n){ int len = 0; while(n){ num[len++] = n % 10; n /= 10; } memset(vis,0,sizeof(vis)); return dfs(len-1,true,0,0);}int main(){ ten[0] = 1; for(int i=1;i<maxn * 2;i++) ten[i] = (ten[i-1] * 10) % mod; int T; scanf("%d",&T); LL l,r; while(T-- && ~scanf("%I64d %I64d",&l,&r)){ printf("%I64d\n",(cal(r) - cal(l-1) + mod ) % mod); } return 0;}
0 0
- [数位DP]HDU 4507——吉哥系列故事——恨7不成妻
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- hdu 4507 吉哥系列故事——恨7不成妻
- hdu 4507 吉哥系列故事——恨7不成妻 数位DP
- hdu 4507 吉哥系列故事——恨7不成妻(数位DP,5级)
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- 【数位DP】HDU 4507 吉哥系列故事——恨7不成妻
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- 数位dp HDU 4507 吉哥系列故事——恨7不成妻
- hdu 4507 吉哥系列故事——恨7不成妻 (数位dp)
- hdu 4507 吉哥系列故事——恨7不成妻
- [数位dp] hdu 4507 吉哥系列故事——恨7不成妻
- 【HDU】4507 吉哥系列故事——恨7不成妻 数位DP
- 【数位DP】【HDU 4507】吉哥系列故事——恨7不成妻
- HDU ACM 4507 吉哥系列故事——恨7不成妻 ->数位DP
- hdu 4507 - 吉哥系列故事——恨7不成妻(数位dp)
- HDU 4507 吉哥系列故事——恨7不成妻(数位DP)
- [HDU 4507] 吉哥系列故事——恨7不成妻 数位dp
- bwlabel(BW,n) matlab中标记二值图像中白色(1)的连通区域
- What does "Vanilla" mean ?
- JSP 中的2种包含(导入)
- (LeetCode)Excel Sheet Column Title --- Excel页码映射
- Error:exception during working with external system:
- Hdu 4507 吉哥系列故事——恨7不成妻
- java数据结构和算法(ListToArrayUtil)
- 第7周项目4-队列数组
- windows下缩短time_wait的时间
- Android本地及网络音乐播放器-网络音乐的试听和下载(四)
- 第七周-栈和队列(二)项目一-建立顺序环形队列算法库
- 【Java基础】单利设计模式
- 第七周项目4-队列数组
- linux入门经验之谈