• HDU 3709: Balanced Number (数位DP)


    类型:数位DP

    题意:定义平衡数为:以某位数为中心,左边的每位数*这个数离中心的距离 == 右边的每位数*这个数离中心的距离。问[x,y]之间有多少平衡数

    思路:

    做的莫名奇妙……

    定义:dp[i][d][k][b] 为 首位为d的i位数,以第k位为中心点,平衡因子为b的数的个数。平衡因子定义为,中心点右边的和-中心点左边的和。

    实际上这个状态定义冗余了。不需要定义首位d,同时,平衡因子如果定义成,之前所有数的加权和为b,那就不有写这么复杂了。

    唉,现在有点乱。理不清楚啊。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define BB 1000
    using namespace std;
    
    long long dp[20][10][20][BB+BB];
    int num[30];
    
    long long dfs(int i, int d, int k, int b, bool isQuery) {
        #ifdef _D
        printf("(%d,%d,%d,%d,%d)
    ", i, d, k, b, isQuery);
        #endif
        if (k < 0) return 0;
        if (k >= BB+BB) return 0;
        long long &nowdp = dp[i][d][k][b];
        if (!isQuery && dp[i][d][k][b] != -1) {
            #ifdef _D
            printf("(%d,%d,%d,%d,%d)  ", i, d, k, b, isQuery);
            printf("return %d
    ", ((i-k)*d+BB == b));
            #endif
            return dp[i][d][k][b];
        }
        if (i == 1) {
            #ifdef _D
            printf("(%d,%d,%d,%d,%d)  ", i, d, k, b, isQuery);
            printf("return %d
    ", ((i-k)*d+BB == b));
            #endif
            return nowdp = ((i-k)*d+BB == b);
        }
        long long ans = 0;
        int nextB = b-(i-k)*d;
        int end = isQuery?num[i-1]:9;
        for (int j = 0; j <= end; j++) {
            ans += dfs(i-1, j, k, nextB, isQuery && j==end);
        }
        if (!isQuery) nowdp = ans;
        #ifdef _D
        printf("(%d,%d,%d,%d,%d)  ", i, d, k, b, isQuery);
        printf("return %d
    ", ans);
        #endif
        return ans;
    }
    
    long long cal(long long x) {
        if (x == -1) return 0;
        int len = 0;
        if (x == 0) {
            num[++len] = 0;
        } else {
            while (x) {
                num[++len] = x%10;
                x /= 10;
            }
        }
        long long ans = 0;
        for (int i = 1; i <= len; i++) {
            ans += dfs(len+1, 0, i, BB, true);
        }
        ans -= len-1; // 每种平衡点,都会算一次0这个数
        return ans;
    }
    
    int Nmain() {
        long long x;
        memset(dp, -1, sizeof(dp));
        //while (cin>>x) {
        long long pre = -1;
        for (int i = 0; i < 9999999; i++) {
            x = i;
            if (cal(x) >  pre+1) {
                cout<<x<<endl;
                pre = cal(x);
                getchar();
            }
            pre = cal(x);
        }
        return 0;
    }
    
    int main() {
        int t;
        scanf("%d", &t);
        memset(dp, -1, sizeof(dp));
        while (t--) {
            long long x, y;
            cin>>x>>y;
            cout<<cal(y)-cal(x-1)<<endl;
        }
        return 0;
    }
  • 相关阅读:
    Java WEB 之页面间传递特殊字符
    c++ using Handle Class Pattern to accomplish implementation hiding
    c++ simple class template example: Stack
    c++ why can't class template hide its implementation in cpp file?
    c++ what happens when a constructor throws an exception and leaves the object in an inconsistent state?
    c++ 用namespace实现java的package的功能
    c++ virtual 和 pure virtual的区别
    c++ istream(ostream)是如何转换为bool的
    c++ 使用boost regex库 总结
    c++ 如何使用第三方的library
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3597505.html
Copyright © 2020-2023  润新知