hihocoder1033交错和
题目链接
坑:
1.ll x,y;
z=x*y;可能会溢出,于是我写成x%mod*y%mod
仍旧错误,要写成x%mod*(y%mod).
2.f(9019)=1.
要注意如果为0,下一位的符号根据0的个数而变化
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<queue> 5 #include<math.h> 6 #include<string.h> 7 #include<string> 8 #include<stdlib.h> 9 using namespace std; 10 typedef long long ll; 11 typedef unsigned long long ull; 12 #define re(i,n) for(int i=0;i<n;i++) 13 const int mod = 1e9 + 7; 14 /* 15 Node cnt表示个数,sum表示和 16 */ 17 struct Node{ 18 ll cnt, sum; 19 Node() :cnt(0), sum(0){} 20 Node(ll c, ll s) :cnt(c), sum(s){} 21 }dp[19][2][2][600];//(bits,+-,+-can change,sum) 22 /* 23 19 最多19位 24 2 +还是- 25 2 是否是第一个数字 26 600 f(n)的结果,因为19位*9=171,输入的k是-100到100,所以范围大概是-300到+300,所以用600 27 */ 28 ll ten[19]; 29 //ten[i]表示10^i 30 void init(){ 31 ten[0] = 1; 32 for (int i = 1; i < 19; i++){ 33 ten[i] = 10 * ten[i - 1]; 34 } 35 } 36 /*d是一个大管家,管理者dp这个数组,如果计算过,那就不再计算了 37 对参数做一些处理,像适配器一样 38 n表示[0,10^n-1]范围内,第一个符号为flag,符号是否会改变change,f(n)=k 39 */ 40 Node d(int n, int flag, int change, int k){ 41 int ff = (flag == 1 ? 1 : 0); 42 int kk = k + 300; 43 Node f(ll,int, int, int); 44 if (dp[n][ff][change][kk].cnt == -1){ 45 dp[n][ff][change][kk] = f(ten[n] - 1, flag, change, k); 46 } 47 return dp[n][ff][change][kk]; 48 } 49 /* 50 主要逻辑都在这个函数里面,n表示[0,n]范围内的值 51 */ 52 Node f(ll n, int flag, int change, int k){ 53 if (n < 0)return Node(0, 0); 54 if (n < 10){ 55 if (flag*k >= 0 && flag*k <= n)return Node(1, flag*k); 56 else return Node(0, 0); 57 } 58 ll mi = 0, h = 0; 59 for (ll tmp = n; tmp; tmp /= 10)h = tmp % 10, mi++; 60 mi--; 61 ll va = h*ten[mi];//处理清楚最高位 62 Node t = d(mi, change ? 1 : -flag, change, k); //第一位为0时,有多少种情况 63 Node ans = t; 64 for (int i = 1; i < h; i++){ 65 t = d(mi, -flag, 0, k - flag*i); 66 ans.cnt += t.cnt; 67 ans.sum = (ans.sum + ten[mi]%mod*i*( t.cnt%mod) + t.sum) % mod; 68 } 69 //第一位为h时的情况 70 int ff = ((mi&1)?flag:-flag); 71 for (ll tmp=n-va; tmp; tmp/=10){ 72 ff *= -1; 73 } 74 t = f(n - va, ff, 0, k - flag*h); 75 ans.cnt += t.cnt; 76 ans.sum = (ans.sum + va%mod*(t.cnt%mod) + t.sum) % mod; 77 return ans; 78 } 79 int main(){ 80 //freopen("in.txt", "r", stdin); 81 init(); 82 memset(dp, -1, sizeof(dp)); 83 ll l, r, k; 84 cin >> l >> r >> k; 85 Node m = f(l - 1, 1,1, k), n = f( r, 1,1, k); 86 ll ans = (n.sum - m.sum) % mod; 87 if (ans < 0)ans += mod; 88 cout << ans << endl; 89 return 0; 90 }
别人的代码还精简,算法更好.
1 struct node 2 { 3 ll cnt,sum; //分别表示该状态的出现的次数,以及数字和 4 node(ll _cnt,ll _sum):cnt(_cnt),sum(_sum){} 5 node(){} 6 }dp[20][20][300]; //dp[i][j][k],表示当前在的i位,第一位有效位为j,交错和为k-100的状态 7 ll num[20]; 8 ll ten[20]; 9 ll l,r; 10 int k; 11 node dfs(int cur,int first,int sum,bool limit) 12 { 13 if(cur <= 0) 14 return node(sum==k,0); 15 if(!limit && dp[cur][first][sum+100].cnt != -1) return dp[cur][first][sum+100]; 16 int up = limit ? num[cur] : 9; 17 node ret(0,0),tv; 18 rep(i,up+1) 19 { 20 int g; 21 if(!first){ g = (i == 0 ? 0 : cur); } 22 else g = first; 23 if(g) 24 tv = dfs(cur-1,g,sum+((g-cur)%2==0?1:-1)*i,limit && i == up); 25 else 26 tv = dfs(cur-1,0,0,limit && i==up); 27 ll t = i*ten[cur-1]%mod; 28 ret.cnt = (ret.cnt + tv.cnt) % mod; //次数相加 29 ret.sum = (ret.sum + tv.sum + t*tv.cnt)%mod; //和相加 30 } 31 if(!limit) dp[cur][first][sum+100] = ret; 32 return ret; 33 } 34 ll solve(ll n) 35 { 36 if(n <= 0) return 0; 37 int len = 0; 38 while(n){ 39 num[++len] = n % 10; 40 n /= 10; 41 } 42 return dfs(len,0,0,1).sum; 43 } 44 void init() 45 { 46 memset(dp,-1,sizeof(dp)); 47 ten[0] = 1; 48 for(int i=1;i<20;i++) ten[i] = (ten[i-1] * 10) % mod; 49 } 50 int main() 51 { 52 #ifndef ONLINE_JUDGE 53 freopen("in.txt","r",stdin); 54 // freopen("out.txt","w",stdout); 55 #endif 56 init(); 57 while(~scanf("%lld%lld%d",&l,&r,&k)) 58 { 59 cout<<(solve(r)-solve(l-1)+mod)%mod<<'\n'; 60 } 61 return 0; 62 }
转载于:https://www.cnblogs.com/weiyinfu/p/4902595.html
hihocoder1033交错和相关推荐
- 【组合数学】组合恒等式 ( 递推 组合恒等式 | 变下项求和 组合恒等式 简单和 | 变下项求和 组合恒等式 交错和 )
文章目录 一.组合恒等式 ( 递推式 ) 二.组合恒等式 ( 变下项求和 ) 简单和 二.组合恒等式 ( 变下项求和 ) 交错和 一.组合恒等式 ( 递推式 ) 组合恒等式 ( 递推式 ) : 1 . ...
- hihoCoder #1033 : 交错和 [ 数位dp ]
传送门 #1033 : 交错和 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个数 x,设它十进制展从高位到低位上的数位依次是 a0, a1, ..., an - ...
- 交错和 (hihocoder)
求L到R之间满足交错和为K的所有数之和模1000000007 dp[i][j]中的n,s分别代表十进制的第i位(个位为第1位)交错和为j的数的数量 与 和 #include<iostream&g ...
- Photoshop 保存PNG格式交错和不交错有差别
1.PNG格式是由Netscape公司开发出来的格式,可以用于网络图像,但它不同于GIF格式图像只能保存256色,PNG格式可以保存24位的真彩色图像,并且支持透明背景和消除锯齿边缘的功能,可以在不失 ...
- 【刷题篇】领扣3167.求交错和(python)
- http2.0的时代来了
KS Knowledge Sharing 知识分享 现在是资源共享的时代,同样也是知识分享的时代,如果你觉得本文能学到知识,请把知识与别人分享! 开篇HTTP发展的心路历程 上图:连接无法复用 上图: ...
- r语言用行名称提取数据框信息显示na_用R语言提取数据框中日期对应年份(列表转矩阵)...
[Fine原创]JMeter分布式测试中踩过的那些坑 最近因为项目需要,研究了性能测试的相关内容,并且最终选用了jmeter这一轻量级开源工具.因为一直使用jmeter的GUI模式进行脚本设计,到测试 ...
- 自动驾驶外卖上线,美团即将配送一切
2020-10-19 12:38:55 北京,首钢冬奥园区. 一家名叫「MAI Shop」的零售商店,最近刚刚在这里开业,然后马上成为新晋网红打卡地,吸引了大量游人和媒体的目光. 原因不在别的,而是因 ...
- NR 5G L1物理层
波形,数学原理和框架结构 下行链路传输波形是使用循环前缀的传统OFDM. 上行链路传输波形是使用循环前缀的常规OFDM,其中变换预编码功能执行可以被禁用或启用的DFT扩展. 具有可选 DFT 扩展的 ...
最新文章
- 使用Shell(bash) 来检查 git 本地某个分支是否存在
- 深入解析Java编译器学习笔记
- DNS support edns-client-subnet
- 读“ModSecurity配置关键字说明”之摘抄
- 《剑指offer》字符流中第一个不重复的字符
- android记事本项目案例,Android实现记事本项目完整实例源代码
- python查看图像通道数(通过PIL)
- numpy.ndarray.flat/flatten 与 Spark 下的 flatMap
- [spoj694spoj705]New Distinct Substrings(后缀数组)
- 【Coursera公开课】职场素养 笔记
- typora 免费版, 最后一个beta版本下载
- Python文件去重代码
- PYTHON-音视频合并方法
- Java 使用POI 给Word添加水印
- 批处理为win7桌面添加计算机图标,win7桌面图标不见了图文解决方案
- 致美网页练习完整代码
- 车牌识别之字符切割2
- jotform 设计器_使用JotForm 4.0减轻表单构建的痛苦
- 制作拼多多app网页css,5+App下Mui框架开发仿拼多多App
- 使用多个icon 字体图标库样式冲突问题