2019牛客暑期多校训练营(第四场)K.number

>传送门<

题意:给你一个字符串s,求出其中能整除300的子串个数(子串要求是连续的,允许前面有0)

思路:

》动态规划

f[i][j]为右端点满足mod 300 = j的子串个数,可以容易的转移

则状态转移方程为:f[i][(10*j+num[i]) %300] = f[i][(10*j+num[i]) %300] + f[i-1][j]

解释:假如给你个数3,很容易得出3mod300的值就是3,f[3] = 1,然后在3后面加一位1,变为31,则31mod300的值为31,f[31] = 1。我们令(10*j+num[i]) mod 300x,仔细想一想后你会发现当前f[x]的值可以由现在的f[x]加上之前f[j]的值更新得到,记得最后让f[num[i]]的值加1

题目求的是mod 300 = 0的字串个数,因此,每次让ans的值加上f[i][0]更新就好了

Code

#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5+200;
char s[maxn];
long long dp[maxn][300];

int main()
{
    cin >> s;
    int len = strlen(s);
    long long ans = 0;
    for(int i = 0 ;i < len; i++){
        dp[i][s[i]-'0']++;
        for(int j = 0; j < 300; j++){
            dp[i+1][(j*10+s[i+1]-'0')%300] += dp[i][j];
        }
        ans += dp[i][0];
    }
    cout << ans << endl;
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/wizarderror/p/11258992.html