51nod 完美消除 DP
2017-02-10 21:45
337 查看
定义数的消除操作为选定[L,R,x],如果数的第L到第R位上的数字都大于等于x,并且这些数都相等,那么该操作是合法的(从低位到高位编号,个位是第一位,百位是第二位……),然后将这些位数上的数减x;否则就是不合法的,不能进行操作。对一个数操作最少的次数使得这个数变成0,这个操作次数称为该数的最小操作数。如:1232的最小操作数为3,一个合法解是[2,2,1],[1,3,2],[4,4,1]。
求L~R中最小操作数为k的数的个数。
例如:132,需要操作3次才能变为0。而131131 => 111131 => 111111 =>0
Input
单组测试数据。
三个整数L、R和k(1<=L<=R<=10^18,1<=k<=18)。
Output
一个整数表示答案。
Input示例
10 21 2
Output示例
9
题解:表示这种题目一看就像套路题,好像模型很熟悉。但是并没有什么卵用,列不出dp式,后来去膜了一发题解才觉得这dp思路是真的巧妙。
我们首先思考给定一个数把它消成0的最小步数如何计算。就是从高位到低位枚举,设当前数字为x,开个栈,将栈里所有大于x的数字删除,如果此时栈里没有数字x则加入,并且答案+1。(经典套路,然而我并没想到)
然后把这个想法套到数位DP中,设f[i,s,k,c]表示前i位,栈中集合为s,已经做了k次操作,当前数与给定数的大小关系(0或1)。
然后就可以直接做了。
code(真的短小精悍= =)
求L~R中最小操作数为k的数的个数。
例如:132,需要操作3次才能变为0。而131131 => 111131 => 111111 =>0
Input
单组测试数据。
三个整数L、R和k(1<=L<=R<=10^18,1<=k<=18)。
Output
一个整数表示答案。
Input示例
10 21 2
Output示例
9
题解:表示这种题目一看就像套路题,好像模型很熟悉。但是并没有什么卵用,列不出dp式,后来去膜了一发题解才觉得这dp思路是真的巧妙。
我们首先思考给定一个数把它消成0的最小步数如何计算。就是从高位到低位枚举,设当前数字为x,开个栈,将栈里所有大于x的数字删除,如果此时栈里没有数字x则加入,并且答案+1。(经典套路,然而我并没想到)
然后把这个想法套到数位DP中,设f[i,s,k,c]表示前i位,栈中集合为s,已经做了k次操作,当前数与给定数的大小关系(0或1)。
然后就可以直接做了。
code(真的短小精悍= =)
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #define fo(i,a,b) for(int i=a;i<=b;i++) using namespace std; int n,m; typedef long long ll; int k,bit[20]; ll f[50][1050][20][2]; ll solve(ll n) { memset(f,0,sizeof(f)); int len=0; while (n)bit[++len]=n%10,n/=10; //reverse(bit+1,bit+1+len); f[0][1][0][0]=1; fo(i,1,len) fo(S,1,1023) fo(v,0,k) fo(c,0,1) { ll ans=f[i-1][S][v][c]; if (!ans)continue; fo(y,0,9)if (y<=bit[i]||c) { int S2=S|(1<<y),k2=v+1; fo(j,y+1,9) if (S>>j&1)S2^=(1<<j); if (S>>y&1)k2--; f[i][S2][k2][c|(y<bit[i])]+=ans; } } ll ans=0; fo(S,1,1023)ans+=f[len][S][k][1]; return ans; } int main() { ll l,r; scanf("%lld%lld",&l,&r); scanf("%d",&k); printf("%lld\n",solve(r+1)-solve(l)); return 0; }
相关文章推荐
- 51nod 1623 完美消除(数位DP)
- 51NOD 1623 完美消除 数位DP
- 51 nod 1623 完美消除(单调栈+数位DP)
- 51Nod-1623-完美消除
- 51nod 1623:完美消除
- 51nod1623 完美消除 (数位dp)
- 51nod1623完美消除 【数位dp】
- 51nod 1791 合法括号子段 (dp)
- 51Nod 1084 矩阵取数问题 V2(多进程DP模板)
- 51nod 1092 回文字符串(区间dp)
- 51Nod 1009 数字1的数量(数位dp)
- 51Nod 1182 完美字符串
- 51nod 1201 整数划分(dp)
- 51Nod 1022(四边形优化dp)
- 51nod 1084 更难的矩阵取数问题(DP)
- 【51nod】1406 与查询 DP
- 51nod 正整数分组(dp_思考题)
- 51Nod 1043 幸运号码 数位DP
- 51nod 1182 完美字符串 (贪心,水题)
- 51nod 1051 最大子矩阵和【dp】