sgu 390 购票(上下界数位dp)
来源:互联网 发布:spss13软件怎么安装 编辑:程序博客网 时间:2024/05/16 00:26
有一位售票员给乘客售票。对于每位乘客,他会卖出多张连续的票,直到已卖出的票的编号的数位之和不小于给定的正数K。然后他会按照相同的规则给下一位乘客售票。
初始时,售票员持有的票的编号是从L到R的连续整数。请你求出,售票员可以售票给多少位乘客。
数据规模:1 ≤ L ≤ R ≤ 10^18,1 ≤ K ≤ 1000。
思路:
此题需要上下界进行数位dp,且需要从小的开始放
dp[i][j][k]表示前面i位,现在前面的和,已经有的值
#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;int dig[2][20],k;bool vis[2][2][20][200][1010];struct node{ long long Count,left;}dp[2][2][20][200][1010];void add(node &x,node y){ x.Count+=y.Count; x.left=y.left;}node dfs(int pos,int limit1,int limit2,int pre_sum,int sum){ if(pos==-1) return sum+pre_sum>=k ? (node){1,0}:node{0,sum+pre_sum}; if(vis[limit1][limit2][pos][pre_sum][sum]==1) return dp[limit1][limit2][pos][pre_sum][sum]; node ans={0,sum}; int low=(limit1==1 ? dig[0][pos]:0),high=(limit2==1 ? dig[1][pos]:9); for(int i=low;i<=high;i++) add(ans,dfs(pos-1,limit1&(i==low),limit2&(i==high),i+pre_sum,ans.left)); vis[limit1][limit2][pos][pre_sum][sum]=1,dp[limit1][limit2][pos][pre_sum][sum]=ans; return ans;}int solve(int i,long long x){ int len=0; while(x){ dig[i][len++]=x%10; x/=10; } return len;}int main(){ long long L,R; scanf("%lld%lld%d",&L,&R,&k); solve(0,L); int len=solve(1,R); printf("%lld\n",dfs(len-1,1,1,0,0).Count);}
#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;int dig[2][20],k;bool vis[20][200][1010];struct node{ long long Count,left;}dp[20][200][1010];void add(node &x,node y){ x.Count+=y.Count; x.left=y.left;}node dfs(int pos,int limit1,int limit2,int pre_sum,int sum){ if(pos==-1) return sum+pre_sum>=k ? (node){1,0}:node{0,sum+pre_sum}; if(!limit1&&!limit2&&vis[pos][pre_sum][sum]==1) return dp[pos][pre_sum][sum]; node ans={0,sum}; int low=(limit1==1 ? dig[0][pos]:0),high=(limit2==1 ? dig[1][pos]:9); for(int i=low;i<=high;i++) add(ans,dfs(pos-1,limit1&(i==low),limit2&(i==high),i+pre_sum,ans.left)); if(!limit1&&!limit2) vis[pos][pre_sum][sum]=1,dp[pos][pre_sum][sum]=ans; return ans;}int solve(int i,long long x){ int len=0; while(x){ dig[i][len++]=x%10; x/=10; } return len;}int main(){ long long L,R; scanf("%lld%lld%d",&L,&R,&k); solve(0,L); int len=solve(1,R); printf("%lld\n",dfs(len-1,1,1,0,0).Count);}
0 0
- sgu 390 购票(上下界数位dp)
- HDU 3565 数位DP + 上下界
- SGU 390 Tickets(数位DP)
- SGU 390 Tickets(数位dp,较难)
- SGU 492 经典数位dp
- SGU 390 Tickets (数位DP, k进制树)
- SGU 390 Tickets (数位dp,k进制树的合并)
- SGU 176 上下界最小流
- sgu 194上下界网络流
- 【数位DP】【SGU 258】. Almost Lucky Numbers
- SGU 194 无源汇的上下界可行流
- sgu 176 有上下界的网络流
- ★ SGU 176 有源汇上下界最小流
- SGU 176 有源汇上下界最小流
- sgu 176 Flow construction 上下界最小流
- SGU 194. Reactor Cooling【无源汇上下界最大流】
- SGU 194 Reactor Cooling-上下界网络流模板题
- SGU 176 Flow construction-上下界网络流
- NOIP模拟题 [构造][贪心][暴力]
- Eclipse 安装FindBugs插件
- Linux(Centos6.5)下如何解压.zip和.rar文件
- Android Studio错误Error:(23, 17) Failed to resolve: junit:junit:4.12解决方案
- 关于MyEclipse的功能
- sgu 390 购票(上下界数位dp)
- 通过word embedding和关联规则改进Aspect提取效果
- BUG级别(优先级、严重级)定义
- Android SQLite常用命令:SQLite增删改查。
- js基本类型 引用类型 简单赋值 对象引用
- .initcall##level##.init
- Robotium自动化测试简介
- 一天一条Linux指令-wc
- 基础资料功能开发(附件上传、查看,获取当前用户信息、时间)