NYOJ VF(数位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?

输入

There are multiple test cases.

Integer S (1 ≤ S ≤ 81).

输出

The milliard VF value in the point S.

样例输入

1

样例输出

10

这一题数位dp,dp[i][j]表示这个数字有i位,以及各个位上数字的和为j。

则有dp[i][j]=dp[i-1][j-k]+dp[i][j](k>=0&&k<=9)

但是有一些两个细节要稍微处理一下:

(1)i最大就只枚举到9,因为虽然有10^9,这个数其实是有10位的,但是十位的刚好就只有这个数,所以单做特例处理一下,所以输入s==1时单独输出

(2)对i==1是单独判断一下,因为这个数是首位,是不允许为0的。所以就是1~9

AC代码:

# include <cstdio>
# include <cstring>
using namespace std;
int dp[20][90];
int main(){
	int s, i, j, k, ans;
	memset(dp, 0, sizeof(dp));
	for(j=1; j<=9; j++){
		dp[1][j]=1;
	}
	for(i=2; i<=9; i++){
		for(j=1; j<=9*i; j++){
			for(k=0; k<=9; k++){
				if(j>=k)
				dp[i][j]=dp[i-1][j-k]+dp[i][j];
			}
		}
	}
	while(scanf("%d", &s)!=EOF){
		if(s==1){
			printf("10\n");
			continue;
		}
		int ans=0;
		for(int i=1; i<10; i++){
			ans=ans+dp[i][s];
		}
		printf("%d\n", ans);
	}
	return 0;
}
时间: 2024-08-30 01:25:47

NYOJ VF(数位dp)的相关文章

nyoj VF函数

大意就是: 在1到在10的9次方中,找到各个位数和为固定值s的数的个数, 首先我们确定最高位的个数,为1到9: 以后的各位为0,到9: 运用递归的思想,n位数有n-1位数生成 f(n)(s) +=f(n-1)(s-k)(k=0~9) 可以学习背包问题,直接降到一维表示,注意规划方向,从高到底. package vf; import java.util.Scanner; public class Main { public static void main(String[] args) { //

URAL1353---Milliard Vasya&#39;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

51Nod 1009 数字1的个数 | 数位DP

题意: 小于等于n的所有数中1的出现次数 分析: 数位DP 预处理dp[i][j]存 从1~以j开头的i位数中有几个1,那么转移方程为: if(j == 1) dp[i][j] = dp[i-1][9]*2+pow(10,i-1);else dp[i][j] = dp[i-1][9]+dp[i][j-1]; 然后注意下对于每个询问统计的时候如果当前位为1需要额外加上他后面所有位数的个数,就是n%pow(10,i-1); 这样总复杂度log(n)*10 #include <bits/stdc++.

HDU 3555 Bomb (数位DP)

数位dp,主要用来解决统计满足某类特殊关系或有某些特点的区间内的数的个数,它是按位来进行计数统计的,可以保存子状态,速度较快.数位dp做多了后,套路基本上都差不多,关键把要保存的状态给抽象出来,保存下来. 简介: 顾名思义,所谓的数位DP就是按照数字的个,十,百,千--位数进行的DP.数位DP的题目有着非常明显的性质: 询问[l,r]的区间内,有多少的数字满足某个性质 做法根据前缀和的思想,求出[0,l-1]和[0,r]中满足性质的数的个数,然后相减即可. 算法核心: 关于数位DP,貌似写法还是

51nod1043(数位dp)

题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1043 题意:中文题诶- 思路:数位dp 我们用dp[i][j]来存储长度为2*i且一半和为j的所有情况(包括前导0的情况),为了方便我们现在只讨论其一半的和的情况,因为如果包括前导0的话其两边的情况是一样的: 我们假设再长度为i-1的数字最前面加1位数字k,0<=k<=9(这位数字加在哪里并不影响答案,因为我们在计算i-1长度的时候已经计算了所有组合情况,

数位dp

1.[hdu3709]Balanced Number 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<cstdlib> 6 #include<algorithm> 7 #include<ctime> 8 #include<cmath> 9 #include<queue>

【HDU 3652】 B-number (数位DP)

B-number Problem Description A wqb-number, or B-number for short, is a non-negative integer whose decimal form contains the sub- string "13" and can be divided by 13. For example, 130 and 2613 are wqb-numbers, but 143 and 2639 are not. Your task

hdu 5898 odd-even number 数位DP

odd-even number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 716    Accepted Submission(s): 385 Problem Description For a number,if the length of continuous odd digits is even and the length

LightOJ1068 Investigation(数位DP)

这题要求区间有多少个模K且各位数之和模K都等于0的数字. 注意到[1,231]这些数最大的各位数之和不会超过90左右,而如果K大于90那么模K的结果肯定不是0,因此K大于90就没有解. 考虑到数据规模,数据组数,这题状态这么表示: dp[i][j][k]:位数为i模K结果为j且各位数之和模K结果为k的数字个数 然后就是转移方程,最后就是统计.. 统计部分好棘手...半乱搞下AC的..还是对数位DP的这一部分太不熟悉了. 1 #include<cstdio> 2 #include<cstr