删除数字
来源:互联网 发布:网络机房装修标准 编辑:程序博客网 时间:2024/06/16 16:46
题目描述
给定两个数A和N,形成一个长度为N+1的序列,(A,A+1,A+2,…,A+N-1,A+N)。
每次操作可以把第i个数上的第x位数字删除,形成一个新的数字。
求有多少种方案,是的最后的数字是单调不递减的。
两种方案是认为不同,如果第i个数的第x位在一个方案中被删除,在另一个方案中,没有被删除。
输入
输入两个整数A和N
输出
输出方案数,对1e9+7 求余。
题目分析:
关键字:DP,二进制枚举
其实DP是比较显然的,现在的决策就是对于目前这个数,删掉它的哪几个数字。用二进制枚举,把剩下的数字取出来变回去,从前一次的状态中把比它小的状态全部转移过来即可,主要还是转移的这部分,因为直接用数的大小作为下标的话空间时间都不够用,所以可以离散了值,从排序完的序列中找到对应的最后一个位置,把值加过来,在加上前缀和维护值就不会复杂度太高了。
直接看代码:
#include<bits/stdc++.h>using namespace std;#define LL long long#define MOD 1000000007#define fin(x) freopen(x,"r",stdin)#define fout(x) freopen(x,"w",stdout)LL a;int n;void chkmax(int &a,int b) { if(a<b) a=b;}void chkmin(int &a,int b) { if(a>b) a=b;}void add(int &a,int b) { b%=MOD; a+=b; a%=MOD;}void add(int &a,LL b){ b%=MOD; a+=b; a%=MOD;}int tmp[22];LL A[305];struct NODE{ LL res,dp;};bool cmp(NODE A,NODE B) { return A.res<B.res;}struct node{ int cnt; int sum[20005]; NODE ok[20005]; int Find(LL x){ int L=1,R=cnt,Res=0; while(L<=R) { int mid=(L+R)>>1; if(ok[mid].res<=x) L=mid+1,Res=mid; else R=mid-1; } return Res; } void init() { for(int i=1;i<=cnt;i++){ sum[i]=0; add(sum[i],ok[i].dp+sum[i-1]); } }} DP[2]; //ok存的是值int len,cur;//记录上一层方案ok的个数int f(LL x) { int cnt=0; while(x) { tmp[cnt++]=x%10;//tmp从右到左 x/=10; } return cnt;}void Init(){ for(int i=0;i<=n;i++) A[i]=a+i;}void solve() { Init(); int m0=f(A[0]); DP[cur].cnt=0; for(int j=1; j<(1<<m0); j++) { LL num=0; for(int k=m0-1; k>=0; k--) if( (1<<k)&j ) num=num*10+tmp[k]; //从左到右 DP[cur].ok[++DP[cur].cnt].res=1LL*num; DP[cur].ok[DP[cur].cnt].dp=1; } sort(DP[cur].ok+1,DP[cur].ok+1+DP[cur].cnt,cmp); DP[cur].init(); for(int i=1; i<=n; i++) { int m=f(A[i]); DP[1-cur].cnt=0; for(int j=1; j<(1<<m); j++) { LL num=0; for(int k=m-1; k>=0; k--) if( (1<<k)&j ) num=num*10+tmp[k]; //从左到右 int pos=DP[cur].Find(num); DP[1-cur].ok[++DP[1-cur].cnt].dp=DP[cur].sum[pos]; DP[1-cur].ok[DP[1-cur].cnt].res=num; } cur=1-cur; sort(DP[cur].ok+1,DP[cur].ok+1+DP[cur].cnt,cmp); DP[cur].init();//统计前缀和 } printf("%d\n",DP[cur].sum[DP[cur].cnt]%MOD);}int main() { cin>>a>>n; solve(); return 0;}
阅读全文
1 0
- 删除数字
- 删除数字
- 删除数字
- 删除数字
- 删除数字
- 删除数字
- AOJ191 删除数字
- [java]间隔删除数字
- 删除字符串中的数字
- C 语言 数字删除
- 字符串删除数字
- 题目:删除数字
- lintcode-删除数字-182
- lintcode 删除数字
- 删除重复数字,java
- 删除数字vba
- LintCode 182-删除数字
- LintCode :删除数字
- 习题7-8:数字谜(dfs暴搜)
- 类与对象
- 第二课
- 十个关于自由和开源软件历史
- 前端打包构建工具Gulp、Rollup、Webpack、Webpack-stream
- 删除数字
- 能ping通Linux但是ssh连不上,可能的原因
- Hibernate ORM 之 单向一对多
- 试试
- MYSQL自带工具使用介绍
- opencv学习笔记 一 图像读取与操作
- 机会是给有准备的人-为了进入牛B软件公司我需要------------------------
- Codeforces Round #439 (Div. 2) C. The Intriguing Obsession
- 数据结构实验二之顺序表