Loading [MathJax]/extensions/tex2jax.js

P1415:拆分数列题解

思路

这道题其实第一个方程非常的显然,即\(f[i] = max\{f[i], j\}, number(f[j-1], j-1)<number(j,i)\)。第二个方程其实就是重构了一下状态结构,跟原本的\(f[]\)差不多,转移式\(dp[i] = max\{dp[i], j\}, number(i,j)<number(j+1, dp[j+1)\)。注意这道题要写高精度比较,要不然会 gg (我调这玩意半个小时)。

代码

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// P1415.cpp
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX_N = 550;
int f[MAX_N], dp[MAX_N], numarr[MAX_N];
string str;
bool smaller(int i, int j, int a, int b)
{
int cur1 = i, cur2 = a;
for (; j - cur1 > b - cur2; cur1++)
if (numarr[cur1])
return false;
for (; j - cur1 < b - cur2; cur2++)
if (numarr[cur2])
return true;
while (cur1 <= j)
{
if (numarr[cur1] < numarr[cur2])
return true;
else if (numarr[cur1] > numarr[cur2])
return false;
cur1++, cur2++;
}
return false;
}
int main()
{
ios::sync_with_stdio(false);
cin >> str;
int siz = str.length();
str = " " + str;
for (int i = 1; i <= siz; i++)
numarr[i] = str[i] - '0';
for (int i = 1; i <= siz; i++)
{
f[i] = 1;
for (int j = i; j >= 1; j--)
if (smaller(f[j - 1], j - 1, j, i))
{
f[i] = max(f[i], j);
break;
}
}
dp[f[siz]] = siz;
int cnt = 0;
for (int i = f[siz] - 1; i >= 1 && !numarr[i]; i--)
cnt++, dp[i] = siz;
for (int i = f[siz] - cnt - 1; i >= 1; i--)
{
dp[i] = i;
for (int j = f[siz] - 1; j >= i; j--)
if (smaller(i, j, j + 1, dp[j + 1]))
{
dp[i] = max(dp[i], j);
break;
}
}
bool flag = true;
for (int pos = 1; pos <= siz;)
{
if (flag)
flag = false;
else
printf(",");
for (int i = pos; i <= dp[pos]; i++)
printf("%d", numarr[i]);
pos = dp[pos] + 1;
}
return 0;
}
// P1415.cpp #include <bits/stdc++.h> #define ll long long using namespace std; const int MAX_N = 550; int f[MAX_N], dp[MAX_N], numarr[MAX_N]; string str; bool smaller(int i, int j, int a, int b) { int cur1 = i, cur2 = a; for (; j - cur1 > b - cur2; cur1++) if (numarr[cur1]) return false; for (; j - cur1 < b - cur2; cur2++) if (numarr[cur2]) return true; while (cur1 <= j) { if (numarr[cur1] < numarr[cur2]) return true; else if (numarr[cur1] > numarr[cur2]) return false; cur1++, cur2++; } return false; } int main() { ios::sync_with_stdio(false); cin >> str; int siz = str.length(); str = " " + str; for (int i = 1; i <= siz; i++) numarr[i] = str[i] - '0'; for (int i = 1; i <= siz; i++) { f[i] = 1; for (int j = i; j >= 1; j--) if (smaller(f[j - 1], j - 1, j, i)) { f[i] = max(f[i], j); break; } } dp[f[siz]] = siz; int cnt = 0; for (int i = f[siz] - 1; i >= 1 && !numarr[i]; i--) cnt++, dp[i] = siz; for (int i = f[siz] - cnt - 1; i >= 1; i--) { dp[i] = i; for (int j = f[siz] - 1; j >= i; j--) if (smaller(i, j, j + 1, dp[j + 1])) { dp[i] = max(dp[i], j); break; } } bool flag = true; for (int pos = 1; pos <= siz;) { if (flag) flag = false; else printf(","); for (int i = pos; i <= dp[pos]; i++) printf("%d", numarr[i]); pos = dp[pos] + 1; } return 0; }
// P1415.cpp
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int MAX_N = 550;
int f[MAX_N], dp[MAX_N], numarr[MAX_N];
string str;
bool smaller(int i, int j, int a, int b)
{
    int cur1 = i, cur2 = a;
    for (; j - cur1 > b - cur2; cur1++)
        if (numarr[cur1])
            return false;
    for (; j - cur1 < b - cur2; cur2++)
        if (numarr[cur2])
            return true;
    while (cur1 <= j)
    {
        if (numarr[cur1] < numarr[cur2])
            return true;
        else if (numarr[cur1] > numarr[cur2])
            return false;
        cur1++, cur2++;
    }
    return false;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> str;
    int siz = str.length();
    str = " " + str;
    for (int i = 1; i <= siz; i++)
        numarr[i] = str[i] - '0';
    for (int i = 1; i <= siz; i++)
    {
        f[i] = 1;
        for (int j = i; j >= 1; j--)
            if (smaller(f[j - 1], j - 1, j, i))
            {
                f[i] = max(f[i], j);
                break;
            }
    }
    dp[f[siz]] = siz;
    int cnt = 0;
    for (int i = f[siz] - 1; i >= 1 && !numarr[i]; i--)
        cnt++, dp[i] = siz;
    for (int i = f[siz] - cnt - 1; i >= 1; i--)
    {
        dp[i] = i;
        for (int j = f[siz] - 1; j >= i; j--)
            if (smaller(i, j, j + 1, dp[j + 1]))
            {
                dp[i] = max(dp[i], j);
                break;
            }
    }
    bool flag = true;
    for (int pos = 1; pos <= siz;)
    {
        if (flag)
            flag = false;
        else
            printf(",");
        for (int i = pos; i <= dp[pos]; i++)
            printf("%d", numarr[i]);
        pos = dp[pos] + 1;
    }
    return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *