初始给定一个整数n。每次可以对其做一个操作,这个操作是将n减去他其中的某一位。得到新的一个数字n’,然后继续操作,直到他变成0为止。
  比如24这个例子,24 → 20 → 18 → 10 → 9 → 0

 Input
  单组测试数据。
  第一行有一个整数n(0 ≤ n ≤ 10^12)
 Output
  输出一个整数表示使得n变成0最少的操作步数。.

  呃...今年学车中学noi摸你赛某场的T3....怎么在51nod上才5级啊(掀桌

  十连测那时候抄高分代码才过的...现在终于成功乱(背)搞(诵)出来了...

  没见过的数位DP姿势。

  结构体f[i][j][k].step、.rest:更高的位数最大值为j,将10^(i-1)-k变成<=0的最少步数step、变后的数字为-rest(1<=k<=9)

  g[i].step、.rest:将n的最低i位变成<=0的最少步数step、变后的数字为-rest

  然后转移的时候其实就是调若干次f数组,每次把当前位的数字-1。需要特判.rest等于0的情况。具体见代码吧。

 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#include<cstdlib>
#include<bitset>
//#include<ctime>
#define ll long long
#define ull unsigned long long
#define ui unsigned int
#define d double
//#define ld long double
using namespace std;
const int maxn=;
struct zs{ll step;int rest;}f[][][],g[];
int s[],premx[];
//int ff[233333];ll ten[23];
int i,j,k,n,m; int ra,fh;char rx;
inline int read(){
rx=getchar(),ra=,fh=;
while((rx<''||rx>'')&&rx!='-')rx=getchar();
if(rx=='-')fh=-,rx=getchar();
while(rx>=''&&rx<='')ra=ra*+rx-,rx=getchar();return ra*fh;
}
inline int max(int a,int b){return a>b?a:b;}
/*
inline void vio(){
for(i=1;i<=9;i++)ff[i]=1;
for(i=10;i<233333;i++){
int mx=0,j=i;
while(j)mx=max(mx,j%10),j/=10;
ff[i]=ff[i-mx]+1;
// if(i<30)printf("%d %d\n",i,ff[i]);
}
}*/
int main(){
// vio();
ll n;
scanf("%lld",&n);int len=;
if(!n)return puts(""),;
for(ll x=n;x;x/=)s[++len]=x%;
for(i=/*ten[0]=*/;i<=len;i++)premx[i]=max(premx[i-],s[len-i+]);//,ten[i]=ten[i-1]*10; for(i=;i<=;i++)for(j=;j<;j++)f[][i][j]=(zs){,max(,i-(-j))};
g[]=(zs){,premx[len]-s[]}; register int digit,nrest;ll nstep;zs tmp;
for(i=;i<=len;i++){
if(i<len){
for(j=;j<=;j++)for(k=;k<;k++){
for(digit=,nstep=,nrest=k;digit>=;digit--){
tmp=f[i-][max(j,digit)][nrest],
nstep+=tmp.step,nrest=tmp.rest;
if(!nrest&&digit)nstep++,nrest=max(j,digit);
}
f[i][j][k]=(zs){nstep,nrest};
//if(!j)printf("%d %d %d (%lld,%d) ff:%d\n",i,j,k,f[i][j][k].step,f[i][j][k].rest,ff[ten[i]-k]);
}
} nstep=g[i-].step,nrest=g[i-].rest;
if(!nrest&&s[i])nstep++,nrest=premx[len-i+];
for(digit=s[i]-;digit>=;digit--){
tmp=f[i-][max(premx[len-i],digit)][nrest],
nstep+=tmp.step,nrest=tmp.rest;
if(!nrest&&digit)nstep++,nrest=max(premx[len-i],digit);
}
g[i]=(zs){nstep,nrest};
}//printf("%lld %d\n",g[len].step,ff[n]);
printf("%lld\n",g[len].step);
}

[51nod1425]减减数的更多相关文章

  1. 小巧实用的数字加减插件(jquery插件)

    2015-12-04 近期项目需要,我将插件更新了,增加了两个参数,一个参数控制文本框是否支持输入,另一个参数则是新增了一个回调函数,返回文本框内的值.另外对代码局部重构了,优化了一下封装,需要的朋友 ...

  2. jQuery数字加减插件

    jQuery数字加减插件 我们在网上购物提交订单时,在网页上一般会有一个选择数量的控件,要求买家选择购买商品的件数,开发者会把该控件做成可以通过点击实现加减等微调操作,当然也可以直接输入数字件数.本文 ...

  3. 大整数加减运算的C语言实现

    目录 大整数加减运算的C语言实现 一. 问题提出 二. 代码实现 三. 效果验证 大整数加减运算的C语言实现 标签: 大整数加减 C 一. 问题提出 培训老师给出一个题目:用C语言实现一个大整数计算器 ...

  4. C语言实现用位移运算符进行加减乘…

      最近,在百度知道上回答问题,然后看见有的人问如何用位移运算符去进行加减乘除运算,于是巩固今天就在这总结一下.   先讲讲总体思路: 加法运算:将一个整数用二进制表示,其加法运算就是:相异(^)时, ...

  5. C语言复习---获取最大公约数(辗转相除法和更相减损法)

    源自:百度百科 辗转相除法 辗转相除法:辗转相除法是求两个自然数的最大公约数的一种方法,也叫欧几里德算法. 例如,求(,): ∵ ÷=(余319) ∴(,)=(,): ∵ ÷=(余58) ∴(,)=( ...

  6. JavaScript大位数相加减

    function arrayAdd(number, addNumber) { var numberArr = number.toString().split(''); var addNumberArr ...

  7. JavaScript 加减危机——为什么会出现这样的结果?

    在日常工作计算中,我们如履薄冰,但是 JavaScript 总能给我们这样那样的 surprise~ 0.1 + 0.2 = ? 1 - 0.9 = ? 如果小伙伴给出内心的结果: 0.1 + 0.2 ...

  8. Python_列表相减(判断长度后长的减短的)

    #定义一个方法,可进行列表相减 class V(object): def __init__(self,*value): self.value=value def __sub__(self,other) ...

  9. 笔记:如何使用postgresql做顺序扣减库存

    如何使用postgresql做顺序扣减库存 Ⅰ.废话在前面 首先这篇笔记源自于最近的一次需求,这个临时性需求是根据两份数据(库存数据以及出库数据) 算出实际库存给到业务,至于库存为什么不等于剩余库存, ...

随机推荐

  1. ES6之遍历器(Iterator)

    什么是Iterator?他是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署上Iterator接口就可以完成遍历操作(PS:个人认为他的这个遍历就是c语言里面的指针),他的作用有 ...

  2. iOS知识点、面试题 之二

    最近面试,与大家分享一下,分三文给大家: 当然Xcode新版本区别,以及iOS新特性 Xcode8 和iOS 10 在之前文章有发过,感兴趣的可以查阅: http://www.cnblogs.com/ ...

  3. Python学习日记:day9--------函数

    初识函数 1,自定义函数 s ='内容' #自定义函数 def my_len():#自定义函数没有参数 i =0 for k in s: i+=1 print(i) return i #返回值 my_ ...

  4. 实现WebSocket和WAMP协议的开源库WampSharp

    Websocket Application Messaging Protocol 协议:https://github.com/wamp-proto/wamp-proto 1. 基础档案 引入: WAM ...

  5. ArcGIS 网络分析[8.4] 资料4 聚合——创建及打开网络数据集的类实现

    这篇是对前三篇的总结,因为网络数据集涉及的"点"太多了,我只能挑重点来设置,大家明白框架后可以自行寻求帮助文档添加功能. 我以C#类的形式给出,这个类包含很多种方法,因为本人的C# ...

  6. bzoj 4872: [Shoi2017]分手是祝愿

    Description Zeit und Raum trennen dich und mich. 时空将你我分开.B 君在玩一个游戏,这个游戏由 n 个灯和 n 个开关组成,给定这 n 个灯的初始状态 ...

  7. php-迭代创建级联目录

    方法一代码: path = './a/b/c/d/e/f'; $path_arr = explode('/',$path);//得到数组array('.','a','b','c','d','e','f ...

  8. ubuntu 编译运行 opencv C++ 项目

    ubuntu 编译运行 opencv C++ 项目 环境 ubuntu 16.04 opencv3.4.0 一. 编译方法 1)命令行 g++ imageResize.cpp -o resize `p ...

  9. 再谈javascript面向对象编程

    前言:虽有陈皓<Javascript 面向对象编程>珠玉在前,但是我还是忍不住再画蛇添足的补上一篇文章,主要是因为javascript这门语言魅力.另外这篇文章是一篇入门文章,我也是才开始 ...

  10. 动态求区间K大值(权值线段树)

    我们知道我们可以通过主席树来维护静态区间第K大值.我们又知道主席树满足可加性,所以我们可以用树状数组来维护主席树,树状数组的每一个节点都可以开一颗主席树,然后一起做. 我们注意到树状数组的每一棵树都和 ...