HDU3555 常规数位dp入门....

Problem Description
The counter-terrorists found a time bomb in the dust. But this time the terrorists improve on the time bomb. The number sequence of the time bomb counts from 1 to N. If the current number sequence includes the sub-sequence “49”, the power of the blast would add one point.
Now the counter-terrorist knows the number N. They want to know the final points of the power. Can you help them?

Input
The first line of input consists of an integer T (1 <= T <= 10000), indicating the number of test cases. For each test case, there will be an integer N (1 <= N <= 2^63-1) as the description.

The input terminates by end of file marker.

Output
For each test case, output an integer indicating the final points of the power.

Sample Input
3
1
50
500

Sample Output
0
1
15

WA到我怀疑人生………..
各种迷之WA
先写一下这个玩意要注意的东西吧…..
第一个是边界问题
第二个是标记问题….
其实就是一个问题….
到边界的时候不能xjb记录….
就不能记录….
如果不是边界那么就可以记忆化….
讲道理
其实我也不知道为什么…..
突然加了个可有可无的条件就这么过了….
满脸嘎嘎嘎…
要是懂了再补上

补充:找到原因了…biaoji==0这个条件并不是可有可无的
虽然确实biaoji==0的时候最大一定是bte[chang]但是有一种例外
那就是bte[chang]==9的情况,这样的话if和else两个条件都没有区别…就不知道会发生些什么了……..传给后面1和0都对…对后面的结果会有影响…….但是边界为什么不能记忆化我还没想到…想到再补充

补充:边界确实不能记忆化,因为边界的记忆化也只能对应边界的记忆化,而实际上dp数组里边装的根本不是对应边界值得记忆化,所以就不对

#include
#include
#include
using namespace std;
long long  dp[50][50][3], bte[20], n;
long long dfs(long long chang, long long zhuangtai, long long biaoji,long long shiji)
{
    if (dp[chang][shiji][zhuangtai] != -1&&biaoji!=0)return dp[chang][shiji][zhuangtai];
    if (chang == 0)
    {
        if (zhuangtai == 2)return dp[chang][shiji][zhuangtai] = 1;
        else return dp[chang][shiji][zhuangtai] = 0;
    }
    long long bianjie = biaoji ? 9 : bte[chang];//这是边界,比如85712,最高位是8,第二位最大就不能是9 
    long long sum = 0;
    for (long long a = 0;a <= bianjie;a++)
    {
        if (zhuangtai == 2 || (zhuangtai == 1 && a == 9))
        {
            if (a == bianjie&&bianjie == bte[chang]&&biaoji==0)sum += dfs(chang - 1, 2, 0,a);
            else sum += dfs(chang - 1, 2, 1,a);
        }
        else
        {
            if (a == 4)
            {
                if (a == bianjie&&bianjie == bte[chang]&&biaoji==0)sum += dfs(chang - 1, 1, 0,a);
                else sum += dfs(chang - 1, 1, 1,a);
            }
            else
            {
                if (a == bianjie&&bianjie == bte[chang]&&biaoji==0)sum += dfs(chang - 1, 0, 0,a);
                else sum += dfs(chang - 1, 0, 1,a);
            }
        }
    }
    if(biaoji)dp[chang][shiji][zhuangtai]=sum;
    return  sum;
}
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        memset(dp, -1, sizeof(dp));
        bte[0]=0;
        scanf("%lld",&n);
        long long q = n;
        while (q)
        {
            bte[++bte[0]] = q % 10;
            q /= 10;
        }
       printf("%lld\n",dfs(bte[0],0,0,0));
    }
    return 0;
}

你可能感兴趣的:(ACM练习,动态规划)