51Nod 1009 数字1的数量 数位dp

51Nod 1009 传送门

模板orz 好难记的感觉……

#include<iostream>  
#include<algorithm>
#include<string>
#include<string.h>
typedef long long ll;
using namespace std;
ll n, res;
ll dp[20];
void init()
{
    memset(dp, 0, sizeof(dp));
    for (int i = 1; i <= 10; i++)
        dp[i] = dp[i - 1]*10 + pow(10, i - 1);
}
ll DP(ll n)
{
    ll ans = 0, len = 0, crt = 0;
    ll l = 0, r = 1;
    while (n)  //比如n=12345,当前计算到crt=3 
    {
        crt = n % 10; 
        n /= 10;
        len++; //len为数位,len=3,r=100
        if (crt > 1)
            ans += r + crt*dp[len - 1]; //前导1产生r个+其余的crt*dp[len-1]个(当前位前导1产生100个,其余位前导(1,2,3)产生3*dp[2]个)
        else if (crt == 1)
            ans += l + 1 + dp[len - 1]; //高位1产生l+1个+其余的dp[len-1]个
        l += crt*r; //l表示当前计算到的数,比如12345,当前计算到crt=3,l=345;
        r *= 10;    //r=1000
    }
    return ans;
}
int main()
{
    init();
    scanf("%d", &n) ;
    printf("%lld
", DP(n));
    return 0;
}
原文地址:https://www.cnblogs.com/Egoist-/p/7628965.html