当前位置: 首页 > news >正文

BZOJ 1974 [Sdoi2010] auction 代码拍卖会(数位dp)

题目描述

随着iPig在P++语言上的造诣日益提升,他形成了自己一套完整的代码库。猪王国想参加POI的童鞋们都争先恐后问iPig索要代码库。iPig不想把代码库给所有想要的小猪,只想给其中的一部分既关系好又肯出钱的小猪,于是他决定举行了一个超大型拍卖会。

在拍卖会上,所有的N头小猪将会按照和iPig的好感度从低到高,从左到右地在iPig面前站成一排。每个小猪身上都有9猪币(与人民币汇率不明),从最左边开始,每个小猪依次举起一块牌子,上面写上想付出的买代码库的猪币数量(1到9之间的一个整数)。大家都知道,如果自己付的钱比左边的猪少,肯定得不到梦寐以求的代码库,因此从第二只起,每只猪出的钱都大于等于左边猪出的价钱。最终出的钱最多的小猪(们)会得到iPig的代码库真传,向着保送PKU(Pig Kingdom University)的梦想前进。

iPig对自己想到的这个点子感到十分满意,在去现场的路上,iPig就在想象拍卖会上会出现的场景,例如一共会出现多少种出价情况之类的问题,但这些问题都太简单了,iPig早已不敢兴趣了,他想要去研究更加困难的问题。iPig发现如果他从台上往下看,所有小猪举的牌子从左到右将会正好构成一个N位的整数,他现在想要挑战的问题是所有可能构成的整数中能正好被P整除的有多少个。由于答案过大,他只想要知道答案mod 999911659就行了。

输入输出格式

输入格式:

 

输入文件auction.in有且仅有一行:两个数N(1≤N≤10^18)、P(1≤P≤500),用一个空格分开。

 

输出格式:

 

输入文件auction.out有且仅有一行:一个数,表示答案除以999911659的余数。

 

输入输出样例

输入样例#1:  复制
2 3
输出样例#1:  复制
15

说明

样例解释

方案可以是:12 15 18 24 27 33 36 39 45 48 57 66 69 78 99,共15种。

数据规模

题解

  这题太神仙了……题解看都看不懂……最后基本只能硬生生的理解了……

  首先,我们考虑数列,原数列是一个不降的序列

  考虑如下数列,$1,1,2,3,4$

  这样我们是相当于竖着分割的

  那么怎么转换为横着分割呢?我们可以记录大于等于$1$的数的个数,为$5$,大于等于$2$的数的个数,为$3$……

  那么最后原数列可以转化为$11111,111,11,1$(每个数用相同个数的$1$表示),然后我们惊奇的发现他们的和和原来的$n$位数是一样的,也就是说,他们构成的整数取模之后也是一样的!

  这就相当于在每一个位置放相当于权值大小的石头,我们一开始是竖着分,而第二种方法是横着分割

  如果竖着分割,总共有$n$个数,如果横着割,把所有模$p$同余的看成一类,那么总共只有$p$个数(因为0,1,11,111这样下去模$p$的值肯定能构成一个循环节,所以只需要计算$p$次,剩下的可以直接计算)

  那么我们为什么不转化为横着分割呢?设$cnt[i]$表示模$p$为$i$的数的个数,那么题目就变成从$cnt[i]$中取$9$个使下标之和被$p$整除

  那么就可以转化为dp了,设$f[i][j][k]$表示考虑到第$i$个数,选了$k$个,他们的和模$p$为$j$,那么状态转移方程就是$f[i+1][(j+l*i)%mod][k+l]=(f[i][j][k]*C_{cnt_i}^l+f[i+1][(j+l*i)%mod][k+l])%mod$

  然后要先考虑加上一个$11111$($n$个$1$),因为我们dp的时候是允许有前导$0$的,所以得先强制至少为$1$才行

  细节有点多,都写在注解里了

 1 //minamoto
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #define ll long long
 7 using namespace std;
 8 const int mod=999911659;
 9 ll ans,n,p,cnt[505],beg,len,pos[505],A[11],c[505][11],f[505][505][11],a;
10 int main(){
11     scanf("%lld%d",&n,&p);
12     ll sum=0;
13     if(n<=p){
14         //直接把循环节跑出来 
15         for(int i=1;i<=n;++i) sum=(sum*10+1)%p,++cnt[sum];
16         a=sum;
17     }else{
18         //否则去找循环节,数出每一个余数的出现次数 
19         for(int i=1;i<=p+1;++i){
20             sum=(sum*10+1)%p;
21             if(cnt[sum]){
22                 beg=pos[sum],len=i-pos[sum];
23                 break;
24             }
25             ++cnt[sum],pos[sum]=i;
26         }
27         for(int i=0;i<p;++i)
28         if(cnt[i]&&pos[i]>=beg){
29             cnt[i]=(n-beg+1)/len;
30             if(pos[i]-beg+1<=(n-beg+1)%len) ++cnt[i];
31             if((pos[i]-beg+1)%len==(n-beg+1)%len) a=i;
32         }
33     }
34     A[1]=1,A[0]=0;
35     for(int i=2;i<=8;++i)
36     A[i]=(mod-mod/i)*A[mod%i]%mod;
37     for(int i=0;i<p;++i){
38         c[i][0]=1;
39         if(cnt[i])
40         for(int j=1;j<=8;++j){
41             c[i][j]=cnt[i]*c[i][j-1]%mod*A[j]%mod;
42             cnt[i]=(cnt[i]+1)%mod;
43             //C(n,m-1)->C(n,m)
44             //C(n,m-1)/m*(n-m+1)=C(n,m)
45             //cnt[i]=n-m+1
46         }
47     }
48     f[0][a][0]=1;
49     //默认加n个1,因为dp的时候可以有前缀0 
50     for(int i=0;i<p;++i)
51     for(int j=0;j<p;++j)
52     for(int k=0;k<9;++k)
53     for(int l=0;l<=k;++l)
54     (f[i+1][j][k]+=f[i][(j-(l*i%p)+p)%p][k-l]*c[i][l]%mod)%mod;
55     for(int i=0;i<=8;++i) (ans+=f[p][0][i])%=mod;
56     printf("%lld\n",ans);
57     return 0;
58 }

 

转载于:https://www.cnblogs.com/bztMinamoto/p/9542722.html

相关文章:

  • Java中单例设计模式之最佳实践举例
  • Redkale 入门教程 01 -- Hello Word!
  • iOS sqlite 使用事务操作数据库
  • 【队列】【P2827】【NOIP2016D2T3】蚯蚓
  • java中Xml、json之间的相互转换
  • 新概念书店无非内容电商线下变体,西西弗终难逃被资本吞并命运?
  • android应用activity中调出输入法后界面调整问题的解决
  • watch深度监测
  • PHP-学习大规模高并发Web系统架构及开发推荐书籍
  • [caffe(二)]Python加载训练caffe模型并进行测试1
  • 【转】ini载入保存类,操作INI配置文件方便的很
  • PostgreSQL 连接的问题
  • 珍爱之礼 美妙感受
  • Python Flask-Mail环境变量配置
  • 内表生成XML简单实例
  • [译]前端离线指南(上)
  • 【个人向】《HTTP图解》阅后小结
  • 0基础学习移动端适配
  • Angular数据绑定机制
  • EventListener原理
  • Fastjson的基本使用方法大全
  • idea + plantuml 画流程图
  • Java程序员幽默爆笑锦集
  • laravel with 查询列表限制条数
  • Median of Two Sorted Arrays
  • Mybatis初体验
  • ng6--错误信息小结(持续更新)
  • SpiderData 2019年2月23日 DApp数据排行榜
  • vue自定义指令实现v-tap插件
  • Zsh 开发指南(第十四篇 文件读写)
  • 分类模型——Logistics Regression
  • 力扣(LeetCode)22
  • 聊聊flink的BlobWriter
  • 排序算法之--选择排序
  • 前端
  • 容器服务kubernetes弹性伸缩高级用法
  • 入手阿里云新服务器的部署NODE
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 正则学习笔记
  • 继 XDL 之后,阿里妈妈开源大规模分布式图表征学习框架 Euler ...
  • ​比特币大跌的 2 个原因
  • #1015 : KMP算法
  • #ifdef 的技巧用法
  • #我与Java虚拟机的故事#连载17:我的Java技术水平有了一个本质的提升
  • (3)llvm ir转换过程
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (七)微服务分布式云架构spring cloud - common-service 项目构建过程
  • (强烈推荐)移动端音视频从零到上手(上)
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .NET 中什么样的类是可使用 await 异步等待的?
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题