显然每一位的限制独立,对于每一位求出仅限制该位下的最大数,然后求最小值即可。

假设当前要求数字$d$的答案:

考虑填数字的过程,可以看作依次考虑一个序列中的每个数,当前缀和$<0$时退出。

设$dp[i][j][k]$表示正在考虑最低的$i$位,高位部分有$j$个$d$,第$i$位能不能填$0$为$k$时,所有可能的数字形成的序列的信息。

这个信息需要维护两个值:

  • $f$:前缀和最小值。
  • $s$:总和。

显然这个信息可以进行合并。

求出答案的位数后,再从高到低逐位确定即可。

时间复杂度$O(\log^2n)$。

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. const int N=100,B=10000,MAXL=25;
  5. int cur,v[N][N][2];
  6. struct Num{
  7. int a[MAXL],len,fu;
  8. Num(){len=1,fu=a[1]=0;}
  9. void clr(){len=1,fu=a[1]=0;}
  10. Num operator+(const Num&b)const{
  11. Num c;
  12. c.len=max(len,b.len)+2;
  13. int i;
  14. for(i=1;i<=c.len;i++)c.a[i]=0;
  15. if(fu==b.fu){
  16. for(i=1;i<=len;i++)c.a[i]=a[i];
  17. for(i=1;i<=b.len;i++)c.a[i]+=b.a[i];
  18. for(i=1;i<=c.len;i++)if(c.a[i]>=B)c.a[i+1]++,c.a[i]-=B;
  19. while(c.len>1&&!c.a[c.len])c.len--;
  20. c.fu=fu;
  21. }else{
  22. bool flag=0;
  23. if(len==b.len){
  24. for(i=len;i;i--)if(a[i]!=b.a[i]){
  25. if(a[i]>b.a[i])flag=1;
  26. break;
  27. }
  28. }else{
  29. if(len>b.len)flag=1;
  30. }
  31. if(flag){
  32. for(i=1;i<=len;i++)c.a[i]=a[i];
  33. for(i=1;i<=b.len;i++)c.a[i]-=b.a[i];
  34. for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=B;
  35. while(c.len>1&&!c.a[c.len])c.len--;
  36. c.fu=fu;
  37. }else{
  38. for(i=1;i<=b.len;i++)c.a[i]=b.a[i];
  39. for(i=1;i<=len;i++)c.a[i]-=a[i];
  40. for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=B;
  41. while(c.len>1&&!c.a[c.len])c.len--;
  42. c.fu=b.fu;
  43. }
  44. }
  45. return c;
  46. }
  47. Num operator-(Num b)const{
  48. b.fu^=1;
  49. return *this+b;
  50. }
  51. Num operator*(const Num&b)const{
  52. Num c;
  53. c.len=len+b.len+2;
  54. c.fu=fu^b.fu;
  55. int i,j;
  56. for(i=1;i<=c.len;i++)c.a[i]=0;
  57. for(i=1;i<=len;i++)for(j=1;j<=b.len;j++){
  58. c.a[i+j-1]+=a[i]*b.a[j];
  59. if(c.a[i+j-1]>=B){
  60. c.a[i+j]+=c.a[i+j-1]/B;c.a[i+j-1]%=B;
  61. if(c.a[i+j]>=B)c.a[i+j+1]+=c.a[i+j]/B,c.a[i+j]%=B;
  62. }
  63. }
  64. while(c.len>1&&!c.a[c.len])c.len--;
  65. return c;
  66. }
  67. bool iszero()const{
  68. return len==1&&!a[1];
  69. }
  70. void write(){
  71. if(len==1&&!a[1])fu=0;
  72. if(fu)putchar('-');
  73. printf("%d",a[len]);
  74. for(int i=len-1;i;i--)printf("%04d",a[i]);
  75. }
  76. void set(int x){
  77. if(x<0)fu=1,x=-x;else fu=0;
  78. if(x>=B){
  79. len=2;
  80. a[1]=x%B;
  81. a[2]=x/B;
  82. }else{
  83. len=1;
  84. a[1]=x;
  85. }
  86. }
  87. int sgn()const{
  88. if(iszero())return 0;
  89. return fu==1?-1:1;
  90. }
  91. int cmp(const Num&b)const{
  92. int x=sgn(),y=b.sgn();
  93. if(x!=y)return x<y?-1:1;
  94. if(!x)return 0;
  95. if(x>0){
  96. if(len!=b.len)return len<b.len?-1:1;
  97. for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]<b.a[i]?-1:1;
  98. return 0;
  99. }
  100. if(len!=b.len)return len>b.len?-1:1;
  101. for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]>b.a[i]?-1:1;
  102. return 0;
  103. }
  104. bool operator<(const Num&b)const{return cmp(b)<0;}
  105. bool operator==(const Num&b)const{return cmp(b)==0;}
  106. bool operator>(const Num&b)const{return cmp(b)>0;}
  107. }ans,val[11];
  108. struct P{
  109. Num f,s;
  110. P(){f.clr();s.clr();}
  111. void clr(){f.clr();s.clr();}
  112. P(Num _f,Num _s){f=_f,s=_s;}
  113. P operator+(const P&b)const{return P(min(f,s+b.f),s+b.s);}
  114. void operator+=(const P&b){*this=*this+b;}
  115. }base,f[N][N][2];
  116. P dfs(int x,int y,int z){
  117. if(x==0){
  118. P t;
  119. t.f.set(-y);
  120. t.s.set(-y);
  121. return base+t;
  122. }
  123. if(v[x][y][z]==cur+1)return f[x][y][z];
  124. v[x][y][z]=cur+1;
  125. P t;
  126. t.clr();
  127. for(int i=z;i<10;i++)t+=dfs(x-1,y+(i==cur),0);
  128. return f[x][y][z]=t;
  129. }
  130. Num solve(int _cur,int _base){
  131. cur=_cur;
  132. base.f.set(0);
  133. base.s.set(_base);
  134. int i,j,len;
  135. P pre;
  136. pre.clr();
  137. for(len=1;;len++){
  138. P now=dfs(len,0,1);
  139. if((pre+now).f.sgn()<0)break;
  140. pre+=now;
  141. }
  142. Num ans=val[0];
  143. int sum=0;
  144. for(i=len;i;i--)for(j=i==len?1:0;;j++){
  145. int nowsum=sum+(j==cur);
  146. P now=dfs(i-1,nowsum,0);
  147. if((pre+now).f.sgn()<0){
  148. sum=nowsum;
  149. ans=ans*val[10]+val[j];
  150. break;
  151. }
  152. pre+=now;
  153. }
  154. return ans;
  155. }
  156. int main(){
  157. for(int i=0;i<11;i++)val[i].set(i);
  158. for(int i=0;i<10;i++){
  159. int x;
  160. scanf("%d",&x);
  161. if(i==0)ans=solve(i,x);
  162. else ans=min(ans,solve(i,x));
  163. }
  164. ans=ans-val[1];
  165. ans.write();
  166. return 0;
  167. }

  

BZOJ1386 : [Baltic2000]Stickers的更多相关文章

  1. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  2. bzoj1385: [Baltic2000]Division expression

    欧几里得算法.可以发现规律,a[2]作为分母,其他作为分子,必定是最好的选择.判断是否为整数即可. #include<cstdio> #include<cstring> #in ...

  3. BZOJ 1385: [Baltic2000]Division expression

    题目 1385: [Baltic2000]Division expression Time Limit: 5 Sec  Memory Limit: 64 MB Description 除法表达式有如下 ...

  4. About Unixstickers - Unixstickers - stickers on unix, programming, software, development and open source

    About Unixstickers - Unixstickers - stickers on unix, programming, software, development and open so ...

  5. [LeetCode] Stickers to Spell Word 贴片拼单词

    We are given N different types of stickers. Each sticker has a lowercase English word on it. You wou ...

  6. [Swift]LeetCode691. 贴纸拼词 | Stickers to Spell Word

    We are given N different types of stickers. Each sticker has a lowercase English word on it. You wou ...

  7. 使用Stickers拓展集成iMessage简单功能

    添加一个target,选择Stickers拓展: 然后就会出现iMessage的文件夹:添加你需要的iMessage图片,这里图片遵循下面的要求: Small: 100 x 100 pt @3x sc ...

  8. LeetCode691. Stickers to Spell Word

    We are given N different types of stickers. Each sticker has a lowercase English word on it. You wou ...

  9. 691. Stickers to Spell Word

    We are given N different types of stickers. Each sticker has a lowercase English word on it. You wou ...

随机推荐

  1. Java中方法定义和调用的学习

    方法其实就是若干语句的功能集合. 参数(原料):就是进入方法的数据.返回值(原产物):就是从方法中出来的数据. 定义方法的完整格式:修饰符  返回值类型  方法名称(参数类型 参数名称,...){ 方 ...

  2. Ubuntu18.04应用程序安装集锦

    整理网上的资源: Python Web开发工具箱 ubuntu美化及超NB的zsh配置 api文档查询工具:zeal,dash(收费)

  3. Css - 选择器和样式

    Css - 选择器和样式 标签选择器 即使用html标签作为选择对象 <style>     div{ background:red; } </style> <div&g ...

  4. sql注入--双查询报错注入原理探索

    目录 双查询报错注入原理探索 part 1 场景复现 part 2 形成原因 part 3 报错原理 part 4 探索小结 双查询报错注入原理探索 上一篇讲了双查询报错查询注入,后又参考了一些博客, ...

  5. [Kubernetes]基于角色的权限控制之RBAC

    Kubernetes中有很多种内置的编排对象,此外还可以自定义API资源类型和控制器的编写方式.那么,我能不能自己写一个编排对象呢?答案是肯定的.而这,也正是Kubernetes项目最具吸引力的地方. ...

  6. L2-007 家庭房产 (25 分) (并查集)

    链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805068539215872 题目: 给定每个人的家庭成员和其自己名 ...

  7. 医学图像数据(一)——TCIA基本介绍

    1.介绍 The Cancer Imaging Archive (TCIA)是癌症研究的医学图像的开放获取数据库.该网站由国家癌症研究所(NCI)癌症影像计划资助,合同由阿肯色大学医学科学院管理.存档 ...

  8. 变分自编码器(Variational Autoencoder, VAE)通俗教程

    原文地址:http://www.dengfanxin.cn/?p=334 1. 神秘变量与数据集 现在有一个数据集DX(dataset, 也可以叫datapoints),每个数据也称为数据点.我们假定 ...

  9. web文件下载

    web页面实现文件下载的几种方法 今天碰到文件下载的一些问题,本着知其然也要知其所以然的精神,站在巨人的肩膀上深入学习和测试了一下,抛砖引玉,现在总结结论如下: 1)标准URL下载方式可以通过在web ...

  10. vertx的HttpServer模块

    Start HttpServer /** * 启动 HttpServer * multi instances 采用 synchronized防止线程安全问题 * addHandlers 方法是acto ...