PAT 1049. Counting Ones (30)(数位dp(记忆化搜索))
2017-11-26 21:55
399 查看
The task is simple: given any positive integer N, you are supposed to count the total number of 1’s in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1’s in 1, 10, 11, and 12.
Input Specification:
Each input file contains one test case which gives the positive N (<=230).
Output Specification:
For each test case, print the number of 1’s in one line.
Sample Input:
12
Sample Output:
5
题意很好理解,求1到n这n个数其中1总共出现了多少次。
还是比较基础的数位dp,dp数组建议使用结构体,保存两个量,1出现了多少次和总共有多少个数。至于为什么呢,也是很好理解的,如果当前位不是1,那么总共出现的1的个数和当前位减一出现的1的个数相等,如果当前位是1,那么出现1的个数由两部分组成,当前位减一出现1的个数和从当前位开始总共有多少个数,因为如果当前位是1,那么前面只要存在一个数,那么1的总数就会加一。
详细见代码:
Input Specification:
Each input file contains one test case which gives the positive N (<=230).
Output Specification:
For each test case, print the number of 1’s in one line.
Sample Input:
12
Sample Output:
5
题意很好理解,求1到n这n个数其中1总共出现了多少次。
还是比较基础的数位dp,dp数组建议使用结构体,保存两个量,1出现了多少次和总共有多少个数。至于为什么呢,也是很好理解的,如果当前位不是1,那么总共出现的1的个数和当前位减一出现的1的个数相等,如果当前位是1,那么出现1的个数由两部分组成,当前位减一出现1的个数和从当前位开始总共有多少个数,因为如果当前位是1,那么前面只要存在一个数,那么1的总数就会加一。
详细见代码:
#include <iostream> #include <string> #include <cstring> #include <iomanip> #include <cmath> #include <cstdlib> #include <cstdio> #include <algorithm> #include <map> #include <stack> #include <queue> using namespace std; #define ll long long #define maxn 20 #define angel 0x3f3f3f3f #define eps 1e-9 const int mod=1e9+7; struct maths { ll cnt;//出现1的个数 ll sum;//总共多少个数 }dp[maxn]; int tmp[maxn]; maths dfs(int len,int flag) { if(len==0) { maths element; element.sum=1;element.cnt=0; return element; } if(!flag&&dp[len].sum!=-1) return dp[len]; int maxx=flag?tmp[len]:9; maths now; now.cnt=now.sum=0; for(int i=0;i<=maxx;i++) { maths next=dfs(len-1,i==maxx&&flag); if(i==1) now.cnt=now.cnt+next.cnt+next.sum; else now.cnt=now.cnt+next.cnt; now.sum+=next.sum; } if(!flag) dp[len]=now; return now; } ll solve(int n) { int len=0; while(n>0) { tmp[++len]=n%10; n/=10; } return dfs(len,1).cnt; } int main() { int n; scanf("%d",&n); memset(dp,-1,sizeof(dp)); printf("%lld\n",solve(n)); return 0; }
相关文章推荐
- PAT 1049 Counting Ones 数位dp
- 【PAT甲级】1049. Counting Ones (30)
- pat 1049. Counting Ones (30)
- PAT (Advanced Level) Practise 1049 Counting Ones (30)
- 【PAT】1049. Counting Ones (30)
- PAT 甲级 1049. Counting Ones (30)
- PAT 1049. Counting Ones (30)
- PAT 1049. Counting Ones (30)
- PAT (Advanced Level) 1049. Counting Ones (30) 1到N中1出现的次数
- PAT 1049. Counting Ones (30)
- PAT_A 1049. Counting Ones (30)
- PAT甲级 1049. Counting Ones (30)
- PAT 1049. Counting Ones (30)
- 1049. Counting Ones (30)【计算1 的个数】——PAT (Advanced Level) Practise
- PAT (Advanced Level) 1049. Counting Ones (30)
- 【PAT (Advanced Level)】1049. Counting Ones (30)
- PAT 1049. Counting Ones (30)
- PAT 1049. Counting Ones (30)
- PAT 1049. Counting Ones (30)(计算1到N,这些数字中1出现的个数,before i after,归纳)
- Python实现Pat 1049. Counting Ones (30)