• ABC155E


    简述题意,给你一个大数,你可以选择10的次幂进行加减运算,问如何用最少的次数从0到达这个大数

    考虑从这个大数到0,从最低位开始,每次都将这个位置取完,2种策略,贪心的话不好处理进位的情况,可以想到是DP

    设dp[i][0]为取到第i位,将第i位直接拿完的最小次数,dp[i][1]为取到第i位,进位后拿完的最小次数,可以得到状态转移,num表示第i位的数字

    dp[i][0] = min(dp[i-1][0], dp[i-1][1]+1) + num,dp[i-1][1]-1表示进了一位,所以第i位就要+1

    dp[i][1] = 10 - num + min(dp[i-1][0], dp[i-1][1]-1)  同理,dp[i-1][1]进了一位,num相当于(num+1), 10-(num+1) = 10 - num - 1

    注意初始化状态,最终取答案的时候要在最高位的下一位统计,因为最高位可能也进位了,相当于放了一个虚0

    #include<bits/stdc++.h>
    using namespace std;
    #define lowbit(x) ((x)&(-x))
    typedef long long LL;
    
    const int maxm = 1e6+5;
    int dp[maxm][2];
    
    void run_case() {
        string str;
        cin >> str;
        dp[str.size()-1][1] = str[str.size()-1]-'0';
        dp[str.size()-1][0] = 10 - str[str.size()-1] +'0';
        for(int i = str.size()-2; i >= 0; --i) {
            int num = str[i]-'0';
            dp[i][1] = min(dp[i+1][0]+1, dp[i+1][1]) + num;
            dp[i][0] = 10 - num + min(dp[i+1][0]-1, dp[i+1][1]);
        }
        cout << min(dp[0][0]+1, dp[0][1]);
        
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        //cout.setf(ios_base::showpoint);cout.precision(8);
        run_case();
        cout.flush();
        return 0;
    }
    View Code

    我们也可以从最高位开始,dp函数的意义相同,只是状态转移的部分不一样

    dp[i][0] = min(dp[i+1][0], dp[i+1][1]) + num

    dp[i][1] = 10 - num + min(dp[i+1][0]+1, dp[i+1][1]-1) 第i位进位了,所以dp[i+1][0]要+1, 进了位dp[i+1][1]要-1

    #include<bits/stdc++.h>
    using namespace std;
    #define lowbit(x) ((x)&(-x))
    typedef long long LL;
    
    const int maxm = 1e6+5;
    int dp[maxm][2];
    
    void run_case() {
        string str;
        cin >> str;
        dp[0][0] = str[0] - '0';
        dp[0][1] = 10 - str[0] + '0' + 1;
        for(int i = 1; i < str.size(); ++i) {
            int num = str[i] - '0';
            dp[i][0] = min(dp[i-1][0], dp[i-1][1]) + num;
            dp[i][1] = 10 - num + min(dp[i-1][0]+1, dp[i-1][1]-1);
        }
        cout << min(dp[str.size()-1][0], dp[str.size()-1][1]);
    }
    
    int main() {
        ios::sync_with_stdio(false), cin.tie(0);
        //cout.setf(ios_base::showpoint);cout.precision(8);
        run_case();
        cout.flush();
        return 0;
    }
    View Code

    注意代码中的i+1与i-1是相反的,因为字符串读入下标是反的

     该题的母题应该是cf gym的一套题

    ArabellaCPC 2019 J. Thanos Power

  • 相关阅读:
    Quicksum -SilverN
    uva 140 bandwidth (好题) ——yhx
    uva 129 krypton factors ——yhx
    uva 524 prime ring problem——yhx
    uva 10976 fractions again(水题)——yhx
    uva 11059 maximum product(水题)——yhx
    uva 725 division(水题)——yhx
    uva 11853 paintball(好题)——yhx
    uva 1599 ideal path(好题)——yhx
    uva 1572 self-assembly ——yhx
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/12323390.html
Copyright © 2020-2023  润新知