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

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

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

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

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

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

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

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

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

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100,B=10000,MAXL=25;
int cur,v[N][N][2];
struct Num{
int a[MAXL],len,fu;
Num(){len=1,fu=a[1]=0;}
void clr(){len=1,fu=a[1]=0;}
Num operator+(const Num&b)const{
Num c;
c.len=max(len,b.len)+2;
int i;
for(i=1;i<=c.len;i++)c.a[i]=0;
if(fu==b.fu){
for(i=1;i<=len;i++)c.a[i]=a[i];
for(i=1;i<=b.len;i++)c.a[i]+=b.a[i];
for(i=1;i<=c.len;i++)if(c.a[i]>=B)c.a[i+1]++,c.a[i]-=B;
while(c.len>1&&!c.a[c.len])c.len--;
c.fu=fu;
}else{
bool flag=0;
if(len==b.len){
for(i=len;i;i--)if(a[i]!=b.a[i]){
if(a[i]>b.a[i])flag=1;
break;
}
}else{
if(len>b.len)flag=1;
}
if(flag){
for(i=1;i<=len;i++)c.a[i]=a[i];
for(i=1;i<=b.len;i++)c.a[i]-=b.a[i];
for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=B;
while(c.len>1&&!c.a[c.len])c.len--;
c.fu=fu;
}else{
for(i=1;i<=b.len;i++)c.a[i]=b.a[i];
for(i=1;i<=len;i++)c.a[i]-=a[i];
for(i=1;i<=c.len;i++)if(c.a[i]<0)c.a[i+1]--,c.a[i]+=B;
while(c.len>1&&!c.a[c.len])c.len--;
c.fu=b.fu;
}
}
return c;
}
Num operator-(Num b)const{
b.fu^=1;
return *this+b;
}
Num operator*(const Num&b)const{
Num c;
c.len=len+b.len+2;
c.fu=fu^b.fu;
int i,j;
for(i=1;i<=c.len;i++)c.a[i]=0;
for(i=1;i<=len;i++)for(j=1;j<=b.len;j++){
c.a[i+j-1]+=a[i]*b.a[j];
if(c.a[i+j-1]>=B){
c.a[i+j]+=c.a[i+j-1]/B;c.a[i+j-1]%=B;
if(c.a[i+j]>=B)c.a[i+j+1]+=c.a[i+j]/B,c.a[i+j]%=B;
}
}
while(c.len>1&&!c.a[c.len])c.len--;
return c;
}
bool iszero()const{
return len==1&&!a[1];
}
void write(){
if(len==1&&!a[1])fu=0;
if(fu)putchar('-');
printf("%d",a[len]);
for(int i=len-1;i;i--)printf("%04d",a[i]);
}
void set(int x){
if(x<0)fu=1,x=-x;else fu=0;
if(x>=B){
len=2;
a[1]=x%B;
a[2]=x/B;
}else{
len=1;
a[1]=x;
}
}
int sgn()const{
if(iszero())return 0;
return fu==1?-1:1;
}
int cmp(const Num&b)const{
int x=sgn(),y=b.sgn();
if(x!=y)return x<y?-1:1;
if(!x)return 0;
if(x>0){
if(len!=b.len)return len<b.len?-1:1;
for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]<b.a[i]?-1:1;
return 0;
}
if(len!=b.len)return len>b.len?-1:1;
for(int i=len;i;i--)if(a[i]!=b.a[i])return a[i]>b.a[i]?-1:1;
return 0;
}
bool operator<(const Num&b)const{return cmp(b)<0;}
bool operator==(const Num&b)const{return cmp(b)==0;}
bool operator>(const Num&b)const{return cmp(b)>0;}
}ans,val[11];
struct P{
Num f,s;
P(){f.clr();s.clr();}
void clr(){f.clr();s.clr();}
P(Num _f,Num _s){f=_f,s=_s;}
P operator+(const P&b)const{return P(min(f,s+b.f),s+b.s);}
void operator+=(const P&b){*this=*this+b;}
}base,f[N][N][2];
P dfs(int x,int y,int z){
if(x==0){
P t;
t.f.set(-y);
t.s.set(-y);
return base+t;
}
if(v[x][y][z]==cur+1)return f[x][y][z];
v[x][y][z]=cur+1;
P t;
t.clr();
for(int i=z;i<10;i++)t+=dfs(x-1,y+(i==cur),0);
return f[x][y][z]=t;
}
Num solve(int _cur,int _base){
cur=_cur;
base.f.set(0);
base.s.set(_base);
int i,j,len;
P pre;
pre.clr();
for(len=1;;len++){
P now=dfs(len,0,1);
if((pre+now).f.sgn()<0)break;
pre+=now;
}
Num ans=val[0];
int sum=0;
for(i=len;i;i--)for(j=i==len?1:0;;j++){
int nowsum=sum+(j==cur);
P now=dfs(i-1,nowsum,0);
if((pre+now).f.sgn()<0){
sum=nowsum;
ans=ans*val[10]+val[j];
break;
}
pre+=now;
}
return ans;
}
int main(){
for(int i=0;i<11;i++)val[i].set(i);
for(int i=0;i<10;i++){
int x;
scanf("%d",&x);
if(i==0)ans=solve(i,x);
else ans=min(ans,solve(i,x));
}
ans=ans-val[1];
ans.write();
return 0;
}

  

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. 【LOJ 6041】「雅礼集训 2017 Day7」事情的相似度

    Description 人的一生不仅要靠自我奋斗,还要考虑到历史的行程. 历史的行程可以抽象成一个 01 串,作为一个年纪比较大的人,你希望从历史的行程中获得一些姿势. 你发现在历史的不同时刻,不断的 ...

  2. Repeater取不到服务端控件

    <td>      <asp:Button ID="Button1" runat="server" Text="查看" O ...

  3. kail linux虚拟机安装tools工具

    因为自己比较懒,有时候自己不想打字需要粘贴就安装了虚拟机tools工具,又因为自己脑子不好使所以就写一下步骤,以便以后用得着.我这里用得是kail linux系统,不知道contest能不能这样安,下 ...

  4. This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de 错误解决办法

    这是我们开启了bin-log, 我们就必须指定我们的函数是否是1 DETERMINISTIC 不确定的2 NO SQL 没有SQl语句,当然也不会修改数据3 READS SQL DATA 只是读取数据 ...

  5. 2018-2019-2 20165231 王杨鸿永 Exp6 信息搜集与漏洞扫描

    实践目标 掌握信息搜集的最基础技能与常用工具的使用方法. 2.实践内容 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具体服 ...

  6. 使用Mac下的sequel Pro链接数据库时提示错误(已解决)

    使用Mac下的sequel Pro链接数据库时,出现如下问题: ? 1 MySQL said: Authentication plugin 'caching_sha2_password' cannot ...

  7. 阻塞IO,非阻塞IO,IO多路复用模型

    #服务端 import socket sk = socket.socket() sk.bind(('127.0.0.1',8080)) sk.listen() while True: conn, ad ...

  8. IIS+nginx反向代理 负载均衡

    本文没有过多的讲述,只讲述重点地方.由这两个转自的文章进行中和 1.nginx+iis实现负载均衡(这篇文章主要是有第2篇文章的工具) 2.nginx+iis使用(这篇文章讲得很详细,配置文件直接复制 ...

  9. python正则表达式基础,以及pattern.match(),re.match(),pattern.search(),re.search()方法的使用和区别

    正则表达式(regular expression)是一个特殊的字符序列,描述了一种字符串匹配的模式,可以用来检查一个字符串是否含有某种子字符串. 将匹配的子字符串替换或者从某个字符串中取出符合某个条件 ...

  10. flex布局学习

    教程来自阮一峰的flex布局教程实例篇 容器五大属性: flex-direction:容器内项目的排列方向 (1)row:横向从左往右排列(默认) (2)row-reverse:横向从右往左排列 (3 ...