confusion with a dp problem
Difference between en1 and en2, changed 55 character(s)
I was doing this problem: _____ and my approach to solving was to binary search on the time required, and the predicate for the search would be whether the time is enough -- determined by a DP check as follows: given some time t, we have w*t water and f*t fire available, so we try to use as much of the water as possible, and then see if enough fire remains. I don't understand why the following implementation of this idea does not work and was hoping someone could help:↵

~~~~↵
bool possible(vector<int>& s, int a, int b, int n, int t) {↵
    // s1 = size of container 1 (how much water we have)↵
    // s2 = size of container 2 (how much fire we have)↵
    int s1 = t*a, s2 = t*b;↵
    ↵
    // definition of dp[i][j][k]:↵
    // first i elements↵
    // using j of them↵
    // using or not using kth one↵
    // considering these i, j, k, what is the min space remaining in container 1?↵
    vector<vector<vector<int>>> dp(n+1, vector<vector<int>>(n+1, vector<int>(2, 1e15)));↵

    for (int i = 0; i <= n; i++) dp[i][0][0] = s1;↵

    for (int i = 1; i <= n; i++) {↵
        for (int j = 1; j <= i; j++) {↵
            dp[i][j][0] = min(dp[i-1][j][0], dp[i-1][j][1]);↵

            for (int k = i-1; k >= j-1; k--) {↵
                int op1 = ((dp[k][j-1][0] != 1e15 && dp[k][j-1][0] >= s[i-1]) ? dp[k][j-1][0] - s[i-1] : 1e15);↵
                int op2 = ((dp[k][j-1][1] != 1e15 && dp[k][j-1][1] >= s[i-1]) ? dp[k][j-1][1] - s[i-1] : 1e15);↵

                dp[i][j][1] = min({dp[i][j][1], op1, op2});↵
            }↵
        }↵
    }↵
    ↵
    int mn = s1;↵

    // take the min space left in container 1 across all possibilities↵
    for (int i = 0; i <= n; i++) {↵
        mn = min({mn, dp[n][i][0], dp[n][i][1]});↵
    }↵

    int sm = 0;↵
    ↵
    for (auto i : s) sm += i;↵
    ↵
    return (sm-(s1-mn) <= s2);↵
}↵

void solve() {↵
    int a, b, n;↵
    cin >> a >> b >> n;↵

    vector<int> s(n);↵

    for (int i = 0; i < n; i++) cin >> s[i];↵

    int curr = 0;↵
    ↵
    // binary searching on the time required ("curr")↵
    for (int p = 30; p >= 0; p--) {↵
        int pwp = (1ll<<p);↵

        while (curr+pwp <= 1e6 && !possible(s, a, b, n, curr+pwp)) curr += pwp;↵
    }↵

    cout << curr+1 << endl;↵
}↵
 ↵
signed main() {↵
    cin.tie(0)->sync_with_stdio(0);↵

    int t;↵
    cin >> t;↵
 ↵
    while (t--) {↵
        solve();↵
    }↵
}↵
~~~~

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en3 English ycperson 2025-01-16 18:43:07 53
en2 English ycperson 2025-01-16 18:41:50 55
en1 English ycperson 2025-01-16 18:40:33 2359 Initial revision (published)