timus 1353. Milliard Vasya's Function 解题报告 URAL

timus   1353. Milliard Vasya's Function   解题报告  URAL

一个函数,定义为输入s,输出1-N中各个位上的数之和为s的个数,n=10^9
这个题也是划归到DP一类里面,可是我对DP的状态转移貌似还是不清楚,没理解透,所以愣是没想出来,反正一碰到这种题我就向往排列组合上面想!
后来看了别人的思路才一下子豁然开朗,位数为i位时,能组成的位数和j也要考前一个转化而来,当前最高位可以为0,1,2,3,……9那么就是dp[i-1][j-k]  k是0--9,并且小于等于j
 初次之外还有边界需要处理!

{///这里的初始化很关键,dp[i][j]表示最多用i位,一共能组成多少个各位上的和是j的数
        dp[1][i]=1;
        dp[i][0]=1;///这一句加不加将会影响后面的判断,如果不加那么dp[i-1][0]直接等于0也就少几种情况首位自己贡献0-9的十种情况
    }///dp[10][1]=10;


AC代码
#include<stdio.h>
#include<iostream>
#include<cstring>
using namespace std;
int dp[11][90];
void init()
{
    memset(dp,0,sizeof(dp));
    for(int i=1; i<10; ++i)
    {///这里的初始化很关键,dp[i][j]表示最多用i位,一共能组成多少个各位上的和是j的数
        dp[1][i]=1;
        dp[i][0]=1;///这一句加不加将会影响后面的判断,如果不加那么dp[i-1][0]直接等于0也就少几种情况首位自己贡献0-9的十种情况
    }///dp[10][1]=10;

    for(int i=2; i<=9; ++i)
    {
        for(int j=1; j<=81; j++)
        {
            for(int k=9; k>=0; k--)if(j>=k) dp[i][j]+=dp[i-1][j-k];
        }
    }

}
int s;
int main ( )
{
    init();
    //cout<<dp[2][1]<<endl;
    while(scanf("%d",&s)!=EOF)
    {
        if(s==1)cout<<10<<endl;
       else cout<<dp[9][s]<<endl;
    }



    return 0;
}

timus   1353. Milliard Vasya's Function   解题报告  URAL
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值