题目链接:戳我

昨天做的题了,今天补一发题解。

是一个比较奇怪的数位DP。详细的我还是写代码注释里好了,感觉直接说不好描述。

代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#define MAXN 200010
#define mod 1000000007
using namespace std;
int tot,cnt,len,nn;
int a[15],num[MAXN];
long long N,K,x,ans;
long long b[MAXN*10],dp[15][MAXN][2],siz[MAXN];
struct Node
{
int x,y;
long long val;
friend bool operator < (struct Node x,struct Node y)
{return x.val<y.val;}
Node(int u,int v)
{
x=u,y=v;
val=1ll*siz[num[u]]*siz[num[v]];
}
//构造函数
};
priority_queue<Node>q;
inline void dfs(int now,int x,long long kk)
{
if(kk==0) return;
if(x>len){b[++cnt]=kk;return;}
for(int i=now;i<=9;i++) dfs(i,x+1,kk*i);
}
//首先通过dfs求出来合法的(也就是会被转移到的格子)
//为什么这样时间复杂度是正确的?大家计算一下,对于该题目里的格子,它转移到的格子的数分解下来
//也不过就是(2^a)*(3^b)*(5^c)*(7^d)
//所以总的状态数量大概就在1e5的级别
inline bool cmp(const int x,const int y){return siz[x]>siz[y];}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%lld%lld",&N,&K);
while(N){a[++len]=N%10;N/=10;}//按位分解
dfs(0,0,1);
sort(&b[1],&b[1+cnt]);
cnt=unique(&b[1],&b[1+cnt])-b-1;
//离散化预处理
dp[0][2][0]=1;
//dp[i][j][0/1]表示的是现在处理到了第i位,数位乘积为j,0表示它当前位小于等于n对应的位上的数
//1表示大于
for(int i=0;i<=len;i++)
{
for(int j=1;j<=cnt;j++)
{
for(int k=0;k<=1;k++)
{
if(!dp[i][j][k]) continue;
for(int p=1;p<=9;p++)
(dp[i+1][lower_bound(&b[1],&b[1+cnt],b[j]*p)-b][k+p>a[i+1]]+=dp[i][j][k])%=mod;
}
}
}
//注:我们将i+1当做当前位,i当做上一位,以下叙述均按此
//注意乘积比较大,所以要离散化,而这里使用lower_bound来确定位次就是一个不错的选择
//当前位填p,进行转移(感觉转移方程式还是很好懂的吧qwqwq,思考一下就行了)
//至于第三维为什么写k+p>a[i+1]呢?
//当上一位小于等于的时候,k=0,只有当前位>a[i+1]的时候,它才会比原数N大(对吧qwq)
//当上一位大于的时候,只要当前位等于,它就会比原数N大,更别说大于了qwqwq
//(懵懵懂懂
for(int j=1;j<=cnt;j++)
{
num[j]=j;
for(int i=1;i<len;i++)siz[j]+=dp[i][j][1]+dp[i][j][0];
siz[j]+=dp[len][j][0];
}
sort(&num[2],&num[cnt+1],cmp);
q.push(Node(2,2));//为什么从2,2开始?因为这里是第一个
//取前K大,用优先队列维护即可
while(!q.empty())
{
int u_x=q.top().x,u_y=q.top().y;
long long u_val=q.top().val;
q.pop();
ans=(ans+u_val)%mod;
nn++;
if(nn==K) break;
if(u_x!=u_y)
{
ans=(ans+u_val)%mod;
//如果x坐标y坐标不一样要加两遍(也就是乘2的意思),至于为什么,大家想想吧qwq
q.push(Node(u_x+1,u_y));
nn++;
if(nn==K) break;
}
if(u_x==2) q.push(Node(u_x,u_y+1));
}
printf("%lld\n",ans);
return 0;
}
//完结撒花~

备注:该代码很大程度上参考了网上的题解(因为本弱菜实在是写不出来正解。。。要是考试估计也是打个暴力走人了),但是网上题解写的实在不是很详细,所以这里特地来补一篇详细的,希望大家都能看懂qwq

SDOI2013 淘金的更多相关文章

  1. [BZOJ3131] [Sdoi2013]淘金

    [BZOJ3131] [Sdoi2013]淘金 Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐 ...

  2. [Bzoj3131][Sdoi2013]淘金(数位dp)(优先队列)

    3131: [Sdoi2013]淘金 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 847  Solved: 423[Submit][Status][ ...

  3. Bzoj 3131 [Sdoi2013]淘金 题解

    3131: [Sdoi2013]淘金 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 733  Solved: 363[Submit][Status][ ...

  4. 题解-SDOI2013 淘金

    题面 SDOI2013 淘金 有一个 \(X\).\(Y\) 轴坐标范围为 \(1\sim n\) 的范围的方阵,每个点上有块黄金.一阵风来 \((x,y)\) 上的黄金到了 \((f(x),f(y) ...

  5. bzoj 3131: [Sdoi2013]淘金

    #include<cstdio> #include<iostream> #include<queue> #include<algorithm> #def ...

  6. bzoj 3131 [Sdoi2013]淘金(数位DP+优先队列)

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

  7. 【bzoj 3131】[Sdoi2013]淘金

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

  8. bozoj3131: [Sdoi2013]淘金 数位dp

    链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3131 思路 1. 函数值的素因子只有2.3.5.7 由他们组成的状态不多,爆搜的时候即使搜不 ...

  9. BZOJ 3131 [SDOI2013]淘金 - 数位DP

    传送门 Solution 这道数位$DP$看的我很懵逼啊... 首先我们肯定要先预处理出 $12$位乘起来的所有的可能情况, 记录入数组 $b$, 发现个数并不多, 仅$1e4$不到. 然后我们考虑算 ...

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

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

随机推荐

  1. 修改kvm虚拟机镜像大小

    修改虚拟机镜像大小(qcow2/raw resize) 创建一个镜像文件,大小1G taw muxueqz@muxueqz /tmp $ qemu-img create -f raw t.raw 1G ...

  2. https 理解

    这张图已经很明白,以下为翻译: 一.秘钥传输过程(确认秘钥相同) 1.请求服务端 2.服务端有公司要 3.公钥发给客户端 4.验证发过来的公钥crt,生成随机秘钥,并用此公钥加密 5.加密后的秘钥发给 ...

  3. WebPack 从安装到闲置

    序言:各种技术在研究过程中常常会出现在实际工作中难以实施的情况,于是就慢慢闲置,但学毕竟还是必须要学学的,就看能用到多少,至少开拓了眼界,谨以此安慰下那些学完又闲置的技术~ 跑题结束,以下开始正式配置 ...

  4. Computer2

    luo@luo-All-Series:~/MyFile/TensorflowProject$ conda create -n flappbird1 python=3.7Solving environm ...

  5. STM32 FATFS文件系统移植

    http://www.360doc.com/content/11/1221/10/7736891_173820469.shtml

  6. JVM内存区域解析

    引言 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,以及创建和销毁的时间.有的区域随着虚拟机进程的启动而存在,有些区域则是依赖用户线程的 ...

  7. [SoapUI] 通过SoapUI发送POST请求,请求的body是JSON格式的数据

    通过SoapUI发送POST请求,请求的body是JSON格式的数据: data={"currentDate":"2015-06-19","reset ...

  8. Spring Boot☞ 配置文件详解:自定义属性、随机数、多环境配置等

    自定义属性与加载 我们在使用Spring Boot的时候,通常也需要定义一些自己使用的属性,我们可以如下方式直接定义: application-dev.yml com.didispace.blog: ...

  9. 黑盒测试实践-任务进度-Day05

    任务进度11-30 使用工具 selenium 小组成员 华同学.郭同学.穆同学.沈同学.覃同学.刘同学 任务进度 经过了前两天的学习任务的安排,以下是大家的任务进度: 华同学(任务1) 1.由于昨天 ...

  10. 用jvm指令分析String 常量池

    其他博友的不同理解方式:  http://hi.baidu.com/boywell/item/d5ee5b0cc0af55c875cd3cfd 我们先来看一个类 public class javaPT ...