90pts RE on #2, 玄关求条
查看原帖
90pts RE on #2, 玄关求条
980845
_HappyCoder_楼主2025/7/30 18:11
#include <iostream>
#include <cstring>

using namespace std;

using LL = long long;

const int MAXN = 40 + 5;
const int MAXM = 1e5 + 5;
const int INF = 0x3f3f3f3f;

LL dp[MAXN][MAXM]; // dp[i][j] 表示使用字符串前i位,数字之和恰好为j的最少加号数
LL num[MAXN][MAXN]; // num[i][j] 表示字符串第i位到第j为所形成的数字

string str;

int N;

signed main()
{

    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    cin >> str >> N;

    int len = str.length();

    for (int i = 1; i <= len; i++)
    {
        for (int j = 1; j <= i; j++)
        {
            num[j][i] = num[j][i - 1] * 10 + str[i - 1] - '0'; 
			// 预处理num数组,便于转移
        }
    }

    for (int i = 0; i <= len; i++)
    {
        for (int j = 0; j <= N; j++)
        {
            dp[i][j] = INF; // 初始化dp数组
        }
    }
    
    dp[0][0] = -1;

    for (int i = 1; i <= len; i++)
    {
        for (int j = 0; j <= N; j++)
        {
            for (int k = 0; k < i; k++)
            {
                if (j >= num[k + 1][i])
                    dp[i][j] = min(dp[i][j], dp[k][j - num[k + 1][i]] + 1);
            }
        }
    }

    int ans = dp[len][N];

    if (ans == INF)
        ans = -1; // 特判无解
    
    cout << ans << endl;

    return 0;
}
2025/7/30 18:11
加载中...