【动态规划】 nyoj269 VF

来源:互联网 发布:淘宝怎么导出订单信息 编辑:程序博客网 时间:2024/04/30 05:24

题目链接:VF


起初看到题的时候看半天没理解什么意思,后来才理解题意是,给你一个S (1~81)让求出1~10^9之间所有数中各位数字之和等于S的数的个数,知道题意也知道是动态规划,可是自己还是没推出状态转移方程式,也是看了博客才恍然大悟,
1、当s=1时,10^9的系数才能为1,否则就大于10^9。所以和为1的时候要单一特判下。
2、如果s!=1  定义状态dp[i][j]为前i位各位数之和为j的情况的数量:对于前i位的数字之和最大为9*i,即每一位数字都是9。
只有一位数字的时候,因为s>=1,所以最低位只能是1-9其中的一个数字。
假设第i位放数字k(则k只能是0~9并且k<=s),若要使第前i位数字之和为j,那么前i-1位只能放j-k,由此得出动态转移方程:d[i]][j]=d[i][j]+d[i-1][j-k] (0<=k<=j&&k<=9)。


#include<stdio.h>#include<string.h>int dp[15][85];//dp[i][j]为前i位各位数之和为j的情况数量int main(){    for(int i=1;i<=9;i++)    {        dp[1][i]=1;    }    for(int i=1;i<=9;i++)    {        for(int j=1;j<=9*i;j++)        {            for(int k=0;k<=9&&k<=j;k++)            dp[i][j]+=dp[i-1][j-k];//假设第i位放数字k(则k只能是0~9并且k<=s),若要使第前i位数字之和为j,那么前i-1位只能放j-k.          }    }    int s;    while(~scanf("%d",&s))    {    if(s==1)    {        printf("10\n");    }    else    {        int ans=0;        for(int i=1;i<=9;i++)        {            ans+=dp[i][s];        }        printf("%d\n",ans);    }    }}


0 0
原创粉丝点击