zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    头插法建立单链表
    顺序表
    栈的顺序存储实现
    折半查找
    myeclipe 快捷键盘
    ztree redio单选按钮
    webuploader上传进度条 上传删除
    svn乱码解决办法
    异构SOA系统架构之Asp.net实现(兼容dubbo)
    RPC框架
  • 原文地址:https://www.cnblogs.com/shinecheng/p/3597505.html
Copyright © 2011-2022 走看看