hihocoder 1033 交错和 数位DP
2015-07-22 10:39
323 查看
dp[site][sum][p]代表有site位数字,交错和为sum,并且site位置的符号是+(p==1)或者-(p==0)。因为最后的和我们已经得知是k,所以将sum初始值设置为k+100(因为有负数)。对于某一位如果是要加,我们用sum减,这样进行到最后一位,如果是sum==100那么可以肯定前面的交错和就是k..因为对于不同位数的数字,对于本位数字有加减两种情况所以开了p这一维防止搞混。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<cctype> #include<cstdlib> using namespace std; #define N 1000000007 #define LL long long struct node { LL cnt; LL sum; }dp[20][202][2]; int num[20]; LL c[20],k; node dfs(int site,int sum,int f,int p,int flag) { if(site==0) { node a; if(flag) a.cnt=0; else a.cnt=sum==100?1:0; a.sum=0; return a; } if(!f&&!flag&&dp[site][sum][p].cnt!=-1) return dp[site][sum][p]; node ans,a; ans.cnt=ans.sum=0; int len=f?num[site]:9; for(int i=0;i<=len;i++) { if(flag&&i==0) { a=dfs(site-1,sum,f&&i==len,p,flag); } else { if(p) a=dfs(site-1,sum-i,f&&i==len,p^1,0); else a=dfs(site-1,sum+i,f&&i==len,p^1,0); } ans.cnt=(ans.cnt+a.cnt)%N; ans.sum=(ans.sum+((c[site]*a.cnt)%N)*i+a.sum)%N; } if(!f&&!flag) { dp[site][sum][p].cnt=ans.cnt; dp[site][sum][p].sum=ans.sum; } return ans; } LL solve(LL n) { int i=0; while(n) { num[++i]=n%10; n=n/10; } node ans; ans=dfs(i,k+100,1,1,1); return ans.sum; } int main() { LL l,r; memset(dp,-1,sizeof(dp)); c[1]=1; for(int i=2;i<=18;i++) c[i]=(c[i-1]*10)%N; while(scanf("%lld %lld %d",&l,&r,&k)!=EOF) { printf("%lld\n",((solve(r)-solve(l-1))%N+N)%N); } return 0; }
相关文章推荐
- 数据结构与算法分析第二章读书笔记
- 部分Android手机拍照后照片被旋转的解决方案
- 浅析Oracle语句优化规则
- 一篇很全面的freemarker教程
- 一篇很全面的freemarker教程
- 一篇很全面的freemarker教程
- 一篇很全面的freemarker教程
- java最简单实现LRUCache
- 使用Fiddler调试手机页面请求
- [Windows驱动开发](二)基础知识——数据结构
- 排序算法
- hdu5293 Tree chain problem 树形dp+线段树
- 知道你们不想撸代码写PPT之可视化页面做一款炫酷的WEB PPT
- C#实现汉字转拼音或转拼音首字母的方法
- [LeetCode]Balanced Binary Tree
- PAT (Advanced Level) 1020. Tree Traversals (25) 给定后序中序,递归建树
- jsp版本端口转发
- Search for a Range
- Hduoj2830 【矩阵数学】
- hdoj 3367 Pseudoforest 【伪森林】 【并查集判断环 + 最大生成树】