CF2B

非常恶心的dp题,测试数据也恶心,坑多,特别是0的坑

#include <iostream>
#include <utility>
#include <string>
#include <algorithm>
using namespace std;
typedef long long ll;
#define fi(i, a, b) for (int i = a; i <= b; ++i)
#define fr(i, a, b) for (int i = a; i >= b; --i)
#define x first
#define y second
#define sz(x) ((int)(x).size())
#define pb push_back
using pii = pair<int, int>;
//#define DEBUG
int s[1005][1005];
int dp[1005][1005][2];
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    int flag = 0;
    int fx, fy;
    fi(i, 1, n) fi(j, 1, n)
    {
        cin >> s[i][j];
        if (s[i][j] == 0)
        {
            if (!flag)
            {
                flag = 1;
                fx = i;
                fy = j;
            }
            continue;
        }
        while (s[i][j] % 2 == 0)
        {
            s[i][j] /= 2;
            dp[i][j][0]++;
        }
        while (s[i][j] % 5 == 0)
        {
            s[i][j] /= 5;
            dp[i][j][1]++;
        }
    }
    fi(i, 1, n) fi(j, 1, n)
    {
        if (i == 1 && j == 1)
            continue;
        int p, q, r, ss, res1, res2;
        p = q = r = ss = 0x3f3f3f3f;
        if (s[i - 1][j] != 0)
        {
            p = dp[i][j][0] + dp[i - 1][j][0];
            q = dp[i][j][1] + dp[i - 1][j][1];
        }
        if (s[i][j - 1] != 0)
        {
            r = dp[i][j][1] + dp[i][j - 1][1];
            ss = dp[i][j][0] + dp[i][j - 1][0];
        }
        res1 = min(p, ss);
        res2 = min(q, r);
        if (res1 == 0x3f3f3f3f && res2 == 0x3f3f3f3f)
            continue;
        dp[i][j][0] = res1;
        dp[i][j][1] = res2;
    }
    int count = 0;
    // fi(i, 1, n) fi(j, 1, n)
    // {
    //     count++;
    //     cout << dp[i][j][0] << " " << dp[i][j][1] << " " << count << endl;
    // }
    string ans = "";
    int res = dp[n][n][0] > dp[n][n][1] ? 1 : 0;
    int i = n, j = n;
    while (1)
    {
        if (dp[i - 1][j][res] <= dp[i][j - 1][res])
        {
            if (s[i - 1][j] != 0)
            {
                i--;
                ans += "D";
            }
            else if (s[i][j - 1] != 0)
            {
                j--;
                ans += "R";
            }
        }
        else if (dp[i - 1][j][res] >= dp[i][j - 1][res])
        {
            if (s[i][j - 1] != 0)
            {
                j--;
                ans += "R";
            }
            else if (s[i - 1][j] != 0)
            {
                i--;
                ans += "D";
            }
        }
        if (s[i - 1][j] == 0 && s[i][j - 1] == 0)
            break;
        //走到第一行或第一列
        if (i == 1)
        {
            for (int x = 1; x < j; x++)
                ans += "R";
            break;
        }
        if (j == 1)
        {
            for (int x = 1; x < i; x++)
                ans += "D";
            break;
        }
    }
    reverse(ans.begin(), ans.end());
    // fi(i, 1, n) fi(j, 1, n)
    // {
    //     cout << dp[i][j][0] << " " << dp[i][j][1] << endl;
    // }
    if (ans.size() < 2 * n - 2)
    {
        cout << 1 << endl;
        string temp = "";
        fi(i, 1, fx - 1) temp += 'D';
        fi(i, 1, fy - 1) temp += 'R';
        fi(i, fx, n - 1)
        {
            temp += 'R';
        }
        fi(j, fy, n - 1)
        {
            temp += 'D';
        }
        cout << temp << endl;
        return 0;
    }
    if (flag)
    {
        if (1 <= min(dp[n][n][0], dp[n][n][1]))
        {
            cout << 1 << endl;
            string temp = "";
            fi(i, 1, fx - 1) temp += 'D';
            fi(i, 1, fy - 1) temp += 'R';
            fi(i, fx, n - 1)
            {
                temp += 'R';
            }
            fi(j, fy, n - 1)
            {
                temp += 'D';
            }
            cout << temp << endl;
            return 0;
        }
        else
        {
            cout << 0 << endl;
            cout << ans << endl;
            return 0;
        }
    }
    else
    {
        cout << min(dp[n][n][0], dp[n][n][1]) << endl;
        cout << ans << endl;
    }
#ifdef DEBUG
    //freopen(D:\in.txt,r,stdin);
#endif
    return 0;
}
posted @ 2022-03-02 20:07  Sun-Wind  阅读(58)  评论(0编辑  收藏  举报