刷题刷出新高度,偷偷领先!偷偷领先!偷偷领先! 关注我们,悄悄成为最优秀的自己!

简答题

数字之和

题目描述

给定一个数字字符串 n,定义一次操作为:移除字符串中一个非空子串,并将剩余部分拼接形成新数字。

求所有可能操作方案生成的新数字之和,结果对 109+7取模。

输入格式

一行字符串 n

输出格式

一个整数,表示所有方案生成数字之和取模后的结果。


输入样例#1

1003

输出样例#1

339

输入样例#2

123

输出样例#2

52

说明提示

【数据范围】

1≤∣n∣≤105,| n |表示字符串长度。

限制

时间限制:1000ms

内存限制:256MiB

使用微信搜索喵呜刷题,轻松应对考试!

答案:

由于数据范围较大,需要利用动态规划的思想来解决这个问题。我们可以定义一个二维数组dp,其中dp[i][j]表示从字符串的第i个字符到第j个字符之间的子串操作生成的所有数字之和。初始时,我们可以设定dp[i][i]为字符串的第i个字符代表的数字。对于dp[i][j],我们可以根据操作分为两种情况:保留第i个字符和第j个字符之间的子串,或者不保留这个子串。如果保留这个子串,那么dp[i][j]就等于这个子串代表的数字加上dp[i+1][j-1];如果不保留这个子串,那么dp[i][j]就等于dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1](注意要减去重复计算的部分)。最终的结果就是dp[1][n],其中n为字符串的长度。为了避免计算过程中的溢出,需要对结果取模。

解析:

这个问题可以通过动态规划来解决。我们可以定义一个二维数组dp,其中dp[i][j]表示从字符串的第i个字符到第j个字符之间的子串操作生成的所有数字之和。我们可以根据操作分为两种情况来计算dp[i][j]。对于每一种情况,我们可以递归地计算子问题,直到子问题的规模缩小到只有一个字符。在计算过程中,需要注意避免重复计算,因此需要对结果取模以避免溢出。最终的结果就是dp[1][n],其中n为字符串的长度。在C语言中,可以利用递归和取模运算来实现这个算法。

以下是C语言的代码实现:

#include <stdio.h>
#include <string.h>
#define MOD 1000000007

long long dp(char *str, int l, int r) {
    if (l == r) {  // 子问题规模缩小到只有一个字符
        return str[l] - '0';  // 返回这个字符代表的数字
    }
    long long res = 0;  // 保存计算结果
    int len = r - l + 1;  // 子串长度
    int mul = pow_mod(10, len - 1);  // 计算乘积避免溢出
    for (int i = l; i <= r; i++) {  // 枚举分割点
        res = (res + dp(str, l, i - 1) * (str[i] - '0') % MOD + dp(str, i + 1, r)) % MOD;  // 计算两种情况的和并取模
    }
    return res * mul % MOD;  // 返回结果并取模
}

int main() {
    char str[100005];  // 存储输入的字符串
    scanf("%s", str);  // 读入字符串
    printf("%lld\n", dp(str, 0, strlen(str) - 1));  // 输出结果
    return 0;
}
创作类型:
原创

本文链接:数字之和 题目描述 给定一个数字字符串 n,定义一次操作为:移除字符串中一个非空子串,并将剩余部分拼

版权声明:本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处。

让学习像火箭一样快速,微信扫码,获取考试解析、体验刷题服务,开启你的学习加速器!

分享考题
share