• bzoj 1111


    Description

    给定 1000的十进制数, 求 最小的 四幂拆分 方案 有多少种

    Solution

    先大除法 (nlog_4(n))次取余转化为 四进制数.
    然后从 低位 往 高位 (dp) .
    (f[i]) 表示不往上借位的最小代价.
    (g[i]) 表示往上借位的最小代价(被借的位的代价先不计算).
    那么最后答案为 (f[n]+(g[n]+1)) (可以往更高位再借 (1)).

    转移为
    (f[i] = min(f[i-1] + a[i], g[i-1] + a[i] + 1))
    (g[i] = min(f[i-1] + 4 - a[i], g[i - 1] + 3 - a[i]))

    边界为
    先去掉最低位的所有 (0) , 然后 (f=0,g=inf).

    因为要求方案, 所以在 (f,g) 维护二元组 ((cost.ways)) 即可

    Code

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    #include <iostream>
    #include <cassert>
    #define rep(i, a, b) for (int i = (a); i <= (b); ++ i)
    #define per(i, a, b) for (int i = (a); i >= (b); -- i)
    #define For(i, a, b) for (int i = (a); i < (b); ++ i)
    #define foreach(it, c) for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++ it)
    #define fore(e, x, y) for (int ep = e(x), y = e[ep].y; ep; y = e[ep = e[ep].nxt].y)
    using namespace std;
    const int N = 1e3 + 7;
    const int M = 2e3 + 7;
    const int INF = 1e9 + 7;
    const int Mod = 1e9;
     
    inline int pls(int x, int y) {return (x + y) % Mod;}
    inline int mns(int x, int y) {return pls(x, Mod - y);}
    inline int mul(int x, int y) {return 1LL * x * y % Mod;}
    inline int Add(int &x, int y) {return x = pls(x, y);}
     
    int n, m;
    char s[N];
    int b[N], a[M];
     
    struct rec {
        int cost, ways;
     
        inline rec operator + (const rec &v) {
            if (cost == v.cost) {return (rec){cost, pls(ways, v.ways)};}
            else return cost < v.cost ? *this : v;
        }
     
        inline rec operator + (const int d) const {
            return (rec){cost + d, ways};
        }
    }f[M], g[M];
     
    int main() {
    #ifndef ONLINE_JUDGE
        freopen("a.in", "r", stdin);
    #endif
     
        scanf("%s", s+1);
        n = strlen(s+1);
     
        rep (i, 1, n) b[i] = s[i] - '0';
        reverse(b+1, b+n+1);
         
        while (n > 0) {
            int res = 0;
            per (i, n, 1) {
                int d = res * 10 + b[i];
                b[i] = d / 4;
                res = d % 4;
            }
            while (n > 0 && b[n] == 0) --n;
            a[++m] = res;
        }
     
        int bg;
        rep (i, 1, m) if (a[i] != 0) {bg = i; break;}
     
        f[bg - 1] = (rec){0, 1}; g[bg - 1] = (rec){INF, 0};
        rep (i, bg, m + 1) {
            f[i] = (f[i - 1] + a[i]) + (g[i - 1] + (a[i] + 1));
            g[i] = (f[i - 1] + (4 - a[i])) + (g[i - 1] + (3 - a[i]));
        }
     
        printf("%d
    ", f[m + 1].ways);
     
        return 0;
    }
    
  • 相关阅读:
    [WPF系列] window自定义
    [WPF系列]-Prism+EF
    C#基础-事件 继承类无法直接引发基类的事件
    [WPF系列] 高级 调试
    [WPF系列]-DynamicResource与StaticResource的区别
    [WPF系列]-DataBinding 绑定计算表达式
    [WPF系列]- Style
    [WPF系列]-基础 TextBlock
    [WPF系列]-ListBox
    [WPF系列]-DataBinding 枚举类型数据源
  • 原文地址:https://www.cnblogs.com/acha/p/7721712.html
Copyright © 2020-2023  润新知