ABC155E - Payment

懵懂的女人 提交于 2020-02-17 21:52:33

简述题意,给你一个大数,你可以选择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是相反的,因为字符串读入下标是反的

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!