제출 #1339996

#제출 시각아이디문제언어결과실행 시간메모리
1339996notbrainingPotatoes and fertilizers (LMIO19_bulves)C++20
0 / 100
1 ms836 KiB
//https://oj.uz/problem/view/LMIO19_bulves
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<iomanip>
#include <cassert>
#include<algorithm>
#include<queue>
#include <array>
#include <bitset>
#include<cstring>
using namespace std;
#define int long long
#define pii pair<int,int>
int INF = 1e18;
int a[500001];
int n;
const int lol = 30000;
void ez(){
    int cur = 0;
    int ans = 0;
    for(int i = 1; i <= n; ++i){
        cur += a[i];
        ans += abs(cur);
    }
    cout << ans << "\n";
}
int dp[30001]; int dp2[30001];
void onedp(){
    vector<int>psums(n + 1, 0);
    for(int i = 1; i <= n; ++i){
        psums[i] = psums[i - 1] + a[i];
    }
    vector<vector<int>>dp(n + 2, vector<int>(2, INF)); //min cost to reach this state
    dp[1][1] = 0;
    for(int i = 1; i <= n; ++i){
        for(int j = 0; j <= 1; ++j){
            //if the psums is negative, you must transfer it all out (def not optimal to just drag it here)
            if(j == 1){
                //can choose to either transfer all or transfer not all
                dp[i + 1][1] = min(dp[i + 1][j], dp[i][j] + abs(psums[i]));
                if(psums[i] > 0){
                    dp[i + 1][0] = min(dp[i + 1][0], dp[i][j] + abs(psums[i]) - 1);
                }
            } else{
                dp[i + 1][0] = min(dp[i + 1][0], dp[i][0] + abs(psums[i] - 1));
            }
        }
    }
    cout << min(dp[n + 1][0], dp[n + 1][1]) << "\n";
}
void seconddp(){
    vector<int>psums(n + 1, 0);
    for(int i = 1; i <= n; ++i){
        psums[i] = psums[i - 1] + a[i];
    }
    //vector<vector<int>>dp(n + 2, vector<int>(2, INF)); //min cost to reach this state
    //state: from 1...i-1 is all 0, if j==1 then it has the total prefix sums here, otherwise, it has one less than the total prefix sums, (didn't transfer one)
    memset(dp, 0x3f, sizeof(dp));
    memset(dp2, 0x3f, sizeof(dp2));
    dp[0] = 0;
    for(int i = 1; i <= n; ++i){
        int smallest = INF;
        for(int j = 0; j <= lol; ++j){
            smallest = min(smallest, dp[j]);
            dp2[j] = min(dp2[j], smallest + abs(psums[i] - j));
        }
        swap(dp, dp2);
        memset(dp2, 0x3f, sizeof(dp2));
    }
    int ans = INF;
    for(int i = 0; i <= lol; ++i){
        ans = min(ans, dp[i]);
    }
    cout << ans << "\n";
}
int32_t main(){
    cin.tie(0)->sync_with_stdio(0);
    cin >> n;
    int sumA = 0;
    for(int i = 1; i <= n; ++i){
        int x, y; cin >> x >> y;
        a[i] = x - y;
        sumA += x - y;
    }
    if(sumA == 0){
        ez();
    }
    if(sumA == 1){
        onedp();
    } else{
        seconddp();
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...