NYOJ_269_VF

个人觉得DP最烦的就是确定初始边界,比如说这题,求10^9的数内各个数位相加的和中有多少个数的数位和等于S

初始条件:dp[0][j]=1   j=1、2…9

状态转移方程:

dp[i][j]表示:和为i,不超过j个数相加的符合条件的数有多少个

dp[i][j]=sum{dp[i-k][j-1]  k=0、1…9}

#include<iostream>

#include<cstdio>

#include<algorithm>

#include<cmath>

#include<cstring>

#include<string>

using namespace std;

int main()

{

    int i,j,k,dp[89][30]={0},n;

 for(i=0;i<12;++i)

     dp[0][i]=1;

 for(i=1;i<82;++i)

     for(j=1;j<10;++j) //10^9,只需要算9位就好了

         for(k=0;k<10&&i-k>=0;++k) //k表示第j位为k

         {

             if(dp[i-k][j-1]) //如果前面的数位能组合成和i-k

             dp[i][j]+=dp[i-k][j-1];

         }

 while(~scanf("%d",&n))

 {

     if(n==1)  //特判一下

         printf("10\n");

     else printf("%d\n",dp[n][9]);

 }

 return 0;

}

 

你可能感兴趣的:(OJ)