标签:
1
10
题目大意:题中给出了N。每次询问给你一个s,问你从1--N中各个位之和为s的这样的数字有多少。
解题思路:定义状态:dp[i][j]表示前i位的和为j的这样的数有多少个。i的范围只需要1-9即可,因为N的值为1e9,即使你要找i为10的数,也只有1e9这个数,所以枚举i到10是无意义的。j的范围为1-i*9,因为i位最大的和就是i位都为9。需要枚举k,k表示在第i位需要加的数字,则状态转移方程为dp[i][j]=dp[i][j]+dp[i-1][j-k]。同时需要特殊处理边界,也是最容易出差错的地方。
#include<bits/stdc++.h> using namespace std; const int N=1e9; int dp[10][100]; int main(){ int s,i,j,k,sum; for(i=1;i<10;i++) //边界处理 dp[1][i]=1; for(i=1;i<10;i++){ for(j=1;j<=i*9;j++){ for(k=0;k<10&&j>=k;k++){ //枚举第i位值k dp[i][j]=dp[i][j]+dp[i-1][j-k]; } } } while(scanf("%d",&s)!=EOF){ if(s==1) printf("10\n"); else{ sum=0; for(i=1;i<10;i++) sum+=dp[i][s]; printf("%d\n",sum); } } return 0; }
标签:
原文地址:http://www.cnblogs.com/chengsheng/p/4523029.html