您的位置:首页 > 其它

HDU3555——Bomb(数位DP)

2014-07-23 10:12 211 查看
递推式:

<span style="font-size:18px;">#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
typedef __int64 LL;
using namespace std;
LL dp[25][3];
void Init()
{
    memset(dp,0,sizeof dp);
    dp[0][0]=1;
    for(int i=1;i<=20;i++){
        dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
        dp[i][1]=dp[i-1][0];
        dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
    }
}
int main()
{
    Init();
    int t;
    cin>>t;
    while(t--){
        LL n;
        scanf("%I64d",&n);
        n++;
        int num[21],k=0;
        while(n){
            num[++k]=n%10;
            n/=10;
        }
        LL ans=0;
        int flag=0,pre=0;
        for(int i=k;i>=1;i--){
            ans+=dp[i-1][2]*num[i];
            if(!flag&&num[i]>4){
                ans+=dp[i-1][1];
            }
            if(flag){
                ans+=dp[i-1][0]*num[i];
            }
            if(pre==4&&num[i]==9){
                flag=1;
            }
            pre=num[i];

        }
        printf("%I64d\n",ans);
    }
    return 0;
}</span>


记忆化搜索式:

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef __int64 LL;

LL dp[20][3], N;

int num[20];

LL dfs(int pos, int statu, int limit)
{
    if (pos == -1) { // 如果到了已经枚举了最后一位,并且在枚举的过程中有49序列出现
        return statu == 2;
    }
    if (!limit && dp[pos][statu] != -1) return dp[pos][statu];  // 对于有限制的询问我们是不能够记忆化的
    LL sum = 0;
    int s, end = limit ? num[pos] : 9; // 确定这一位的上限是多少
    for (int i = 0; i <= end; ++i) { // 每一位有这么多的选择
        s = statu;
        if (statu == 1 && i == 9) s = 2;
        if (statu == 0 && i == 4) s = 1;
        if (statu == 1 && i != 4 && i != 9) s = 0;
        sum += dfs(pos-1, s, limit && i == end);
    }
    return limit?sum:dp[pos][statu]=sum;
}

LL Cal(LL n)
{
    int pos = 0;
    while (n != 0) {
        num[pos++] = n % 10;
        n /= 10;
    }
    return dfs(pos-1, 0, 1);
}

int main()
{
    int T;
    scanf("%d", &T);
    while (T--) {
        memset(dp, -1, sizeof (dp));
        scanf("%I64d", &N);
        printf("%I64d\n", Cal(N));
    }
    return 0;
}<span style="color:#ff0000;">
</span>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: