传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3131
思路:人生第一道数位dp,,,解锁了人生新成就,,,
数位dp的一般思路,分为两步:1.dp预处理 2. 统计答案
然而第二步往往非常恶心,,,
一般来讲,第二步是根据位数从前向后统计第一个当前位数小于给定n的位置,,,这一道题的idea在于一个数的各个位数都是1 - 9
如果按质因数来看只有2 3 5 7,实际网上大部分都是爆搜所有可能性再dp(貌似总状态非常少啊,,),然而我直接数位dp保存了,因为状态的可行性挂了好久
感觉恶心,,,
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#define N 15
#define max2 41
#define max3 27
#define max5 19
#define max7 16
#define maxn 2320500
#include<algorithm>
using namespace std;
typedef long long LL;
struct node { LL loc1,loc2,value;};
node heap[maxn + 5];
double limit;
LL n,k,P,f[N + 5][max2 + 5][max3 + 5][max5 + 5][max7 + 5],ans[max2 + 5][max3 + 5][max5 + 5][max7 + 5],
p[10][4],g[4],len,w[N + 5],cnt,num,q[maxn + 5],real_ans,maxa,maxb,maxc,maxd,r[4][max2 + 5];
bool can[max2 + 5][max3 + 5][max5 + 5][max7 + 5];
inline bool cmp(LL a,LL b){ return (a > b); }
void init(){memset(can,0,sizeof(can));scanf("%lld%lld",&n,&k); P = 1000000007LL; limit = log(n);maxa =  max2 ; maxb =  max3;maxc = max5; maxd = max7;memset(f,0,sizeof(f));f[1][0][0][0][0] = 1; f[1][1][0][0][0] = 1; f[1][0][1][0][0] = 1;f[1][2][0][0][0] = 1; f[1][0][0][1][0] = 1; f[1][1][1][0][0] = 1;f[1][0][0][0][1] = 1; f[1][3][0][0][0] = 1; f[1][0][2][0][0] = 1;p[2][0] = 1; p[3][1] = 1; p[4][0] = 2; p[5][2] = 1; p[6][0] = 1; p[6][1] = 1;p[7][3] = 1; p[8][0] = 3; p[9][1] = 2;r[0][0] = r[1][0] = r[2][0] = r[3][0] = 1;for (int i = 1;i <= maxa; ++i) r[0][i] = r[0][i-1] * 2;for (int i = 1;i <= maxb; ++i) r[1][i] = r[1][i-1] * 3;for (int i = 1;i <= maxc; ++i) r[2][i] = r[2][i-1] * 5;for (int i = 1;i <= maxd; ++i) r[3][i] = r[3][i - 1] * 7;
}inline bool check(LL a,LL b,LL c,LL d){ LL sum = 1; LL x[4] = {a,b,c,d};for (int j = 0;j < 4; ++j){sum = sum * r[j][x[j]];if (sum > n) return 0;}return 1;
}void dp(){len = 0;LL m = n;  while (m) {w[++len] = m % 10;m = m / 10; }for (int i = 1;i < len; ++i){for (int a = 0; a <= maxa; ++a)for (int b = 0; b <= maxb; ++b)for (int c = 0;c <= maxc; ++c)for (int d = 0; d <= maxd; ++d)if (!check(a,b,c,d)) break;else{for (int k = 1;k <= 9; ++k)f[i + 1][a + p[k][0]][b + p[k][1]][c + p[k][2]][d + p[k][3]] += f[i][a][b][c][d];}}for (int i = 1;i < len; ++i)for (int a = 0; a <= maxa; ++a)for (int b = 0; b <= maxb; ++b)for (int c = 0;c <= maxc; ++c)for (int d = 0; d <= maxd; ++d)if (!check(a,b,c,d)) break;else ans[a][b][c][d] += f[i][a][b][c][d];for (int i = len;i > 1; --i){LL t = w[i];if (!t) break;for (int j = 1;j < t; ++j)   for (int a = 0; a <= maxa; ++a)for (int b = 0; b <= maxb; ++b)for (int c = 0;c <= maxc; ++c)for (int d = 0; d <= maxd; ++d)if (!check(a,b,c,d)) break;else{LL t1 =  f[i - 1][a][b][c][d];if (check(a + g[0] + p[j][0],b + g[1] + p[j][1],c + g[2] + p[j][2],d + g[3] + p[j][3]))ans[a + g[0] + p[j][0]][b + g[1] + p[j][1]][c + g[2] + p[j][2]][d + g[3] + p[j][3]] += t1;}for (int j = 0;j < 4; ++j) g[j] += p[w[i]][j];}bool flag = 1;for (int i = 1;i <= len; ++i) if (!w[i]) flag = 0; if (flag) for (int j = 1;j <= w[1]; ++j) ans[g[0] + p[j][0]][g[1] + p[j][1]][g[2] + p[j][2]][g[3] + p[j][3]] ++;
}inline void push(LL x,LL y){heap[++cnt] = (node){x,y,q[x] * q[y]};LL j = cnt;while (1){if (j == 1||heap[j].value < heap[j>>1].value) break;swap(heap[j],heap[j>>1]);j >>= 1;}
}inline node pop(){node val = heap[1];heap[1] = heap[cnt--];LL j = 1;if (cnt){while (1){LL maxist = j;if ((j << 1)<= cnt&& heap[j<<1].value > heap[maxist].value) maxist = j<<1;if ((j<<1|1)<=cnt&&heap[j<<1|1].value > heap[maxist].value) maxist = j<<1|1;if (maxist == j) break;swap(heap[j],heap[maxist]);j = maxist; }}return val;
}void get_ans(){ LL maxi = 0;num = 0; cnt = 0; real_ans = 0;for (int a = 0; a <= maxa; ++a)for (int b = 0; b <= maxb; ++b)for (int c = 0;c <= maxc; ++c)for (int d = 0; d <= maxd; ++d)if (!check(a,b,c,d)) break;else if (ans[a][b][c][d]) {q[++num] = ans[a][b][c][d];}sort(q + 1,q + num + 1,cmp);for (int i = 1;i <= num; ++i) push(i,1); for (int i = 1;i <= k; ++i)if (cnt > 0){node t = pop();real_ans = (real_ans + t.value % P) % P;if (t.loc2 < num) push(t.loc1,t.loc2 + 1); }
}void DO_IT(){dp();get_ans();
}int main(){init();DO_IT();cout<<real_ans;return 0;
}

总结:1.注意读入和输出用I64D还是lld
2.注意审题,看清条件 3.保持思维严谨,不能混乱

3131: [Sdoi2013]淘金相关推荐

  1. bzoj 3131 [Sdoi2013]淘金(数位dp)

    题目描述 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块. 一阵风吹过,金子的位置发生了 ...

  2. BZOJ 3131 [Sdoi2013]淘金

    题解: 首先要看出行列独立 令f[i]表示挂到i点的数量 则(i,j)的金币数量为f[i]*f[j] 然后数位DP求出f[i] 转载于:https://www.cnblogs.com/zzyer/p/ ...

  3. bzoj千题计划268:bzoj3131: [Sdoi2013]淘金

    http://www.lydsy.com/JudgeOnline/problem.php?id=3131 如果已知 s[i]=j 表示有j个<=n数的数码乘积=i 那么就会有 s[a1]*s[a ...

  4. [SDOI2013] 淘金

    题目描述 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块. 一阵风吹过,金子的位置发生了 ...

  5. P3303 [SDOI2013]淘金

    题目描述 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块. 一阵风吹过,金子的位置发生了 ...

  6. SDOI2013 淘金

    题目描述 小 Z在玩一个 叫做<淘金者>的游戏.游戏的世界是一个 二维坐标 .X轴.Y轴X轴.Y轴坐标范围均为1..N1..N.初始的时候,所有的整数坐标点上均有一块金子,共 N∗NN*N ...

  7. 【数位dp】bzoj3131: [Sdoi2013]淘金

    思路比较自然,但我要是考场上写估计会写挂:好像被什么不得了的细节苟住了?-- Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1. ...

  8. bzoj 乱刷计划 50/50

    前言 话说第一个板刷计划由于种种原因而告一段落了..其实那一版还有很多题想做,那就只能放一放了 附上效果图一张(几乎每一题都在我博客有题解): 打算 可以复习,重做自己做过的题,不局限于没做过的 乱刷 ...

  9. Noip前的大抱佛脚----赛前任务

    赛前任务 tags:任务清单 前言 现在xzy太弱了,而且他最近越来越弱了,天天被爆踩,天天被爆踩 题单不会在作业部落发布,所以可(yi)能(ding)会不及时更新 省选前的练习莫名其妙地成为了Noi ...

最新文章

  1. HDLBits 系列(38)值得一看的状态机设计题目
  2. Excel有用的函数(ISBLANK,IF,LEFT,VALUE)
  3. android 获取ArrayList的Capacity
  4. BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
  5. 同步方法中的锁对象_互斥锁与读写锁:如何使用锁完成Go程同步?
  6. php金币格式转换,php 资金格式转换函数_PHP教程
  7. u-boot之SPL分析
  8. vector中resize()和reserve()区别
  9. Insurance 项目——Mybetis-generator生成
  10. 基于STM32的高精度温度测控系统-PCB设计
  11. html页面实现右下角弹窗提示,JS 实现右下角弹窗
  12. 2018 新年快乐 万事如意
  13. diy一个android手机版下载,Notch DIY
  14. mysql实现中文根据拼音排序
  15. 使用DHT11和51单片机进行温湿度的读取(保证好用版本)
  16. 流量卡官网源码 有后台带文章系统
  17. 【渝粤教育】电大中专学习指南作业 题库
  18. android listview 点击获取焦点,android – ListView项目焦点行为
  19. 爬取QQ音乐周杰伦歌曲的歌词
  20. HTTP Cache

热门文章

  1. 如何升级手机android系统,安卓手机系统怎么升级,安卓手机系统升级教程
  2. 【题单——基础字符串】菜鸡L_C_A的基础字符串(KMPACAM)
  3. 实施CRM目标有哪几步?如何制定CRM目标?
  4. 小程序服务器token,小程序-登录-token
  5. PCM A律μ律编码
  6. linux查看cpu主频
  7. 计算机网络论文英语翻译,COMPUTER NETWORK_计算机网络(英语论文翻译)
  8. zero-shot基础入门
  9. python安装了不能用_python – 我安装了pandas,但它无法正常工作
  10. PCB中的微带线和带状线延时上的差别