标签:
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