[海豹海边爆]牛客21302

原题链接:登录—专业IT笔试面试备考平台_牛客网

解题思路:要说明的是,本题中子序列构造的数字,指的是子序列中值相加,而非直接组成一个多位数。

在明白这一点后,题目就变成了一个标准的动态规划。任何一个数被3余后都只会剩下三种结果——0,1,2。

首先,对于每一个数,不管前面的情况,其自身余3后的值所对应的情况必然会产生,因为存在前面都不选的情况。接下来是继承前面的情况,如果不选该数,那么这一层的0,1,2三种情况直接累加上上一层的结果就行。而如果选择,那么将该数加上上一层三种情况,再余3,就能找到在本层所对应的位置,加上位置上原有的数即可。

最后,输出最后一层的,余数为0的情况。

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007
string m;
long long dp[60][3],i;//i用以在循环中顺带记录字符串有多长
int main(){
    cin>>m;
    for(i=1;m[i-1];i++){
        int buffer;
        buffer=(m[i-1]-'0')%3;
        dp[i][buffer]=1;//直接获得该余数的情况,模拟了前面都不选
        for(int j=0;j<3;j++){
            dp[i][j]+=dp[i-1][j];//本数不选
            dp[i][(j+buffer)%3]+=dp[i-1][j];//本数选
        }
        for(int j=0;j<3;j++) dp[i][j]%=MOD;
    }
    cout<<dp[i-1][0];
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值