URAL1353---Milliard Vasya's Function(简单数位dp)

Vasya is the beginning mathematician. He decided to make an important contribution to the science and to become famous all over the world. But how can he do that if the most interesting facts such as Pythagor’s theorem are already proved? Correct! He is to think out something his own, original. So he thought out the Theory of Vasya’s Functions. Vasya’s Functions (VF) are rather simple: the value of the Nth VF in the point S is an amount of integers from 1 to N that have the sum of digits S. You seem to be great programmers, so Vasya gave you a task to find the milliard VF value (i.e. the VF with N = 109) because Vasya himself won’t cope with the task. Can you solve the problem?

Input

Integer S (1 ≤ S ≤ 81).

Output

The milliard VF value in the point S.

Sample

input output

1

10

知道数位dp的应该都会做

dp[i][j] i位数,和为j的数个数

/*************************************************************************
    > File Name: URAL1353.cpp
    > Author: ALex
    > Mail: [email protected]
    > Created Time: 2015年05月19日 星期二 21时27分23秒
 ************************************************************************/

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <queue>
#include <stack>
#include <map>
#include <bitset>
#include <set>
#include <vector>

using namespace std;

const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const double eps = 1e-15;
typedef long long LL;
typedef pair <int, int> PLL;

int dp[15][100];
int bit[15];

int dfs(int now, int sum, bool flag) {
    if (now == -1) {
        return sum == 0;
    }
    if (!flag && ~dp[now][sum]) {
        return dp[now][sum];
    }
    int ans = 0;
    int end = flag ? bit[now] : 9;
    for (int i = 0; i <= end; ++i) {
        if (sum >= i) {
            ans += dfs(now - 1, sum - i, flag && i == end);
        }
    }
    if (!flag) {
        dp[now][sum] = ans;
    }
    return ans;
}

int main() {
    memset(dp, -1, sizeof(dp));
    int s;
    int n = 1e9;
    int cnt = 0;
    while (n) {
        bit[cnt++] = n % 10;
        n /= 10;
    }
    while (cin >> s) {
        printf("%d\n", dfs(cnt - 1, s, 1));
    }
    return 0;
}

URAL1353---Milliard Vasya's Function(简单数位dp)

时间: 2024-11-14 17:35:48

URAL1353---Milliard Vasya's Function(简单数位dp)的相关文章

URAL1353——DP——Milliard Vasya&#39;s Function

Description Vasya is the beginning mathematician. He decided to make an important contribution to the science and to become famous all over the world. But how can he do that if the most interesting facts such as Pythagor’s theorem are already proved?

Ural 1353 Milliard Vasya&#39;s Function(DP)

题目地址:Ural 1353 定义dp[i][j],表示当前位数为i位时,各位数和为j的个数. 对于第i位数来说,总可以看成在前i-1位后面加上一个0~9,所以状态转移方程就很容易出来了: dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i][j-2]+.......+dp[i][j-9]: 最后统计即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <

递推DP URAL 1353 Milliard Vasya&#39;s Function

题目传送门 1 /* 2 题意:1~1e9的数字里,各个位数数字相加和为s的个数 3 递推DP:dp[i][j] 表示i位数字,当前数字和为j的个数 4 状态转移方程:dp[i][j] += dp[i-1][j-k],为了不出现负数 5 改为:dp[i][j+k] += dp[i-1][j] 6 */ 7 #include <cstdio> 8 #include <cstring> 9 #include <cmath> 10 #include <algorithm

URAL 1353 Milliard Vasya&#39;s Function DP

题目:click here 分析:dp[i][j] 表示i位数字,当前数字和为j的个数.dp[i][j] = dp[i-1][j] + dp[i-1][j-k] 前面表示在i-1位数后面加零,后面表示在前一位前面加k这个数.(注意k的取值范围). 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int s; 5 int dp[11][83]; 6 int cnt[83]; 7 void pre() { 8 memset( dp, 0,

timus.1353. Milliard Vasya&#39;s Function 动态规划

题目传送门 题目大意: 输入一个1到81(9*9)的数字s,求在1到109有多少个数字的数位和等于s. 解题思路: 我们很容易知道一位数字等于s的个数.要使一个i位的数字数位和等于s,可以通过一个i-1位的数字后面加上0~9(如果s<9就是0~s).于是很容易得出方程 dp[i][j]=dp[i-1][j-0]+dp[i-2][j-1]+……+dp[i-9][j-9];其中i表示i位的数字,j表示s.dp[i][j]表示一个i位数字数位和为j的方案数. #include <iostream&g

ural 1353. Milliard Vasya&#39;s Function

点击打开链接 1353. Milliard Vasya's Function Time limit: 1.0 second Memory limit: 64 MB Vasya is the beginning mathematician. He decided to make an important contribution to the science and to become famous all over the world. But how can he do that if the

HDU 2089 简单数位dp

1.HDU 2089  不要62    简单数位dp 2.总结:看了题解才敲出来的,还是好弱.. #include<iostream> #include<cstring> #include<cstdio> using namespace std; int dp[10][11]; //dp[i][j]表示以j为首位符合条件的i位数的个数 void init() //预处理 { memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1

windy数(简单数位DP)

1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 6306  Solved: 2810[Submit][Status][Discuss] Description windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道,在A和B之间,包括A和B,总共有多少个windy数? Input 包含两个整数,A B. Output 一个整数 Sample I

[HDOJ6156] Palindrome Function(数位dp, 枚举)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6156 题意:算十进制下数字在[L,R]内用[l,r]进制表述下的数字贡献. 贡献有两种:回文数,贡献是进制k:不是回文数,贡献是1. 由于进制只有36个,枚举进制分别做统计回文数的数位dp即可,贡献按要求. 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int maxn = 1